【问题标题】:How to create a new File with the name of the current date如何使用当前日期的名称创建一个新文件
【发布时间】:2016-06-08 16:18:27
【问题描述】:

所以我正在处理一个工作项目,我被分配的任务之一是创建一个按钮,当按下该按钮时,会创建一个带有当前日期和时间名称的 .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 在那里被抛出。但是,如果我将 dateTxt 替换为“placeHolder.txt”之类的东西,它可以正常工作并创建一个新文件。所以我不明白为什么它不适用于String dateTxt。请帮忙。

【问题讨论】:

  • 请发布例外情况。
  • java.io.IOException: 没有这样的文件或目录
  • @DannySeaton 最好将附加信息作为对问题的编辑而不是作为评论发布。

标签: java file date


【解决方案1】:

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

【讨论】:

  • Windows 不允许文件名包含任何\ / : * ? " < > |,因此转义这些字符是不够的,您必须将它们替换为其他内容。
【解决方案2】:

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

DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss");

【讨论】:

    【解决方案3】:

    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 框架所取代。大部分功能在 ThreeTen-Backport 中向后移植到 Java 6 和 7,并在 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 中的 basic 版本,该标准使用 T 将年-月-日与小时-分钟-秒分开。

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

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

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

    我建议你保留Z,是Zulu 的缩写,意思是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)。如果您更喜欢在某个地区使用 get a wall-clock time,请通过应用 ZoneId 来调整时区以获得 ZonedDateTime

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

    ZonedDateTime 上的 toString 方法既包括从 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( ":" , "" );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-13
      • 1970-01-01
      相关资源
      最近更新 更多