我在将字符串转换为UTC数据,然后转换为各种时区时遇到问题。根据我是否转换为EST或PST,我的程序似乎表现不同。这是我的代码:
SimpleDateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
utcFormat.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));
Date date = utcFormat.parse("2014-08-18 17:00:17");
SimpleDateFormat localFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
localFormat.setTimeZone(java.util.TimeZone.getTimeZone("PST"));
System.out.println(localFormat.format(date));
如果我运行上面的代码,这是我的输出:
2014-08-18 10:00:17
这反映了与提供的UTC时间相差7小时:2014-08-18 17:00:17。这是我所期待的。现在,如果我将该日期更改为2014-11-18 17:00:17(从8月更改为11月),则输出结果如下:
2014-11-18 09:00:17
据我所知,这也很好。输出反映了与UTC的8小时偏移,我相信这是因为11月不是夏令时,而8月是。
我遇到的问题是,如果我从" PST"更改时区,则上述相同代码的工作方式会有所不同。到" EST"。当我改为EST时,无论我的日期是8月还是11月,我都会获得相同的时间输出。
以下是使用EST和2014-08-18 17:00:17的输出
2014-08-18 12:00:17
以下是使用EST和2014-11-18 17:00:17的输出
2014-11-18 12:00:17
在这两种情况下,输出表示距离UTC的5小时偏移,这仅在11月期间有意义,而不是在8月期间。
任何人都可以向我解释我做错了什么吗?
答案 0 :(得分:3)
您应该使用EST
或America/New_York
(这些是别名),而不是使用US/Eastern
。三个字母的时区缩写是不明确的,你不能确定你得到了什么。
答案 1 :(得分:1)
来自TimeZone的文档
为了与JDK 1.1.x兼容,还支持其他一些三字母时区ID(例如“PST”,“CTT”,“AST”)。但是,它们的使用已被弃用,因为相同的缩写通常用于多个时区(例如,“CST”可能是美国“中央标准时间”和“中国标准时间”),然后Java平台只能识别其中一个它们。
而不是"EST"
,"US/Eastern"
将更清楚你的意图。
这些是受支持的美国别名。
答案 2 :(得分:0)
@Compass是对的。 以下是您将使用的代码:
public static void main(String[] args) {
SimpleDateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
utcFormat.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));
Date date = null;
try {
date = utcFormat.parse("2014-08-18 17:00:17");
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SimpleDateFormat localFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
localFormat.setTimeZone(java.util.TimeZone.getTimeZone("US/Eastern"));
System.out.println(localFormat.format(date));
}
答案 3 :(得分:0)
任何人都可以向我解释我做错了吗?
是。您使用的是一个糟糕且令人困惑的日期时间库。
java.util.Date
java.util.Date和.Calendar类非常麻烦,在设计和实现方面都存在缺陷。使用体面的图书馆。在Java中,这意味着Joda-Time或java.time package中的新Java 8(受Joda-Time启发,由JSR 310定义)。
虽然j.u.Date没有时区,但在Joda-Time和java.time中,日期时间对象确实知道自己指定的时区。使这项工作更容易,更明智。
使用proper time zone names。避免使用2个,3个或4个字母代码,因为它们既不标准也不唯一。大多数专有名称都是Continent/CityOrRegion
。
您不必担心夏令时。让日期时间库在那里进行繁重的工作。您需要做的就是确保您的磁带库使用时区数据库的新版本。政客们喜欢重新定义夏令时。
Joda-Time和java.time都支持ISO 8601格式作为解析和生成日期时间值的字符串表示的默认值。
以下是Joda-Time 2.4中的一些示例代码。此示例中的所有DateTime对象表示Universe历史记录中的相同时刻,但经过调整以显示每个地点的人员所看到的wall-clock time。
String inputRaw = "2014-08-18 17:00:17"; // Nearly in [ISO 8601][7] format.
String input = inputRaw.replace( " ", "T" );
DateTime dateTimeUtc = DateTime.parse( input, DateTimeZone.UTC );
DateTime dateTimeLosAngeles = dateTimeUtc.withZone( DateTimeZone.forID( "America/Los_Angeles" ) );
DateTime dateTimeNewYork = dateTimeUtc.withZone( DateTimeZone.forID( "America/New_York" ) );
DateTime dateTimeMontréal = dateTimeUtc.withZone( DateTimeZone.forID( "America/Montreal" ) );
DateTime dateTimeKolkata = dateTimeUtc.withZone( DateTimeZone.forID( "Asia/Kolkata" ) );
答案 4 :(得分:-1)
这是因为EST
在保存之外是ET
,其转变是不变的,夏令时的补充区域为EDT
。
你应该使用ET
来获得预期的行为。
更多关于Wikipedia