Quantcast
Channel: Scratch Where It's Itching
Viewing all articles
Browse latest Browse all 73

Format Date with java time

$
0
0
An advantage of the DateTimeFormatter class from the java time package over the old DateFormat is that it is thread-safe. But if the only thing I have is a Date, how can I proceed?

The DateTimeFormatter's format method takes a TemporalAccessor as a parameter. Date has a toInstant() method that converts the Date to an Instant object that implements the TemporalAccessor interface. All that sounds pretty easy:

  Date date = new Date();
  DateTimeFormatter df = DateTimeFormatter.ISO_DATE_TIME;
  System.out.println(df.format(date.toInstant()));

Unfortunately, that does not work. You en up with the following error:

Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: Year
	at java.time.Instant.getLong(Unknown Source)
	at java.time.format.DateTimePrintContext$1.getLong(Unknown Source)
	at java.time.format.DateTimePrintContext.getValue(Unknown Source)
	at java.time.format.DateTimeFormatterBuilder$NumberPrinterParser.format(Unknown Source)

As it turns out, the only formatter that can be used with an Instant is DateTimeFormatter.ISO_INSTANT. And the output would be in UTC time zone and look like this: '2011-12-03T10:15:30Z'.

In fact, this is all very logical. The only information missing from a Date to know the correct time and date to print is the time zone. The old DateFormat class assumed you would want to use the current time zone. For java time, you have to explicitly sate it:

  Date date = new Date();
  DateTimeFormatter df = DateTimeFormatter.ISO_DATE_TIME;
  System.out.println(df.format(date.toInstant().atZone(ZoneId.systemDefault())));

Or you can also provide the time zone to the formatter:

  Date date = new Date();
  DateTimeFormatter df = DateTimeFormatter.ISO_DATE_TIME
    .withZone(ZoneId.systemDefault());
  System.out.println(df.format(date.toInstant()));

The toZone() method of Instant creates a ZonedDateTime object, from which you can easily convert to LocalDate, LocalTime or LocalDateTime. To convert back to a Date is always a matter of providing the missing information.

For instance, from a Localtime, you provide a date and a time zone:

  LocalTime now = LocalTime.now();
  Date date = Date.from(now.atDate(LocalDate.now()).atZone(ZoneId.systemDefault()).toInstant());

From a LocalDate, you need a time and a time zone:

  LocalDate now = LocalDate.now();
  Date date = Date.from(now.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());


Viewing all articles
Browse latest Browse all 73

Trending Articles