简体   繁体   中英

Convert Date Time String from one timezone A to timezone B where jvm is running in timezone C

I have a scenario where I need to convert a date time string from Timezone A(UTC) to Timezone B(EST) .

Catch here is the JVM where this transformation is happening is Timezone C(HKT) Date Object .

So the code block is as follows:

String dateString="20141114213000";
dateString += " UTC";
String formatString ="yyyyMMddHHmmss";
SimpleDateFormat sdf = new SimpleDateFormat(formatString + " z");

 Date localDate = sdf.parse(dateString);
 System.out.println("Local Date::"+localDate); // Local Date::Sat Nov 15 05:30:00 HKT 2014

 Calendar localCal = Calendar.getInstance();
 localCal.setTime(localDate);

 TimeZone estTimeZone = TimeZone.getTimeZone("America/New_York");

 localCal.setTimeZone(estTimeZone);
 sdf.setTimeZone(estTimeZone);

 System.out.println(sdf.format(localCal.getTime()));//20141114163000 EST

 System.out.println(localCal.getTime());//Sat Nov 15 05:30:00 HKT 2014

The output I am expecting is to be " Fri Nov 14 16:30:00 EST 2014 " from the last statement, ie, the final date object available should be in EST .

Please let know if anyone has info on this.


Update:
Just to make my request clear, output should be in Date object only.

The sample code and the output I printed is only for clearer explanation.

So basically String " 20141114213000 " which is a UTC Date String needs to be converted to EST Date Object and JVM where this transformation is happening is in HKT .

There seems to be notable issues with Java's Date and Time classes.

Lets use the popular Joda-Time - Java date and time API . Simply download the newest stable release and add the jar files to your project's build path.

On a line-by-line basis, I have commented out your code and rewritten the Joda Time alternative. This way you can understand how I transitioned your existing code to the Joda Time API.

import java.text.ParseException;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class JodaTimeTransition {
    public static void main(String[] args) throws ParseException {
        String dateString="20141114213000";
        dateString += " UTC";

        /*new*/
        String formatString = "yyyyMMddHHmmss z";
//      String formatString ="yyyyMMddHHmmss";

        /*new*/ 
        DateTimeFormatter dtf = DateTimeFormat.forPattern(formatString);
//      SimpleDateFormat sdf = new SimpleDateFormat(formatString + " z");

        /* new - Create localDate using JodaTime DateTime class */
        DateTime localDate = DateTime.parse(dateString, dtf);
//      Date localDate = sdf.parse(dateString);

        /* new - convert time to MST, since it is currently UTC*/
        localDate = localDate.toDateTime(DateTimeZone.forID("America/Denver"));

        /* new - print out <local date> using specified format.*/
        System.out.println("Local Date::" + localDate.toString("EEE MMM dd HH:mm:ss z yyyy"));
        /* Where did you get the local date mentioned at comments of line below? */
//      System.out.println("Local Date::"+localDate); // Local Date::Sat Nov 15 05:30:00 HKT 2014


        /* new - Get reference to current date/time as <localCal> 
         * (This step can be omitted, and the previous localDate variable can be used)
        */
        DateTime localCal = DateTime.now();
//      Calendar localCal = Calendar.getInstance();

        /* new - Set <localCal> to <localDate> */
        localCal = localDate;
//      localCal.setTime(localDate);

        /* new - Create new EST time zone*/
        DateTimeZone estTimeZone= DateTimeZone.forID("America/New_York");
//      TimeZone estTimeZone = TimeZone.getTimeZone("America/New_York");

        /* new - set <localCal> time zone from MST to EST */
        localCal = localCal.toDateTime(estTimeZone);
//      localCal.setTimeZone(estTimeZone);
//      sdf.setTimeZone(estTimeZone);

        /* new - print <localCal> as new EST time zone */
        System.out.println(localCal.toString("yyyyMMddHHmmss z"));
//      System.out.println(sdf.format(localCal.getTime()));//20141114163000 EST

        /* new - print in desired format: Fri Nov 14 16:30:00 EST 2014 */
        System.out.println(localCal.toString("EEE MMM dd HH:mm:ss z yyyy"));
//      System.out.println(localCal.getTime());//Sat Nov 15 05:30:00 HKT 2014
    }
}

This is actually very straightforward (no need for Joda time, not that it isn't a great library), you just need to set the TimeZone on the SimpleDateFormat. Use the source TimeZone when you parse, then the destination TimeZone when you format (and you don't need the intermediate Calendar).

UPDATE:

Date's don't have TimeZones. If you want something with a TimeZone (other than a String), then you will need a Calendar. Your current code is mostly correct except that you haven't set the source TimeZone on the SimpleDateFormat before parsing.

Update

After some discussion in the comments, it seems now clear that you should not rely on java.util.Date for time zones at all. The trick sketched below (my original answer) will probably work, but it is not the right thing to do . Switch to something which supports time zones ( java.util.Calendar for instance), but better use JodaTime.


Warning: this is a trick which may (or may not) work for Sun's implementation of java.util.Date whose internal structures are initialized with a time zone.

Try setting the default time zone with TimeZone.setDefault(...) first.

Your last call:

System.out.println(localCal.getTime());

Is actually:

System.out.println(new Date(localCal.getTimeInMillis()).toString());

So setting any time zone info on the calendar is pointless.

Date.toString() , however first does an internal normalization on the date and uses the static TimeZone.getDefaultRef() . This should give you the default time zone - which you can (normally) set via TimeZone.setDefailt(...) .

And by all means use JodaTime.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM