简体   繁体   中英

Covert date time from one zone to another

This is continuation to one of my previous question where I am not able to parse the date which is resolved now. In the below code, I have a date string and I know the time zone for the date string even though the string itself doesn't contain it. Then I need to convert the date into EST time zone.

        String clientTimeZone = "CST6CDT";
        String value = "Dec 29 2014 11:36PM";
        value=StringUtils.replace(value, "  ", " ");
         DateTimeFormatter df = DateTimeFormat.forPattern("MMM dd yyyy hh:mma").withZone(DateTimeZone.forID(clientTimeZone));
                DateTime temp = df.parseDateTime(value);
                System.out.println(temp.getZone().getID());
                Timestamp ts1 = new Timestamp(temp.getMillis());
                DateTime date = temp.withZoneRetainFields(DateTimeZone.forID("EST"));//withZone(DateTimeZone.forID("EST"));
                Timestamp ts = new Timestamp(date.getMillis());
System.out.println(ts1+"="+ts);

When I am running the code I am expecting ts1 to remain same and ts to be up by 1 hr. But iam getting below which I don't understand. I thought EST is one hour ahead of CST and so if it is 11 in CST, it should be 12 in EST. Also there seems to be offset by about eleven and half hours. Any clues on what I am missing.

2014-12-30 11:06:00.0=2014-12-30 10:06:00.0

I think the below code will help you.

      String clientTimeZone = "CST6CDT";
      String toStimeZone = "EST";
      String value = "Dec 29 2014 11:36PM";
      TimeZone fromTimeZone = TimeZone.getTimeZone(clientTimeZone);
      TimeZone toTimeZone = TimeZone.getTimeZone(toStimeZone);
      Calendar calendar = Calendar.getInstance();
      calendar.setTimeZone(fromTimeZone);
      SimpleDateFormat sf = new SimpleDateFormat("MMM dd yyyy KK:mma");
      Date date = sf.parse(value);
      calendar.setTime(date);
      System.out.println(date);
      calendar.add(Calendar.MILLISECOND, fromTimeZone.getRawOffset() * -1);
      if (fromTimeZone.inDaylightTime(calendar.getTime())) {
          calendar.add(Calendar.MILLISECOND, calendar.getTimeZone().getDSTSavings() * -1);
          }
      calendar.add(Calendar.MILLISECOND, toTimeZone.getRawOffset());
      if (toTimeZone.inDaylightTime(calendar.getTime())) {
      calendar.add(Calendar.MILLISECOND, toTimeZone.getDSTSavings());
      }
      System.out.println(calendar.getTime());

Copied from : http://singztechmusings.wordpress.com/2011/06/23/java-timezone-correctionconversion-with-daylight-savings-time-settings/

The method withZoneRetainFields() preserves the fields in the timezone CST (= UTC-06) hence your local timestamp (as LocalDateTime ) but combines it with a different timezone (EST = UTC-05) which is one hour ahead in offset and result in a different instant. You should it interprete it this way: The same local time happens one hour earlier in New York compared to Chicago.

The rule is to subtract positive offsets and to add negative offsets in order to make timestamp representations of instants comparable (normalizing to UTC offset).

Alternatively: Maybe you don't want this but want to preserve the instant instead of the local fields. In this case you have to use the method withZone() .

Side notice: Effectively, you compare the instants represented by the variables temp and date and finally use your default timezone to print these instants in the JDBC-escape-format (explanation - you implicitly use Timestamp.toString() ). I would rather recommend to use a dedicated instant formatter for this purpose or simpler (to have the offsets in focus):

System.out.println(temp.toInstant() + " = " + date.toInstant());

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