String ip="2011-05-01T06:47:35.422-05:00";
ZonedDateTime mzt = ZonedDateTime.parse(ip).toInstant().atZone(ZoneOffset.UTC);
System.out.println(mzt);
System.out.println("-----");
String ip2="2011-05-01T00:00:00.000-05:00";
ZonedDateTime mzt2 = ZonedDateTime.parse(ip2).toInstant().atZone(ZoneOffset.UTC);
System.out.println(mzt2);
Output:
2011-05-01T11:47:35.422Z
-----
2011-05-01T05:00Z
Why is the date format getting changed in case 2? I am getting SQLServer Database error due to this.
This is what toString from documentation said
The format used will be the shortest that outputs the full value of
the time where the omitted parts are implied to be zero.
To solve this problem, you need another formatter :
String result = mzt2.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss:SSS'Z'"));
Output
2011-05-01T11:47:35.422Z
2011-05-01T05:00:00:000Z
Just to complement YCF_L's answer:
Using a quoted letter in the pattern, like it was done with the Z (it's inside quotes: 'Z'
) is wrong. This will treat Z as a literal and ignore the object's offset.
For this particular case, it works, but the "Z" in the end means that the date is in UTC, and you can't hardcode it as a literal. Putting it inside quotes will always print "Z" no matter what's the offset, giving wrong results.
Example:
// wrong: it uses Z inside quotes
DateTimeFormatter wrong = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss:SSS'Z'");
// correct: it uses the offset pattern (X)
DateTimeFormatter correct = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss:SSSXXX");
// print a date/time not in UTC
String ip2 = "2011-05-01T00:00:00.000-05:00";
ZonedDateTime mzt = ZonedDateTime.parse(ip2);
System.out.println(mzt.format(wrong)); // 2011-05-01T00:00:00:000Z
System.out.println(mzt.format(correct)); // 2011-05-01T00:00:00:000-05:00
Note that the wrong formatter prints Z, which is wrong, because the offset of mzt
is -05:00
.
The wrong formatter works for your case because you're using UTC:
// convert to UTC
ZonedDateTime mzt2 = mzt.withZoneSameInstant(ZoneOffset.UTC);
System.out.println(mzt2.format(wrong)); // 2011-05-01T05:00:00:000Z
System.out.println(mzt2.format(correct)); // 2011-05-01T05:00:00:000Z
In this case, both formatters prints the correct result, but that's a coincidence, because mzt2
is in UTC (so the offset is "Z"). But for any offset different than UTC, only the correct formatter will work.
Also note that I used withZoneSameInstant
, that has the same result as using .toInstant().atZone(ZoneOffset.UTC)
.