[英]Java TimeZone with DST
我有以下代码:
public static void main(String[] args) {
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//get current date time with Date()
Date date = new Date();
String currentDate = dateFormat.format(date);
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
System.out.println(sdf.format(getSomeDate(currentDate,TimeZone.getTimeZone("Asia/Omsk"))));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static Date getSomeDate(final String str, final TimeZone tz) throws ParseException {
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
sdf.setTimeZone(tz);
return sdf.parse(str);
}
现在的问题是,如果我使用我想要的时区(即“美国/芝加哥”),我会得到完全错误的时间。 它执行当前时间 +6 而不是 -6。
那么我该如何解决这个问题,因为现在我必须从 GMT + 6 设置一个时区才能为我的程序获取正确的时间和日期。
另外,Java 是否会自动合并 DST 设置? 由于世界各地的人们都在使用它,因此有些人使用不同的 DST 时间,因此很难保持正确的时间。
现代方法使用java.time类。 您正在使用糟糕的日期时间类,这些类在几年前随着 JSR 310 的采用而过时了。
String input = "2020-01-23 15:00:00" ;
这样的输入缺少时区或UTC偏移量的指标。 所以我们必须解析为LocalDateTime
。 这样的对象不表示一个时刻,因为我们如果你的意思是下午3点在东京,图卢兹,或托莱多不知道-很不同时刻几个小时间隔。
LocalDateTime ldt = LocalDateTime.parse( input.replace( " " , "T" ) ) ;
您似乎确定此日期和时间适用于America/Chicago
的时区。
ZoneId z = ZoneId.of( "America/Chicago" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ldt , z ) ;
让我们以标准 ISO 8601 格式生成一个字符串,以检查当时该区域中使用的偏移量。 ZonedDateTime::toString
方法明智地扩展了标准,将区域名称附加在方括号中。
String output = zdt.toString() ;
输出:2020-01-23T15:00-06:00[美国/芝加哥]
现在我们已经确定了一个时刻,在我们的ZonedDateTime
对象中。 我们在时间线上有一点,芝加哥地区的挂钟时间似乎是下午 3 点。 正如我们在-06:00
看到的那样,这比 UTC 晚了六个小时。
我们可以通过提取Instant
对象来调整到 UTC。 这将使一天中的时间看起来提前六个小时到晚上 9 点。 同一时刻,时间线上的同一点,但挂钟时间不同。 就像冰岛(使用 UTC 作为时区)和芝加哥的两个人打电话一样:如果两人同时抬头看墙上的时钟,一个人看到的是下午 3 点,而另一个看到的是下午 6 点。
Instant instant = zdt.toInstant() ;
Instant.toString(): 2020-01-23T21:00:00Z
你问了“来自世界各地的人,所以有些人的夏令时不同”。 您可以轻松地将时刻调整到其他时区。 也许东京的某个人希望在他们的时区看到同一时刻,比UTC早几个小时,而不是晚几个小时。
ZoneId zTokyo = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdtTokyo = zdt.withZoneSameInstant( zTokyo ) ;
要么:
ZonedDateTime zdtTokyo = instant.atZone( z ) ;
zdtTokyo.toString(): 2020-01-24T06:00+09:00[亚洲/东京]
请注意日期如何从 23 日跃升至 24 日,以及一天中的时间跳跃。 同样,同一时刻,不同的挂钟时间。
java.time框架内置于 Java 8 及更高版本中。 这些类取代麻烦的老传统日期时间类,如java.util.Date
, Calendar
,和SimpleDateFormat
。
要了解更多信息,请参阅Oracle 教程。 并在 Stack Overflow 上搜索许多示例和解释。 规范是JSR 310 。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
您可以直接与您的数据库交换java.time对象。 使用符合JDBC 4.2或更高版本的JDBC 驱动程序。 不需要字符串,不需要java.sql.*
类。
从哪里获得 java.time 类?
ThreeTen-Extra项目用额外的类扩展了 java.time。 该项目是未来可能添加到 java.time 的试验场。 您可以在这里找到一些有用的类,比如Interval
, YearWeek
, YearQuarter
,和更多。
问题,我想是你在 getSomeDate() 方法中只为 SimpleDateFormat 设置了一次 TimeZone 。 尝试对 SimpleDateFormat 的所有实例执行此操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.