Set hours minutes and seconds to 00 in ZonedDateTime or Instant
Asked Answered
R

3

19

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.

Relator answered 3/3, 2017 at 14:36 Comment(0)
R
50

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 an offset from UTC of zero hours-minutes-seconds.

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?

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.

Runaway answered 3/3, 2017 at 16:45 Comment(0)
F
0
   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);

    String strStart = (startTime.toString().split("T"))[0] + "T00:00:00.000Z";
    String strEnd  =  (endTime.toString().split("T"))[0] + "T00:00:00.000Z";

    System.out.println("Start:"+strStart +", End:"+strEnd  );

EDIT new method :

TimeZone timeZone = TimeZone.getTimeZone("Europe/Copenhagen");
Calendar cal = Calendar.getInstance(timeZone);
Calendar defaut = new GregorianCalendar( cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH),0,0,0);

You juste need to get all your necessary fields. With, for example, a dateFormat.

Hope it will help you

Flatter answered 3/3, 2017 at 14:44 Comment(3)
Yes definitely this is one of the way but is it possible to do using java apis instead of String manipulation.Relator
I may have misunderstood the question, can you explain it to me otherwise?Flatter
Like the ones which I had tried but did not worked in the question. e.g setting hours, minutes,seconds to 00 using javaRelator
D
-3

You can simply do:

DateUtils.truncate(yourDate, Calendar.DAY_OF_MONTH);

Hope this will help you

Deanndeanna answered 3/3, 2017 at 15:6 Comment(6)
with org.apache.commons.lang3.time.DateUtilsDeanndeanna
Incorrect. Apache DateUtils is for the troublesome old legacy date-time classes bundled with the earliest versions of Java. This Question is about their replacement, the java.time classes.Runaway
can you send me the source of this?Deanndeanna
Do you mean about DateUtils for the troublesome legacy classes? The JavaDoc for the Apache Commons Lang project’s DateUtils class takes only Date & Calendar arguments, the legacy classes. If you meant info about the java.time classes, see the JavaDoc in Java 8, the Oracle Tutorial, and JSR 310.Runaway
Im talking about java 7 ; yes the DateUtils class takes only Date & calender arguments but he can parse the String to get Date and use truncate to truncate a date . Thanks a lot for your replyDeanndeanna
As for Java 7, most of the java.time functionality has been back-ported to Java 6 and Java 7. See my Answer for links. No need to ever touch the wretched old classes Date & Calendar again.Runaway

© 2022 - 2024 — McMap. All rights reserved.