Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set hours minutes and seconds to 00 in ZonedDateTime or Instant

I have a date string in Utc format -

    String dateStr = "2017-03-03T13:14:28.666Z";

And I want to convert it to below format in Java date representation in ZonedDateTime.

When ZonedDateTime is printed it should show

    String dateStr = "2017-03-03T00:00:00.000Z";

I have tried following code -

    String timeZone = "America/Los_Angeles";
    DateTimeFormatter dtf1 = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX");
    DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    ZoneId zoneId1 = ZoneId.of(timeZone);
    String dateStr = "2017-03-03T13:14:28.666Z";
    Instant inst = Instant.parse(dateStr, dtf2);


    ZonedDateTime dateTimeInTz = ZonedDateTime.ofInstant(inst, zoneId1);

    ZonedDateTime startTime = dateTimeInTz.with(LocalTime.of(0, 0, 0, 0));
    ZonedDateTime endTime = dateTimeInTz.with(LocalTime.MAX);

    System.out.println("Start:"+startTime+", End:"+endTime);
    System.out.println("Start:"+startTime.toString()+", End:"+endTime.toString());  

    ZonedDateTime nT = ZonedDateTime.of ( LocalDate.parse(dateStr, dtf1) , LocalTime.of (0,0,0,0) , ZoneId.of ( timeZone ) );

    System.out.println("Start:"+nT);

Output:

Start:2017-03-03T00:00-08:00[America/Los_Angeles], End:2017-03-03T23:59:59.999999999-08:00[America/Los_Angeles]
Start:2017-03-03T00:00-08:00[America/Los_Angeles], End:2017-03-03T23:59:59.999999999-08:00[America/Los_Angeles]
Start:2017-03-03T00:00-08:00[America/Los_Angeles]

I want the start time to be normalized in ZonedDateTime. I want to achieve it using java libraries only not any third party library.

like image 815
WitVault Avatar asked Mar 03 '17 14:03

WitVault


People also ask

Should I use OffsetDateTime or ZonedDateTime?

Use OffsetDateTime to store unique instants in the universal timelines irrespective of the timezones, such as keeping the timestamps in the database or transferring information to remote systems worldwide. Use ZonedDateTime for displaying timestamps to users according to their local timezone rules and offsets.

How do I set timezone in instant?

Setting the time Instants are immutable so you can only "set" the time by creating a copy of your instant with the given time change. instant = instant. atZone(ZoneOffset. UTC) .

What is the format of ZonedDateTime?

Class ZonedDateTime. A date-time with a time-zone in the ISO-8601 calendar system, such as 2007-12-03T10:15:30+01:00 Europe/Paris . ZonedDateTime is an immutable representation of a date-time with a time-zone.

How would you convert a ZonedDateTime to an instant?

In Java, to convert a ZonedDateTime object to Instant object we can use the ZonedDateTime. toInstant() method as the Java program below.


1 Answers

tl;dr

You are working too hard.

Instant.parse( "2017-03-03T13:14:28.666Z" )
       .truncatedTo( ChronoUnit.DAYS )
       .toString()

2017-03-03T00:00.00Z

Details

What does "normalized in ZonedDateTime" mean? Please edit your Question to clarify.

When ZonedDateTime is printed it should show … "2017-03-03T00:00:00.000Z"

What you are asking is a contradiction. A ZonedDateTime has an assigned time zone for when you want to view a moment though the wall-clock time of a particular region. So asking for a ZonedDateTime to generate a string in UTC such as "2017-03-03T00:00:00.000Z" makes no sense. The Z is short for Zulu and means UTC.

Your input string is in standard ISO 8601 format. The java.time classes use these standard formats by default. So no need to specify a formatting pattern, no need for the DateTimeFormatter class.

Parse as an Instant, a point on the timeline in UTC with a resolution of nanoseconds.

Instant instant = Instant.parse( "2017-03-03T13:14:28.666Z" );

If you want midnight in UTC, truncate.

Instant instantMidnightUtc = instant.truncatedTo( ChronoUnit.DAYS );

instantMidnightUtc.toString(): 2017-03-03T00:00.00Z

No need for the ZonedDateTime class.

If you want to work with a date-only without any time-of-day and without a time zone, use the LocalDate class.

By the way, do not assume the first moment of the day is always 00:00:00. That is true for UTC. But various time zones may have anomalies such as Daylight Saving Time (DST) where the day may start at another time-of-day such as 01:00:00.


About java.time

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.

Where to obtain the java.time classes?

  • Java SE 8 and SE 9 and later
    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android
    • The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
    • See How to use ThreeTenABP….

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.

like image 158
Basil Bourque Avatar answered Oct 02 '22 06:10

Basil Bourque