用 Java 命名文件以包含日期和时间戳

Mar*_*vas 2 java filenames netbeans timestamp file

我正在使用 NetBeans 将数据导出到 Java 应用程序中的文件中。该文件将具有我在代码中给出的硬编码名称。请在代码下方找到。

private static String FILE = "D:\\Report.pdf";
Run Code Online (Sandbox Code Playgroud)

我想将日期和时间戳附加到生成的文件名,以便创建的每个文件都是唯一的文件。如何实现这一目标?

Bas*_*que 5

tl;博士

"Report" + "_" 
         + Instant.now()                               // Capture the current moment in UTC.
                  .truncatedTo( ChronoUnit.SECONDS )   // Lop off the fractional second, as superfluous to our purpose.
                  .toString()                          // Generate a `String` with text representing the value of the moment in our `Instant` using standard ISO 8601 format: 2016-10-02T19:04:16Z
                  .replace( "-" , "" )                 // Shorten the text to the “Basic” version of the ISO 8601 standard format that minimizes the use of delimiters. First we drop the hyphens from the date portion
                  .replace( ":" , "" )                 // Returns 20161002T190416Z afte we drop the colons from the time portion. 
         + ".pdf"
Run Code Online (Sandbox Code Playgroud)

报告_20161002T190416Z.pdf

或者为此目的定义一个格式化程序。单引号的'意思是“忽略这段文字;期待文本,但不要解释”。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "'Report_'uuuuMMdd'T'HHmmss'.pdf'" ) ;
String fileName = OffsetDateTime.now( ZoneOffset.UTC ).truncatedTo( ChronoUnit.SECONDS ).format( f )  ;
Run Code Online (Sandbox Code Playgroud)

使用相同的格式化程序解析回日期时间值。

OffsetDateTime odt = OffsetDateTime.parse( "Report_20161002T190416Z.pdf" , f ) ;
Run Code Online (Sandbox Code Playgroud)

时间

其他答案是正确的,但已过时。麻烦的旧日期时间类现在被 java.time 类取代。

获取当前时刻作为Instant. 该Instant级表示时间轴上的时刻UTC,分辨率为纳秒(最多小数的9个位数)。

Instant instant = Instant.now();  // 2016-10-02T19:04:16.123456789Z
Run Code Online (Sandbox Code Playgroud)

截断小数秒

您可能想要删除小数秒。

Instant instant = Instant.now().truncatedTo( ChronoUnit.SECONDS );
Run Code Online (Sandbox Code Playgroud)

或者,如果您为了简单起见,如果不快速创建此类文件,您可能希望将其截断为整分钟。

Instant instant = Instant.now().truncatedTo( ChronoUnit.MINUTES );
Run Code Online (Sandbox Code Playgroud)

您可以通过调用生成标准ISO 8601格式的字符串toString

String output = instant.toString();
Run Code Online (Sandbox Code Playgroud)

2016-10-02T19:04:16Z

坚持使用UTC

Z上月底是短期的Zulu,并指UTC。作为一名程序员,有时作为一名用户,您应该将 UTC 视为“一个真实的时间”而不是“只是另一个时区”。您可以通过坚持使用 UTC 而不是任何特定时区来防止许多问题和错误。

冒号

这些冒号在Mac OS X (macOS)iOSwatchOStvOS和其他包括 Darwin、Linux、Microsoft Windows 支持的HFS Plus文件系统中是不允许的。

使用 ISO 8601 标准格式

ISO 8601标准提供的“基本”的版本与上方看到的更常用的“扩展”格式沿着隔板的最小数量。您可以通过简单地删除连字符和冒号来将该字符串变形为“基本”版本。

String basic = instant.toString().replace( "-" , "" ).replace( ":" , "" );
Run Code Online (Sandbox Code Playgroud)

20161002T190416Z

按照其他答案中的指示将该字符串插入到您的文件名中。

更优雅

如果您发现对String::replace笨拙的调用,您可以使用更多 java.time 类的更优雅的方法。

这个Instant类是一个基本的构建块类,不适合花哨的格式。为此,我们需要这个OffsetDateTime类。

Instant instant = Instant.now().truncatedTo( ChronoUnit.SECONDS );
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC );
Run Code Online (Sandbox Code Playgroud)

现在DateTimeFormatter为“基本”ISO 8601 格式定义和缓存 a 。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "uuuuMMdd'T'HHmmss" );
Run Code Online (Sandbox Code Playgroud)

使用该格式化程序实例生成一个字符串。不再需要替换字符串中的字符。

String output = odt.format( formatter );
Run Code Online (Sandbox Code Playgroud)

您还可以使用此格式化程序来解析此类字符串。

OffsetDateTime odt = OffsetDateTime.parse( "20161002T190416Z" , formatter );
Run Code Online (Sandbox Code Playgroud)

分区

如果您决定使用特定区域的挂钟时间而不是 UTC,请在 a 中应用时区ZoneId以获取ZonedDateTime对象。与OffsetDateTime时区类似,但时区是与 UTC 的偏移量加上一组用于处理夏令时 (DST) 等异常的规则。

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
Run Code Online (Sandbox Code Playgroud)

使用与上述相同的格式化程序,或根据您的喜好进行自定义。


关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

现在处于维护模式Joda-Time项目建议迁移到java.time类。

要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310

您可以直接与您的数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*

从哪里获得 java.time 类?

ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多