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

Name a file in Java to include date and time stamp

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

private static String FILE = "D:\Report.pdf";

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

使用SimpleDateFormat并拆分以保留文件扩展名:

private static String FILE = "D:\Report.pdf";
DateFormat df = new SimpleDateFormat("yyyyMMddhhmmss"); // add S if you need milliseconds
String filename = FILE.split(".")[0] + df.format(new Date()) + FILE.split(".")[1];
// filename = "D:\Report20150915152301.pdf"

更新:
如果您能够修改 FILE 变量,我的建议是:

private static String FILE_PATH = "D:\Report";
private static String FILE_EXTENSION = ".pdf";
DateFormat df = new SimpleDateFormat("yyyyMMddhhmmss"); // add S if you need milliseconds
String filename = FILE_PATH + df.format(new Date()) + "." + FILE_EXTENSION;
// filename = "D:\Report20150915152301.pdf"

你可以这样做

定义文件名模式如下:

private static final String FILE = "D:\Report_{0}.pdf";
private static final String DATE_PATTERN = "yyyy-MM-dd:HH:mm:ss";

{0}是一个标记,要用下面的代码替换

private String formatFileName(Date timeStamp) {
        DateFormat dateFormatter = new SimpleDateFormat(DATE_PATTERN);
        String dateStr = dateFormatter.format(timeStamp);
        return MessageFormat.format(FILE, dateStr); 
}

有关日期格式的更多信息,请参阅 there and MessageFormat there

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"

Report_20161002T190416Z.pdf

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

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

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

OffsetDateTime odt = OffsetDateTime.parse( "Report_20161002T190416Z.pdf" , f ) ;

java.time

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

获取当前时刻 InstantInstant class represents a moment on the timeline in UTC with a resolution of nanoseconds(最多九 (9) 位小数)。

Instant instant = Instant.now();  // 2016-10-02T19:04:16.123456789Z

截断小数秒

您可能想要删除小数秒。

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

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

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

您可以通过调用 toString.

生成标准 ISO 8601 格式的字符串
String output = instant.toString();

2016-10-02T19:04:16Z

坚持使用 UTC

最后的ZZulu的简写,意思是UTC。作为一名程序员,有时作为一名用户,您应该将 UTC 视为“一个真实时间”,而不是“只是另一个时区”。坚持使用 UTC 而不是任何特定时区可以防止许多问题和错误。

冒号

这些冒号在 HFS Plus file system used by Mac OS X (macOS), iOS, watchOS, tvOS 中是不允许的,其他的包括在 Darwin、Linux、Microsoft Windows.

中的支持

使用 ISO 8601 标准格式

ISO 8601 标准提供了带有最少数量分隔符的“基本”版本以及上面看到的更常用的“扩展”格式。您可以通过简单地删除连字符和冒号将上面的字符串变形为“基本”版本。

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

20161002T190416Z

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

更优雅

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

Instant class 是一个基本的构建块 class,并不意味着花哨的格式。为此,我们需要 OffsetDateTime class.

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

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

DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "uuuuMMdd'T'HHmmss" );

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

String output = odt.format( formatter );

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

OffsetDateTime odt = OffsetDateTime.parse( "20161002T190416Z" , formatter );

分区

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

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );

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


关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

您可以直接与数据库交换 java.time 对象。使用 JDBC driver compliant with JDBC 4.2 或更高版本。不需要字符串,不需要 java.sql.* classes.

从哪里获得java.time classes?

ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.