Reputation: 77
I am trying to convert GMT to IST.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSS");
Date c= sdf.parse("2017-03-31T10:38:14.4723017Z");
Date date = new Date();
DateFormat istFormat = new SimpleDateFormat();
DateFormat gmtFormat = new SimpleDateFormat();
TimeZone gmtTime = TimeZone.getTimeZone("GMT");
TimeZone istTime = TimeZone.getTimeZone("IST");
istFormat.setTimeZone(gmtTime);
gmtFormat.setTimeZone(istTime);
System.out.println("GMT Time: " + istFormat.format(c));
System.out.println("IST Time: " + gmtFormat.format(c));
My output is
GMT Time: 31/3/17 6:26 AM
IST Time: 31/3/17 11:56 AM
But my actual output should be
GMT Time: 31/3/17 5:08 AM
IST Time: 31/3/17 10:38 AM
What is wrong with my code?
Upvotes: 3
Views: 22721
Reputation: 79560
TimeZone
documentation:Three-letter time zone IDs
For compatibility with JDK 1.1.x, some other three-letter time zone IDs (such as "PST", "CTT", "AST") are also supported. However, their use is deprecated because the same abbreviation is often used for multiple time zones (for example, "CST" could be U.S. "Central Standard Time" and "China Standard Time"), and the Java platform can then only recognize one of them.
SimpleDateFormat
processes the number of decimal points as the milliseconds. 4723017 milliseconds = 1 hour 18 minutes 43.017S which explains the difference in your output. System.out.println(Duration.ofMillis(4723017)); // PT1H18M43.017S
java.time
In March 2014, Java 8 introduced the modern, java.time
date-time API which supplanted the error-prone legacy java.util
date-time API. Any new code should use the java.time
API.
Your given date-time string is in the ISO 8601 format, the default format used by java.time
types. So, you do not need to use a DateTimeFormatter
explicitly to parse it into an Instant
or a ZonedDateTime
or an OffsetDateTime
e.g.
Instant instant = Instant.parse("2017-03-31T10:38:14.4723017Z");
ZonedDateTime zdt = ZonedDateTime.parse("2017-03-31T10:38:14.4723017Z");
OffsetDateTime odt = OffsetDateTime.parse("2017-03-31T10:38:14.4723017Z");
Note that Z
represents a time zone offset of +00:00
i.e. zero offset from UTC or GMT. I have parsed your date-time string into an Instant
and converted it into a ZonedDateTime
at ZoneId.of("Asia/Kolkata")
.
Demo:
class Main {
public static void main(String args[]) {
Instant instant = Instant.parse("2017-03-31T10:38:14.4723017Z");
System.out.println(instant);
ZonedDateTime zdt = instant.atZone(ZoneId.of("Asia/Kolkata"));
System.out.println(zdt);
// Representation in a custom format
System.out.println(zdt.format(
DateTimeFormatter.ofPattern("M/d/uu h:mm a VV", Locale.ENGLISH)
));
}
}
Output:
2017-03-31T10:38:14.472301700Z
2017-03-31T16:08:14.472301700+05:30[Asia/Kolkata]
3/31/17 4:08 PM Asia/Kolkata
Learn more about the modern Date-Time API from Trail: Date Time.
Upvotes: 1
Reputation: 2535
Milliseconds (SSS) can only be three digits. On more than that, the date rolls over - e.g. 10:38:14.1000 becomes 10:38:15.000. Add a couple of million milliseconds... and you get the behaviour that you're seeing now.
Try this.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
Date c = sdf.parse("2017-03-31T10:38:14.472Z");
System.out.println(c);
DateFormat istFormat = new SimpleDateFormat();
DateFormat gmtFormat = new SimpleDateFormat();
TimeZone gmtTime = TimeZone.getTimeZone("GMT");
TimeZone istTime = TimeZone.getTimeZone("IST");
istFormat.setTimeZone(gmtTime);
gmtFormat.setTimeZone(istTime);
System.out.println("GMT Time: " + istFormat.format(c));
System.out.println("IST Time: " + gmtFormat.format(c));
Upvotes: 6
Reputation: 132
Have you tried changing the format to "yyyy-MM-dd'T'HH:mm:ss.sssssssZ"
?
Also, when you type Z
in your Date object, you should write the time zone designator, for example, "2017-03-31T10:38:14.4723017+01:00".
Upvotes: -1