我有一些代码来获取两个日期的两个时区偏移量之间的差异。
int diff= date1.getTimezoneOffset() - date2.getTimezoneOffset();
但我使用的是方法getTimezoneOffset()
,该方法已被弃用,我需要用其他方法也这样做。如何获取两个日期之间的时区偏移量?
PS.:我不知道这个日期的时区是多少。
混乱的混乱
这个问题非常棘手。
java.util.Date
类最初设计为具有时区。JVM的当前默认时区是使用无参数构造函数隐式分配的。我们可以通过getTimeZoneOffset
命令提取该时区的偏移量,如本例所示。
java.util.Date date = new java.util.Date();
int offset = date.getTimezoneOffset ();
我在America/Los_Angeles
时区的结果:
420
除以60得到7,因为UTC后的7小时是美国西海岸夏令时(DST)。请注意,此类如何使用正数而不是负数来表示UTC后面的偏移量,如ISO 8601中更常用的偏移量。
因此,如果您真的想得到两个java.util.Date对象的偏移量之差,请减去getTimeZoneOffset
返回的一对int
值(分钟),再除以60(小时)。提示:并非所有时区都是整小时。例如,印度领先UTC +05:30
五个半小时。
您可以看到此类实现toString
方法所使用的时区。
System.out.println ( "now: " + new java.util.Date ().toString () );
10月27日星期二18:49:45 PDT 2015
顺便说一句,请注意该字符串中使用了PDT
。这种3-4个字母的代码既不是标准化的,也不是唯一的,应该避免。这是这个阶层的另一个问题。而是使用适当的时区名称,如America/Los_Angeles
或Africa/Casablanca
。
无法指定时区
奇怪的是,没有一个构造函数可以在其中指定时区。也没有设置时区的setter方法。我正在考虑弃用的方法和当前的方法。作为替代方案,您可能认为可以将偏移量作为输入字符串的一部分传递给静态Date.parse
方法上的构造函数。但不是,这两个都返回一个长的(自epoch以来的秒数),而不是分配给该偏移量的j.u.Date。这就是为什么我们经常说"java.util.Date没有时区",这在技术上是不正确的,但在实际意义上是恰当的。
随之而来的是.Calendar
在Java 1.1中,添加了java.util.Calendar
类来接管时区和其他事务的跟踪。因此,java.util.Date类的剩余时区在内部分配,不太明确,也不太休眠。
避免这些旧类
所有这些都是一团糟。明智的解决方法是完全避免旧的日期时间类:
java.util.Date
java.util.Calendar
java.text.SimpleTextFormat
…和他们的亲人。
java.time
旧的类现在被构建在Java8及更高版本中的新java.time框架所取代。灵感来自于非常成功的Joda Time库,该库由JSR310定义,并由ThreeTen Extra项目扩展。请参见教程。
有一些学习曲线可以掌握这个框架的窍门,但时间花得很好。新类具有逻辑性、统一性,并且非常有用。当与尚未更新以处理新类型的代码进行互操作时,方便的方法提供了转换为旧类型的功能。
Instant
类是UTC时间线上的一个时刻。CCD_ 19是被调整到表示为CCD_。
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:美国/洛杉矶|zdt:2015-10-27T19:25:5.719-07:00[美国/洛杉矶]
请记住,时区是UTC的偏移量加上一组用于处理过去、现在和未来异常(如夏令时)的规则。ZoneId
是一个时区,而ZoneOffset
只是与UTC的偏移量,没有所有其他规则。一旦我们手头有ZoneOffset
,我们就可以询问偏移量的秒数。
ZoneOffset zoneOffset = zdt.getOffset ();
int offsetAsSeconds = zoneOffset.getTotalSeconds ();
转储到控制台。
System.out.println ( "zoneOffset: " + zoneOffset + " = offsetAsSeconds: " + offsetAsSeconds );
zoneOffset:-07:00=offsetAs秒数:-25200
您可以比较一对ZonedDateTime
对象,得到它们各自的偏移量(秒),然后相减得到它们的差值。