Steerpike
Steerpike

Reputation: 1843

Parsing LocalDate to ZonedDateTime in correct format

Given:

public static void main(String[] args) {

   String dateString = "2018-07-30T13:36:17.820";

    DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter
            .ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");

    LocalDate date = LocalDate.parse(dateString, DATE_TIME_FORMATTER);

    ZonedDateTime zonedDateTime = date.atStartOfDay((ZoneOffset.UTC));

    System.out.println(zonedDateTime);
}

And output:

2018-07-30T00:00Z

...what is the pattern to print seconds? Stupid question no doubt but driving me a little nuts

I need:

2018-07-30T00:00:00Z

Upvotes: 0

Views: 1701

Answers (4)

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79075

tl;dr

You have used the wrong things in the wrong places.

  1. You do not need a DateTimeFormatter explicitly in order to parse 2018-07-30T13:36:17.820 because it's already in ISO 8601 format which is also the default format used by LocalDateTime#parse. Moreover, this string has date and time instead of just date; therefore, it makes more sense to parse it into LocalDateTime instead of LocalDate. You can always get LocalDate from LocalDateTime using LocalDateTime#toLocalDate.
  2. The ZonedDateTime#toString uses the LocalDateTime#toString which in turn uses LocalTime#toString for the time part which omits second and fraction-of-second if they are zero. If you need a string with zero second and fraction-of-second, you will need to use a DateTimeFormatter.

Demo:

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String args[]) {
        String dateString = "2018-07-30T13:36:17.820";

        LocalDateTime localDateTime = LocalDateTime.parse(dateString);// You do not need a DateTimeFormatter here

        ZonedDateTime zonedDateTime = localDateTime.toLocalDate().atStartOfDay(ZoneOffset.UTC);

        // Print zonedDateTime.toString()
        System.out.println(zonedDateTime);

        // Custom format
        final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
        System.out.println(DATE_TIME_FORMATTER.format(zonedDateTime));
    }
}

Output:

2018-07-30T00:00Z
2018-07-30T00:00:00.000

Learn more about the modern date-time API from Trail: Date Time.

Upvotes: 1

Opri
Opri

Reputation: 651

I changed java.time.LocalDate to java.time.LocalDateTime, you need it if you want to show also the seconds.

package com.test;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class DateFormatter {

    public static void main(String[] args) {

        String dateString = "2018-07-30T13:36:17.820";

        DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter
                .ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");

        LocalDateTime date = LocalDateTime.parse(dateString, DATE_TIME_FORMATTER);

        ZonedDateTime zonedDateTime = date.atZone(ZoneOffset.UTC);


        System.out.println(zonedDateTime);
    }
}

Output is:

2018-07-30T13:36:17.820Z

Upvotes: 3

deHaar
deHaar

Reputation: 18568

You will have to go a few steps:

  • parse the String to a LocalDateTime because it contains date and time of day
  • extract the date only
  • create a ZonedDateTime out of that by adding the start of day (LocalTime.MIN = 00:00:00) and a ZoneOffset.UTC

This code may do:

public static void main(String[] args) {
    String dateString = "2018-07-30T13:36:17.820";
    // parse a LocalDateTime
    LocalDateTime localDateTime = LocalDateTime.parse(dateString);
    // extract the date part
    LocalDate localDate = localDateTime.toLocalDate();
    // make it a ZonedDateTime by applying a ZoneId
    ZonedDateTime zonedDateTime = ZonedDateTime.of(localDate, LocalTime.MIN, ZoneOffset.UTC);
    // print the result
    System.out.println(zonedDateTime.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
}

Output is

2018-07-30T00:00:00Z

There are several ways to do it, this is just one of them and it just slightly differs from most of the other answers (and comments :-) ).

Upvotes: 1

Akif Hadziabdic
Akif Hadziabdic

Reputation: 2890

LocalDate will keep just date. You need to parse LocalDateTime and convert to ZonedDateTime and you will have seconds as you expect.

    var dateString = "2018-07-30T13:36:17.820";
    var format = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
    var localDate = LocalDateTime.parse(dateString, format);
    var zone = ZoneId.of( "America/Montreal" );
    var zonedDateTime = localDate.atZone(zone);
    System.out.println(zonedDateTime);

Upvotes: 1

Related Questions