How to Parse Date from GMT TimeZone to IST TimeZone and Vice Versa in android

71,564

Solution 1

Date does not have any time zone. It is just a holder of the number of milliseconds since January 1, 1970, 00:00:00 GMT. Take the same DateFormat that you used for parsing, set IST timezone and format your date as in the following example

    DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
    Date date = sdf.parse("2013-01-09T19:32:49.103+05:30"); 
    sdf.setTimeZone(TimeZone.getTimeZone("IST"));
    System.out.println(sdf.format(date));

output

2013-01-09T19:32:49.103+05:30

Note that XXX pattern is used for ISO 8601 time zone (-08:00) since 1.7. If you are in 1.6 try Z. See SimpleDateFormat API for details of format patterns

Solution 2

tl;dr

OffsetDateTime.parse( "2013-01-09T19:32:49.103+05:30" )  // Parsed.
              .toInstant()                               // Adjusted to UTC.

See live code in IdeOne.com.

ISO 8601

Your input string of 2013-01-09T19:32:49.103+05:30 happen to be in standard ISO 8601 format. The +05:30 at the end indicates an offset-from-UTC of five and a half hours ahead, used in India.

java.time

You are using troublesome old date-time classes, now legacy, supplanted by the java.time classes.

The java.time classes happen to use ISO 8601 formats by default when parsing/generating Strings representing date-time values. So no need to specify a formatting pattern at all.

As your input represents a moment on the timeline with an offset-from-UTC, we parse as a OffsetDateTime object.

OffsetDateTime odt = OffsetDateTime.parse( "2013-01-09T19:32:49.103+05:30" );

odt.toString(): 2013-01-09T19:32:49.103+05:30

To obtain a simple object in UTC value, extract an Instant. This Instant class is a basic building-block class of java.time. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

You can think of OffsetDateTime as an Instant plus a ZoneOffset.

Instant instant = odt.toInstant();  // UTC.

When calling toString, a String object is generated in standard ISO 8601 format. The Z on the end is short for Zulu and means UTC.

instant.toString(): 2013-01-09T14:02:49.103Z

An Instant is limited in various ways such as when generating Strings in various formats. So you may want to work with an OffsetDateTime adjusted into UTC as its offset; an offset-of-zero, in other words. The ZoneOffset class holds a constant for UTC, ZoneOffset.UTC.

OffsetDateTime odtUtc = odt.withOffsetSameInstant( ZoneOffset.UTC );

You can also apply an offset (or time zone) to an Instant. Call atOffset or atZone.

The Instant class is the basic building-block class of java.time. Likely to be used often in your code as best practice is to do most of your work in UTC.

OffsetDateTime odt = instant.atOffset( ZoneOffset.ofHoursMinutes( 5 , 30 ) );

Time zone

Note that an offset-from-UTC is not a time zone. A time zone is an offset plus a set of rules, past and present, for handling anomalies such as Daylight Saving Time (DST). So a time zone is always preferable to a mere offset if you are indeed sure of the correct zone.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

If you know the intended time zone, apply a ZoneId to get a ZonedDateTime object. But never assume without verifying with the source of your input data. Many different zones may share a particular offset. For example, in the case of our input here, the offset +05:30 happens to be used today in both India (Asia/Kolkata) and Sri Lanka (Asia/Colombo). Those two time zones may have different rules for different anomalies in their past, present, or future.

ZoneId z = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdt = odt.atZoneSameInstant( z );

The toString method of ZonedDateTime extends standard ISO 8601 format in a wise way by appending the name of the time zone is square brackets. In this case, [Asia/Kolkata].

zdt.toString(): 2013-01-09T19:32:49.103+05:30[Asia/Kolkata]


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 java.time.

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 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.

Solution 3

How could i get a Date class Object having Date in IST format instead of GMT...

You can't. Date doesn't have a format or a time zone. It simply represents a number of milliseconds since the Unix epoch of midnight on January 1st 1970 UTC. Instead, Date.toString() always uses the default time zone.

To use a specific format and time zone, use DateFormat instead of Date.toString(). You can set the time zone with DateFormat.setTimeZone() and then convert a Date to a String using DateFormat.format(). DateFormat itself has some factory methods for creation, or you can use SimpleDateFormat if you want to specify a particular pattern.

As Abu says, Joda Time is a much better date/time API than the built-in one, although for just formatting a date/time the standard library doesn't do a bad job. Just note that DateFormat and its subclasses are generally not thread-safe.

Solution 4

You can do this simply by use of Calender class. Please check below snippets:

Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
calendar.setTimeInMillis(<--time stamp-->);
//calendar.setTime(<--date object of gmt date-->); 
SimpleDateFormat sdf = new SimpleDateFormat("MMM dd, yyyy 'at' hh:mm a");
sdf.setTimeZone(TimeZone.getDefault());
String result=sdf.format(calendar.getTime()); 
Share:
71,564
Amritpal Singh
Author by

