我有一个场景,我需要将日期时间字符串从 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 回答
Java的日期和时间类似乎存在显着问题 .
让我们使用流行的Joda-Time - Java date and time API . 只需下载最新的稳定版本,并将jar文件添加到项目的构建路径中 .
在逐行的基础上,我已经注释掉了你的代码并重写了Joda Time的替代方案 . 这样,您就可以了解我如何将现有代码转换为Joda Time API .
这实际上非常简单(不需要Joda时间,不是它不是一个很棒的库),你只需要在SimpleDateFormat上设置TimeZone . 在解析时使用源TimeZone,在格式化时使用目标TimeZone(并且您不需要中间日历) .
更新:
日期没有TimeZones . 如果你想要一个带有TimeZone(字符串除外)的东西,那么你需要一个日历 . 除了在解析之前没有在SimpleDateFormat上设置源TimeZone之外,您当前的代码大多是正确的 .
Update
在评论中进行了一些讨论之后,现在看来你根本不应该完全依赖
java.util.Date
. 下面描述的技巧(我原来的答案)可能会奏效,但是 it is not the right thing to do . 切换到支持时区的东西(例如java.util.Calendar
),但最好使用JodaTime .Warning: 这是一个技巧,可能(或可能不)适用于Sun的
java.util.Date
实现,其内部结构用时区初始化 .首先尝试使用
TimeZone.setDefault(...)
设置默认时区 .你最后的电话:
实际上是:
因此,在日历上设置任何时区信息都是毫无意义的 .
Date.toString()
,但是首先对日期进行内部规范化并使用静态TimeZone.getDefaultRef()
. 这应该为您提供默认时区 - 您可以(通常)通过TimeZone.setDefailt(...)
设置 .一定要使用JodaTime .