首页 文章

将日期时间字符串从一个时区A转换为时区B,其中jvm在时区C中运行

提问于
浏览
1

我有一个场景,我需要将日期时间字符串从 Timezone A(UTC) 转换为 Timezone B(EST) .

这里捕获的是发生这种转换的JVM是 Timezone C(HKT) Date Object .

所以代码块如下:

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

我期望的输出是来自最后一个语句的“ Fri Nov 14 16:30:00 EST 2014 ”,即可用的最终日期对象应该在 EST 中 .

如果有人有这方面的信息,请告诉我们 .


更新:
只是为了明确我的请求,输出应仅在 Date object 中 .

我打印的示例代码和输出仅用于更清楚的解释 .

所以基本上字符串“ 20141114213000 ”是 UTC Date String 需要转换为 EST Date Object 和JVM,其中发生这种转换的是 HKT .

3 回答

  • 1

    Java的日期和时间类似乎存在显着问题 .

    让我们使用流行的Joda-Time - Java date and time API . 只需下载最新的稳定版本,并将jar文件添加到项目的构建路径中 .

    在逐行的基础上,我已经注释掉了你的代码并重写了Joda Time的替代方案 . 这样,您就可以了解我如何将现有代码转换为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
        }
    }
    
  • 0

    这实际上非常简单(不需要Joda时间,不是它不是一个很棒的库),你只需要在SimpleDateFormat上设置TimeZone . 在解析时使用源TimeZone,在格式化时使用目标TimeZone(并且您不需要中间日历) .

    更新:

    日期没有TimeZones . 如果你想要一个带有TimeZone(字符串除外)的东西,那么你需要一个日历 . 除了在解析之前没有在SimpleDateFormat上设置源TimeZone之外,您当前的代码大多是正确的 .

  • 1

    Update

    在评论中进行了一些讨论之后,现在看来你根本不应该完全依赖 java.util.Date . 下面描述的技巧(我原来的答案)可能会奏效,但是 it is not the right thing to do . 切换到支持时区的东西(例如 java.util.Calendar ),但最好使用JodaTime .


    Warning: 这是一个技巧,可能(或可能不)适用于Sun的 java.util.Date 实现,其内部结构用时区初始化 .

    首先尝试使用 TimeZone.setDefault(...) 设置默认时区 .

    你最后的电话:

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

    实际上是:

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

    因此,在日历上设置任何时区信息都是毫无意义的 .

    Date.toString() ,但是首先对日期进行内部规范化并使用静态 TimeZone.getDefaultRef() . 这应该为您提供默认时区 - 您可以(通常)通过 TimeZone.setDefailt(...) 设置 .

    一定要使用JodaTime .

相关问题