JAVA获得两个日期之间的休息时间差异

时间:2015-10-27 17:16:34

标签: java date timezone timezone-offset

我有一些代码来区分两个日期的两个时区偏移。

int diff= date1.getTimezoneOffset() - date2.getTimezoneOffset();

但是我使用方法getTimezoneOffset(),不推荐使用此方法,我需要以其他方式执行相同的操作。 我如何获得两个日期之间的时区偏移?

PS:我不知道这个日期的TimeZone是什么。

1 个答案:

答案 0 :(得分:0)

令人困惑的混乱

这个问题非常棘手。

java.util.Date类最初设计为具有时区。 JVM的当前默认时区是使用no-arg constructor隐式分配的。我们可以通过getTimeZoneOffset命令提取该时区的offset,如本例所示。

java.util.Date date = new java.util.Date();
int offset = date.getTimezoneOffset (); 

我在America/Los_Angeles时区的结果:

  

420

除以60得到7,与美国西海岸UTC Daylight Saving Time (DST)后面7小时相同。请注意,此类如何使用正数而不是使用UTC后面的偏移的负数,例如在ISO 8601中使用。

因此,如果您真的想要获得两个java.util.Date对象的偏移量的差异,请将int返回的getTimeZoneOffset值对减去几分钟,然后除以60小时。提示:并非所有时区都是整个小时。例如,印度比UTC早5个半小时,+05:30

您可以看到此类实现toString方法时使用的时区。

System.out.println ( "now: " + new java.util.Date ().toString () );
  

Tue Oct 27 2015年1月18日18:49:45

顺便说一句,请注意在该字符串中使用PDT。这样的3-4个字母代码既不是标准的也不是唯一的,应该避免。这个课程的另一个问题。而是使用proper time zone namesAmerica/Los_AngelesAfrica/Casablanca

无法指定时区

奇怪的是,没有可以指定时区的构造函数。也没有用于设置时区的setter方法。我正在考虑弃用和当前的方法。作为替代方案,您可能认为可以在传递给静态the constructor方法上的Date.parse的输入字符串中传递偏移量。但不,这两个都返回一个长(自纪元以来的秒数),而不是指定通过偏移的j.u.Date。这就是为什么我们经常用速记来表示" java.util.Date没有时区"这在技术上是不正确的,但在实际意义上是恰当的。

.Calendar

Java 1.1中,添加了java.util.Calendar课程来接管时区和其他事项的跟踪。所以java.util.Date类在内部分配了它的残留时区,不是很明确但不是完全休眠。

避免使用这些旧类

所有这一切都是一个令人困惑的混乱。理智的出路是完全避免旧的日期时间类:

......和他们的亲戚。

java.time

旧的类现在被Java 8及更高版本中内置的新java.time框架所取代。灵感来自非常成功的Joda-Time库,由JSR 310定义,并由ThreeTen-Extra项目扩展。见the Tutorial

有一些学习曲线可以解决这个框架问题,但是花费的时间已经很长了。新类是合乎逻辑的,统一的,非常有用的。便利方法允许在与尚未更新的代码进行互操作时转换为旧类型以处理新类型。

Instant课程是UTC中时间轴上的一个时刻。 ZonedDateTime是即时调整为时区,表示为ZoneId

Instant instant = Instant.now();
ZoneId zoneId = ZoneId.of ( "America/Los_Angeles" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

转储到控制台。

System.out.println ( "instant: " + instant + "  |  zoneId: " + zoneId + "  |   zdt: " + zdt );
  

时刻:2015-10-28T02:25:25.719Z | zoneId:America / Los_Angeles | zdt:2015-10-27T19:25:25.719-07:00 [America / Los_Angeles]

请记住,时区是与UTC 的偏移量加上用于处理过去,现在和将来异常(例如夏令时)的一组规则。 ZoneId是时区,而ZoneOffset只是offset-from-UTC,没有其他所有规则。一旦我们掌握了ZoneOffset,我们可以将偏移量作为秒数询问。

ZoneOffset zoneOffset = zdt.getOffset ();
int offsetAsSeconds = zoneOffset.getTotalSeconds ();

转储到控制台。

System.out.println ( "zoneOffset: " + zoneOffset + " = offsetAsSeconds: " + offsetAsSeconds );
  

zoneOffset:-07:00 = offsetAsSeconds:-25200

您可以比较一对ZonedDateTime个对象,将它们各自的偏移量作为秒,然后减去得到它们的差异。