我有一些代码来区分两个日期的两个时区偏移。
int diff= date1.getTimezoneOffset() - date2.getTimezoneOffset();
但是我使用方法getTimezoneOffset()
,不推荐使用此方法,我需要以其他方式执行相同的操作。
我如何获得两个日期之间的时区偏移?
答案 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 names或America/Los_Angeles
等Africa/Casablanca
。
奇怪的是,没有可以指定时区的构造函数。也没有用于设置时区的setter方法。我正在考虑弃用和当前的方法。作为替代方案,您可能认为可以在传递给静态the constructor方法上的Date.parse
的输入字符串中传递偏移量。但不,这两个都返回一个长(自纪元以来的秒数),而不是指定通过偏移的j.u.Date。这就是为什么我们经常用速记来表示" java.util.Date没有时区"这在技术上是不正确的,但在实际意义上是恰当的。
.Calendar
在Java 1.1中,添加了java.util.Calendar
课程来接管时区和其他事项的跟踪。所以java.util.Date类在内部分配了它的残留时区,不是很明确但不是完全休眠。
所有这一切都是一个令人困惑的混乱。理智的出路是完全避免旧的日期时间类:
......和他们的亲戚。
旧的类现在被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
个对象,将它们各自的偏移量作为秒,然后减去得到它们的差异。