用 Java 命名文件以包含日期和时间戳
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32587062/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Name a file in Java to include date and time stamp
提问by Maruthi Srinivas
I am exporting data into a file in a Java application using NetBeans. The file will have a hard coded name given by me in the code. Please find below the code.
我正在使用 NetBeans 将数据导出到 Java 应用程序中的文件中。该文件将具有我在代码中指定的硬编码名称。请在代码下方找到。
private static String FILE = "D:\Report.pdf";
I want to append date and time stamp to the file name generated so that each file created is a unique file. How to achieve this?
我想将日期和时间戳附加到生成的文件名,以便创建的每个文件都是唯一的文件。如何实现这一目标?
回答by Basil Bourque
tl;dr
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
报告_20161002T190416Z.pdf
Or define a formatter for this purpose. The single-quote marks '
mean “ignore this chunk of text; expect the text, but do not interpret”.
或者为此目的定义一个格式化程序。单引号的'
意思是“忽略这段文字;期待文本,但不要解释”。
DateTimeFormatter f = DateTimeFormatter.ofPattern( "'Report_'uuuuMMdd'T'HHmmss'.pdf'" ) ;
String fileName = OffsetDateTime.now( ZoneOffset.UTC ).truncatedTo( ChronoUnit.SECONDS ).format( f ) ;
Use same formatter to parse back to a date-time value.
使用相同的格式化程序解析回日期时间值。
OffsetDateTime odt = OffsetDateTime.parse( "Report_20161002T190416Z.pdf" , f ) ;
java.time
时间
The other Answers are correct but outdated. The troublesome old legacy date-time classes are now supplanted by the java.time classes.
其他答案是正确的,但已过时。麻烦的旧日期时间类现在被 java.time 类取代。
Get the current moment as an Instant
. The Instant
class represents a moment on the timeline in UTCwith a resolution of nanoseconds(up to nine (9) digits of a decimal fraction).
获取当前时刻作为Instant
. 该Instant
级表示时间轴上的时刻UTC,分辨率为纳秒(最多小数的9个位数)。
Instant instant = Instant.now(); // 2016-10-02T19:04:16.123456789Z
Truncate fractional second
截断小数秒
You probably want to remove the fractional second.
您可能想要删除小数秒。
Instant instant = Instant.now().truncatedTo( ChronoUnit.SECONDS );
Or if you for simplicity you may want to truncate to whole minutes if not rapidly creating such files.
或者,如果您为了简单起见,如果不快速创建此类文件,您可能希望将其截断为整分钟。
Instant instant = Instant.now().truncatedTo( ChronoUnit.MINUTES );
You can generate a string in standard ISO 8601format by calling toString
.
您可以通过调用生成标准ISO 8601格式的字符串toString
。
String output = instant.toString();
2016-10-02T19:04:16Z
2016-10-02T19:04:16Z
Stick with UTC
坚持使用UTC
The Z
on the end is short for Zulu
and means UTC. As a programmer always, and as a user sometimes, you should think of UTC as the “One True Time” rather than “just another time zone”. You can prevent many problems and errors by sticking with UTC rather than any particular time zone.
在Z
上月底是短期的Zulu
,并指UTC。作为一名程序员,有时作为一名用户,您应该将 UTC 视为“一个真实的时间”,而不仅仅是“另一个时区”。您可以通过坚持使用 UTC 而不是任何特定时区来防止许多问题和错误。
Colons
冒号
Those colons are not allowed in the HFS Plusfile system used by Mac OS X (macOS), iOS, watchOS, tvOS, and others including support in Darwin, Linux, Microsoft Windows.
这些冒号在Mac OS X (macOS)、iOS、watchOS、tvOS和其他包括 Darwin、Linux、Microsoft Windows 支持的HFS Plus文件系统中是不允许的。
Use ISO 8601 standard formats
使用 ISO 8601 标准格式
The ISO 8601standard provides for “basic” versions with a minimal number of separators along with the more commonly used “extended” format seen above. You can morph that string above to the “basic” version by simply deleting the hyphens and the colons.
在ISO 8601标准提供的“基本”的版本与上方看到的更常用的“扩展”格式沿着隔板的最小数量。您可以通过简单地删除连字符和冒号来将该字符串变形为“基本”版本。
String basic = instant.toString().replace( "-" , "" ).replace( ":" , "" );
20161002T190416Z
20161002T190416Z
Insert that string into your file name as directed in the other Answers.
按照其他答案中的指示将该字符串插入到您的文件名中。
More elegant
更优雅
If you find the calls to String::replace
clunky, you can use a more elegant approach with more java.time classes.
如果您发现对String::replace
笨拙的调用,您可以使用更多 java.time 类的更优雅的方法。
The Instant
class is a basic building-block class, not meant for fancy formatting. For that, we need the OffsetDateTime
class.
这个Instant
类是一个基本的构建块类,不适合花哨的格式。为此,我们需要这个OffsetDateTime
类。
Instant instant = Instant.now().truncatedTo( ChronoUnit.SECONDS );
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC );
Now define and cache a DateTimeFormatter
for the “basic” ISO 8601 format.
现在DateTimeFormatter
为“基本”ISO 8601 格式定义和缓存 a 。
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "uuuuMMdd'T'HHmmss" );
Use that formatter instance to generate a String. No more needing to replace characters in the String.
使用该格式化程序实例生成一个字符串。不再需要替换字符串中的字符。
String output = odt.format( formatter );
You can also use this formatter to parse such strings.
您还可以使用此格式化程序来解析此类字符串。
OffsetDateTime odt = OffsetDateTime.parse( "20161002T190416Z" , formatter );
Zoned
分区
If you decide to use a particular region's wall-clock time rather than UTC, apply a time zone in a ZoneId
to get a ZonedDateTime
object. Similar to an OffsetDateTime
but a time zone is an offset-from-UTC plusa set of rules for handling anomalies such as Daylight Saving Time (DST).
如果您决定使用特定区域的挂钟时间而不是 UTC,请在 a 中应用时区ZoneId
以获取ZonedDateTime
对象。与OffsetDateTime
时区类似,但时区是与 UTC 的偏移量加上一组用于处理夏令时 (DST) 等异常的规则。
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
Use the same formatter as above, or customize to your liking.
使用与上述相同的格式化程序,或根据您的喜好进行自定义。
About java.time
关于java.time
The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
该java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date
, Calendar
, & SimpleDateFormat
。
The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310。
You may exchange java.timeobjects directly with your database. Use a JDBC drivercompliant with JDBC 4.2or later. No need for strings, no need for java.sql.*
classes.
您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*
Where to obtain the java.time classes?
从哪里获得 java.time 类?
- Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6and Java SE 7
- Most of the java.timefunctionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- Later versions of Android bundle implementations of the java.timeclasses.
- For earlier Android (<26), the ThreeTenABPproject adapts ThreeTen-Backport(mentioned above). See How to use ThreeTenABP….
- Java SE 8、Java SE 9、Java SE 10、Java SE 11及更高版本 - 标准 Java API 的一部分,具有捆绑实现。
- Java 9 添加了一些小功能和修复。
- Java SE 6和Java SE 7
- 大多数java.time功能在ThreeTen-Backport 中被反向移植到 Java 6 & 7 。
- 安卓
- 更高版本的 Android 捆绑实现java.time类。
- 对于早期的 Android(<26),ThreeTenABP项目采用了ThreeTen-Backport(上面提到过)。请参阅如何使用ThreeTenABP ...。
The ThreeTen-Extraproject 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.
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如Interval
,YearWeek
,YearQuarter
,和更多。
回答by Jordi Castilla
Use SimpleDateFormat
and split to keep file extension:
使用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"
UPDATE:
if you are able to modify FILE
variable, my suggestion will be:
更新:
如果您能够修改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"
回答by Jib'z
You can do something like that
你可以做这样的事情
Define your file name pattern as below :
定义您的文件名模式如下:
private static final String FILE = "D:\Report_{0}.pdf";
private static final String DATE_PATTERN = "yyyy-MM-dd:HH:mm:ss";
The {0}
is a marker to be replaced by the following code
的{0}
是由下面的代码来替换的标记
private String formatFileName(Date timeStamp) {
DateFormat dateFormatter = new SimpleDateFormat(DATE_PATTERN);
String dateStr = dateFormatter.format(timeStamp);
return MessageFormat.format(FILE, dateStr);
}
For further information over date format you can see thereand MessageFormat there