如何使用当前日期的名称创建新文件

时间:2016-06-08 16:18:27

标签: java file date

所以我正在开发一个工作项目,我分配的任务之一是创建一个按钮,当按下该按钮时,会创建一个带有当前日期和时间名称的.txt文件。我知道如何创建.txt文件,我知道如何获取当前日期。但是,当我尝试使用日期名称创建一个新文件时,它会创建一个IOException。这是我的代码:

DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
String dateTxt = dateFormat.format(date) + ".txt";
PrintWriter writer = new PrintWriter(dateTxt, "UTF-8");

抛出IOException。但是,如果我用“placeHolder.txt”之类的东西替换dateTxt,它可以正常工作并创建一个新文件。所以我不明白为什么它不能与String dateTxt一起使用。请帮忙。

3 个答案:

答案 0 :(得分:3)

:/是您在创建文件时可能想要转义的特殊字符。转义这些应该允许您创建文件。

答案 1 :(得分:1)

您可能希望将SimpleDateFormat更改为输出有效文件名的内容:

throws Exception

答案 2 :(得分:1)

Answer by Venkat是正确的,Answer by nvuono也是如此。但让我们看看两个问题:现代日期时间类和时区处理。

TL;博士

对于UTC ...

String now = Instant.now().truncatedTo( ChronoUnit.SECONDS ).toString().replace( "-" , "" ).replace( ":" , "" );
  

20160608T234748Z

对于本地时区(但通过省略偏移或时区而不明确)...

String now = LocalDateTime.now( ZoneId.of( "America/Montreal" ) ).truncatedTo( ChronoUnit.SECONDS ).toString().replace( "-" , "" ).replace( ":" , "" );
  

20160608T194748

对于本地时区,包括从UTC的偏移量...

String now = OffsetDateTime.now( ZoneId.of( "America/Montreal" ) ).truncatedTo( ChronoUnit.SECONDS ).toString().replace( "-" , "" ).replace( ":" , "" );
  

20160608T194748-0700

详细

问题和其他答案中显示的类已经过时了。与最早版本的Java捆绑在一起的麻烦的旧日期时间类在Java 8及更高版本的java.time框架中被取代。大部分功能都被后端移植到Java 6& 7在ThreeTen-Backport中,并在ThreeTenABP中进一步适应Android。

此外,时区未得到解决。

如果您想以UTC格式显示当前时间,请使用Instant

Instant instant = Instant.now();

你需要整秒,所以让我们通过截断到整秒来将小数秒设置为零..

Instant instant = Instant.now().truncatedTo( ChronoUnit.SECONDS );

在解析/生成表示日期时间值的字符串时,java.time类默认使用标准ISO 8601格式。该标准采用年 - 月 - 日 - 小时 - 分 - 秒排序,按字母顺序排序时按时间顺序排序。

String output = instant.toString(); // 2016-06-08T23:47:48Z

示例输出:2016-06-08T23:47:48Z。因此需要替换各种操作系统上各种文件系统不允许的字符。 JonK的评论列出了其中的一些。正如nvuono所建议的,一种方法是消除所有标点符号。这种分隔符的最小化被称为ISO 8601中的基本版本,标准使用T将年 - 月 - 日与小时 - 分 - 秒分开。

获得该基本格式的一种方法是删除完整版中插入的标点符号。

String output = instant.toString().replace( "-" , "" ).replace( ":" , "" );

如果您愿意,可以添加.replace( "T" , "_" )T可以在不使用复杂字体时使值更难读取。有些人根本不使用分隔符,但这使得我很难辨别出这个值。

我建议您保留ZZulu的缩写,即UTC。日期时间的含义是模糊的,没有时区的指示。

或者定义自己的格式模式。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyyMMddTHHmmssX" ); // Or "yyyyMMdd_HHmmssX".

如果使用UTC,请使用X代码在末尾附加Z

Instant类是java.time中的基本构建块,不用于格式化。转换为OffsetDateTime以使用格式化程序。指定您想要的offset-from-UTC;这里我通过常量ZoneOffset.UTC使用UTC本身。

OffsetDateTime odt = OffsetDateTime.ofInstant( instant , ZoneOffset.UTC );

或者,使用便捷方法now捕捉当前时刻,而不通过Instant。记得放弃小数秒。

OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ).truncatedTo( ChronoUnit.SECONDS );

OffsetDateTime适用于只有offset但不是完整time zone的情况。时区是偏移量加上用于处理Daylight Saving Time (DST)等异常的一组规则。如果您希望在某个地区使用wall-clock time,请使用ZoneId调整时区以获得ZonedDateTime

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.now( zoneId ).truncatedTo( ChronoUnit.SECONDS );

toString上的ZonedDateTime方法既包括UTC的偏移量(ISO 8601标准的一部分),也包含方括号中的时区名称(一个很好的主意,但不是标准)。如果您确实不想包含时区信息,请使用上面显示的DateTimeFormatter。或使用有意丢失所有时区信息的LocalDateTime

ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDateTime ldt = LocalDateTime.now( zoneId ).truncatedTo( ChronoUnit.SECONDS );

删除有问题的字符:

String output = ldt.toString().replace( "-" , "" ).replace( ":" , "" );