如何在Java中使用TimeZone解决日光节约问题

我必须在我的Java应用程序中打印EST时间。 我使用以下方法将时区设置为EST:

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST")); 

但是,如果在这个时区中遵守夏令时,我的代码不会打印正确的时间(打印时间会less一小时)。

如何使代码工作始终阅读正确的时间,无论是否遵守夏令时?

PS:我尝试将时区设置为EDT,但不能解决问题。

这是开始的问题:

 Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST")); 

应该完全避免使用3个字母的缩写来支持TZDB区域ID。 EST是东部标准时间 – 标准时间从不观察DST; 这不是一个完整的时区名称。 这是用于部分时区的名称。 (不幸的是,我对这个“半时区”概念没有遇到很好的说法。)

你想要一个完整的时区名称。 例如, America/New_York位于东部时区:

 TimeZone zone = TimeZone.getTimeZone("America/New_York"); DateFormat format = DateFormat.getDateTimeInstance(); format.setTimeZone(zone); System.out.println(format.format(new Date())); 

其他的答案是正确的,尤其是Jon Skeet的那个 ,但是已经过时了。

java.time

这些旧的date时间类已被Java 8及更高版本中内置的java.time框架取代。

如果您只需要UTC中的当前时间,请使用Instant类。

 Instant now = Instant.now(); 

正如Jon Skeet的正确答案所解释的, EST不是一个时区。 这样的3-4个字母代码既不是标准化的,也不是独一无二的,而且还有夏令时(DST)的混淆。 在“大陆/地区”格式中使用适当的时区名称。

也许你指的是北美东海岸的东部标准时间? 还是埃及标准时间? 还是欧洲标准时间?

 ZoneId zoneId = ZoneId.of( "America/New_York" ); ZoneId zoneId = ZoneId.of( "Africa/Cairo" ); ZoneId zoneId = ZoneId.of( "Europe/Lisbon" ); 

使用任何这样的ZoneId对象来获取当前时刻调整到一个特定的时区产生一个ZonedDateTime对象。

 ZonedDateTime zdt = ZonedDateTime.now( zoneId ) ; 

通过从第一个生成另一个ZonedDateTime对象,将ZonedDateTime调整到不同的时区。 java.time框架使用不可变的对象,而不是改变(改变)现有的对象。

 ZonedDateTime zdtGuam = zdt.withZoneSameInstant( ZoneId.of( "Pacific/Guam" ) ) ; 

而不是为时区input“EST”,您可以input“EST5EDT”。 正如你所说,只是“EDT”不起作用。 这将解决夏令时问题。 代码行如下所示:

 Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST5EDT")); 

根据这个答案 :

 TimeZone tz = TimeZone.getTimeZone("EST"); boolean inDs = tz.inDaylightTime(new Date()); 

实现TimeZone类来设置日历的时区可以节省夏令时间。

java.util.TimeZone表示时区偏移量,并计算夏时制。

示例代码:

 TimeZone est_timeZone = TimeZoneIDProvider.getTimeZoneID(TimeZoneID.US_EASTERN).getTimeZone(); Calendar enteredCalendar = Calendar.getInstance(); enteredCalendar.setTimeZone(est_timeZone); 

在java中,DateFormatter默认使用DST,为了避免日光节约(DST),你需要手动做一个技巧,
首先你必须得到DST偏移,即应用多less毫秒的DST,对于某个地方,DST也是45分钟,对于某些地方是30分钟
但在大多数情况下,DST是1小时
您必须使用Timezone对象,并检查date是否属于DST,然后您必须手动添加DST的偏移量。 例如:

  TimeZone tz = TimeZone.getTimeZone("EST"); boolean isDST = tz.inDaylightTime(yourDateObj); if(isDST){ int sec= tz.getDSTSavings()/1000;// for no. of seconds Calendar cal= Calendar.getInstance(); cal.setTime(yourDateObj); cal.add(Calendar.Seconds,sec); System.out.println(cal.getTime());// your Date with DST neglected }