Reputation: 590
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.
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?
Upvotes: 2
Views: 19659
Reputation: 340350
"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
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 ) ;
The other Answers are correct but outdated. The troublesome old legacy date-time classes are now supplanted by the java.time classes.
Get the current moment as an Instant
. The Instant
class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = Instant.now(); // 2016-10-02T19:04:16.123456789Z
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 8601 format by calling toString
.
String output = instant.toString();
2016-10-02T19:04:16Z
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.
Those colons are not allowed in the HFS Plus file system used by Mac OS X (macOS), iOS, watchOS, tvOS, and others including support in Darwin, Linux, Microsoft Windows.
The ISO 8601 standard 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.
String basic = instant.toString().replace( "-" , "" ).replace( ":" , "" );
20161002T190416Z
Insert that string into your file name as directed in the other Answers.
If you find the calls to String::replace
clunky, you can use a more elegant approach with more java.time classes.
The Instant
class is a basic building-block class, not meant for fancy formatting. For that, we need the OffsetDateTime
class.
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 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 );
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 plus a set of rules for handling anomalies such as Daylight Saving Time (DST).
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
Use the same formatter as above, or customize to your liking.
The 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
.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.*
classes.
Where to obtain the java.time classes?
The 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.
Upvotes: 6
Reputation: 27003
Use SimpleDateFormat
and split to keep file extension:
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:
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"
Upvotes: 3
Reputation: 1003
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
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 there and MessageFormat there
Upvotes: 1