0

I am trying to convert a pst time stamp to gmt in java

I have a string with the time stamp of 2021-03-23T22:00:00.669-07:00. How would I go about that string and convert to a gmt timestamp?

2021-03-24T05:03:00.669Z

I did something I attempted, but haven't gone everywhere

//Date date = new Date(str);
      
String s = str;
DateFormat pstFormat = new SimpleDateFormat();
DateFormat gmtFormat = new SimpleDateFormat();
TimeZone gmtTime = TimeZone.getTimeZone("GMT");
TimeZone pstTime = TimeZone.getTimeZone("PST");
      
pstFormat.setTimeZone(gmtTime);
gmtFormat.setTimeZone(pstTime);
System.out.println("GMT Time: " + pstFormat.format(s));
System.out.println("PST Time: " + gmtFormat.format(s));

The result is java.lang.IllegalArgumentException: Cannot format given Object as a Date in this line:

System.out.println("GMT Time: " + pstFormat.format(s));
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Paul Blart
  • 183
  • 1
  • 3
  • 12
  • 1
    I recommend you don’t use `SimpleDateFormat`, `Date` and `TimeZone`. Those classes are poorly designed and long outdated, the first in particular notoriously troublesome. Instead use for example `OffsetDateTime` and `ZoneId`, both from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Mar 23 '21 at 18:37
  • Does this answer your question? [Java : Cannot format given Object as a Date](https://stackoverflow.com/questions/10649782/java-cannot-format-given-object-as-a-date). Tip: paste your error messages into your search engine. – Ole V.V. Mar 23 '21 at 18:44

2 Answers2

5

tl;dr

OffsetDateTime
.parse( "2021-03-23T22:00:00.669-07:00" ) 
.toInstant()
.toString()

Details

Never use those terrible date-time classes SimpleDateFormat, Date, and TimeZone. Supplanted years ago by the modern java.time classes defined in JSR 310.

Your input carries an offset-from-UTC of negative seven hours. So parse as an OffsetDateTime.

OffsetDateTime odt = OffsetDateTime.parse( "2021-03-23T22:00:00.669-07:00" ) ;
Instant instant = odt.toInstant() ;
String output = instant.toString() ;

Both your input and desired output comply with the ISO 8601 standard. The java.time classes use those standard formats by default when parsing/generating text. So no need to specify a formatting pattern.

Never use 2-4 letter pseudo-zones such as PST. Use real time zone names in format of Continent/Region such as America/Los_Angeles. Furthermore, contrary to your first sentence, your input does not represent a moment in a specific time zone. Many time zones may share an offset of -07:00 at that moment, so no way to know which time zone was intended by your data source.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
1

The answer by Basil Bourque is well-explained and spot-on. Just in case, you need to convert such a date-time string to a date-time object in any timezone, you can use ZonedDateTime#withZoneSameInstant. You have a similar method, OffsetDateTime#withOffsetSameInstant to deal with OffsetDateTime.

import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        // Tests
        System.out.println(getDateTimeInDifferentTimezone("2021-03-23T22:00:00.669-07:00", "Etc/UTC"));// GMT
        System.out.println(getDateTimeInDifferentTimezone("2021-03-23T22:00:00.669-07:00", "America/New_York"));
        System.out.println(getDateTimeInDifferentTimezone("2021-03-23T22:00:00.669-07:00", "Asia/Calcutta"));
    }

    static ZonedDateTime getDateTimeInDifferentTimezone(String txtDateTime, String timezone) {
        return ZonedDateTime.parse(txtDateTime).withZoneSameInstant(ZoneId.of(timezone));
    }
}

Output:

2021-03-24T05:00:00.669Z[Etc/UTC]
2021-03-24T01:00:00.669-04:00[America/New_York]
2021-03-24T10:30:00.669+05:30[Asia/Calcutta]

Learn more about the modern date-time API from Trail: Date Time.

Note that the java.util date-time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API*.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110