Amritpal Singh

Java(J2SE &amp; J2EE),Android Learner and Developer..//

Updated on October 08, 2021

Comments

  • Amritpal Singh
    Amritpal Singh over 2 years

    I am working on a project that fetches Date/Time from backend in IST(Indian standard Time) as shown "2013-01-09T19:32:49.103+05:30". However when i parse it using following DateFormat

    DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
    

    followed by parsing..

    Date date = sdf.parse("2013-01-09T19:32:49.103+05:30");
    
    
    System.out.println("XYZ ==============>"+date);
    

    its Displaying date in GMT format as output i.e

    Wed Jan 09 14:02:49 GMT+00:00 2013.
    

    I have tried it using TimeZone class as..

    TimeZone timeZone=TimeZone.getTimeZone("IST");
    sdf.setTimeZone(timeZone);
    

    but no effect..

    How could i get a Date class Object having Date in IST format instead of GMT...

    Please provide an appropriate solution..

    EDIT:

    This is how Code Looks Like:

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
    
    TimeZone timeZone=TimeZone.getTimeZone("IST");
    sdf.setTimeZone(timeZone);
    
    Date date = sdf.parse("2013-01-09T19:32:49.103+05:30");
    String formattedDate=sdf.format(date);
    
    System.out.println("XYZ ==============>"+formattedDate);
    
  • Jon Skeet
    Jon Skeet over 11 years
    @NarendraPal: Why would you want to change the default time zone? And why would you want to create a new Date with the same value? It's not clear what you're trying to achieve or what the code you've given will do, either.
  • Narendra Pal
    Narendra Pal over 11 years
    I am not able to tell my problem in details, but you can have a look at this. stackoverflow.com/a/10545852/1395259
  • Jon Skeet
    Jon Skeet over 11 years
    @NarendraPal: You haven't even explained your problem slightly, let alone in detail. You dumped a bunch of code in a now-deleted comment (making my comment look very odd) without giving any clue about what you're trying to achieve. The link you've given doesn't give us any more idea of what you're trying to do, or why it's related to my answer here. It sounds like you should ask a new question, following tinyurl.com/so-list (Why would you not be able to give details of what you're trying to achieve? There's no business secret in "I want to convert a date/time to time zone X"...)
  • Amritpal Singh
    Amritpal Singh over 11 years
    Since i have tried DateFormat.format() but it is returning a String having Time in GMT format.
  • Jon Skeet
    Jon Skeet over 11 years
    @AmritpalSingh: Well did you set the time zone to the one you want to use, as my answer says to?
  • Amritpal Singh
    Amritpal Singh over 11 years
    the code looks like this:SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); TimeZone timeZone=TimeZone.getTimeZone("IST"); sdf.setTimeZone(timeZone); Date date = sdf.parse("2013-01-09T19:32:49.103+05:30"); String formattedDate=sdf.format(System.out.println("XYZ ==============>"+formattedDate);
  • Jon Skeet
    Jon Skeet over 11 years
    @AmritpalSingh: Edit it into your question as an update. Code in comments is very hard to read.
  • Narendra Pal
    Narendra Pal over 11 years
    @JonSkeet: I am very sorry for deleting my comment. As I wanted to ask that the link I mentioned, is that link for changing the TimeZone. Sorry for my english I do type with the help of google translator. Thats why said I am not able explain my problem in detail. Sorry
  • Narendra Pal
    Narendra Pal over 11 years
    your article is very helpful.thansk
  • Jon Skeet
    Jon Skeet over 11 years
    @NarendraPal: I suggest you find a friend or colleague who could help you translate your request into a new question.
  • Amritpal Singh
    Amritpal Singh over 11 years
    @Evgniy what is XXX stands for as the code is throwing Exception..Unknown Pattern Exception 'X'
  • Evgeniy Dorofeev
    Evgeniy Dorofeev over 11 years
    it is since 1.7 if you are not 1.7 try ZZZ
  • Amritpal Singh
    Amritpal Singh over 11 years
    @Evgniy it is working for me if I dont mention ZZZ in SimpleDateFormat Constructor....thanx a lot../
  • Amritpal Singh
    Amritpal Singh over 11 years
    However if i write zzz, the output is still in GMT as shown:2013-01-09T14:02:49.103+0000
  • Evgeniy Dorofeev
    Evgeniy Dorofeev over 11 years
    See SimpleDateFormat API z and Z are different patterns
  • Amritpal Singh
    Amritpal Singh over 11 years
    @Evgniy but both shows a Time Period in refernce to GMT as follows 2013-01-09T14:02:49.103+0000 with z and 2013-01-09T14:02:49.103GMT+00:00 with Z
  • Evgeniy Dorofeev
    Evgeniy Dorofeev over 11 years
    You are in Android, right? I am not sure you have IST in your Java. Try sdf.setTimeZone(TimeZone.getTimeZone("GMT+5:30"));