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.

greg-449
  • 109,219
  • 232
  • 102
  • 145
WitVault
  • 23,445
  • 19
  • 103
  • 133

3 Answers3

46

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?

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.

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
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

marchat
  • 153
  • 1
  • 9
  • 1
    Yes definitely this is one of the way but is it possible to do using java apis instead of String manipulation. – WitVault Mar 03 '17 at 14:45
  • I may have misunderstood the question, can you explain it to me otherwise? – marchat Mar 03 '17 at 14:48
  • Like the ones which I had tried but did not worked in the question. e.g setting hours, minutes,seconds to 00 using java – WitVault Mar 03 '17 at 14:50
-3

You can simply do:

DateUtils.truncate(yourDate, Calendar.DAY_OF_MONTH);

Hope this will help you

Renats Stozkovs
  • 2,549
  • 10
  • 22
  • 26
Younes Ouchala
  • 300
  • 1
  • 4
  • 15
  • with org.apache.commons.lang3.time.DateUtils – Younes Ouchala Mar 03 '17 at 15:27
  • 4
    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. – Basil Bourque Mar 03 '17 at 16:33
  • can you send me the source of this? – Younes Ouchala Mar 05 '17 at 18:57
  • Do you mean about DateUtils for the troublesome legacy classes? The JavaDoc for the Apache Commons Lang project’s [`DateUtils`](https://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/time/DateUtils.html) class takes only `Date` & `Calendar` arguments, the legacy classes. If you meant info about the java.time classes, see the [JavaDoc in Java 8](http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html), the [Oracle Tutorial](https://docs.oracle.com/javase/tutorial/datetime/TOC.html), and [JSR 310](https://jcp.org/en/jsr/detail?id=310). – Basil Bourque Mar 06 '17 at 00:49
  • 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 reply – Younes Ouchala Mar 06 '17 at 10:27
  • As for Java 7, most of the *java.time* functionality has been back-ported to Java 6 and Java 7. See [my Answer](https://stackoverflow.com/a/42584295/642706) for links. No need to ever touch the wretched old classes `Date` & `Calendar` again. – Basil Bourque Jul 26 '18 at 20:04