标准时间和夏令时



这不是一个真正的技术编程问题,但它与Java中处理和显示时区有关。

在美国,有像Eastern TimePacific Time这样的时区,在夏令时,它们是Eastern Daylight TimePacific Daylight Time,而在夏令时不生效时,它们是Eastern Standard TimePacific Standard Time

那么,既然日光节约时间开始于三月的第二个星期日,结束于十一月的第一个星期日,那么说三月和十一月之间的日期在Eastern Standard TimePacific Standard Time中是无效的吗?例如,以下日期在技术上是否不存在?

2015年9月29日星期二太平洋标准时间上午10点

不应该是Pacific Daylight Time (PDT),或者仅仅是PT,以避免必须指定DaylightStandard?

…说三月和十一月之间的日期是东部标准时间或太平洋标准时间是无效的吗?

如果你说的是一个时区,在那个特定的时间不观察那个特定的时间段,那么是的——它是无效的。东部标准时间总是UTC-5,东部夏令时总是UTC-4。如果你在说UTC-4的时候说EST,那你就用错了。(人们确实经常用错)

然而,正如其他人指出的那样,在许多时区中有一些地方不遵守夏令时,即使他们周围的地区遵守夏令时。如果你在夏天说MST,它在凤凰城有效,但在洛杉矶无效。

…还是仅仅使用PT来避免指定日光或标准时间?

是的,你可以只写PT而省略SD。在电视上经常这样做,但在电脑上并不常见。此外,这对于世界各地的时区也不成立(伦敦使用GMT和BST -那里没有通用的缩写)。

EST表示EDT中的日期/时间,例如纽约的7月4日,是无效的,但我们人类通常不在乎,并且松散地使用EST。这是错误的,但我们还是做了。

在计算中,我们力求精确,所以肯定无效

但VGR是对的。即使是7月4日也可以是"标准"时间,如果你在一个不遵守夏令时的地方。

正确时区名称

诸如"太平洋夏令时"之类的名称不是真正的时区。他们的3-4个字母代码既不标准化也不唯一。帮你自己一个忙,忘掉他们吧. 不要在你的日期时间工作中使用"PDT", "EST"等。

对于日期时间工作,学习使用适当的时区名称。它们的格式是大陆、斜线和城市或地区。这些都不是任意的或方便的,每个都代表了一个变化的历史或异常的调整或时区的定义。

所以地理位置无关紧要。例如,西雅图离洛杉矶比离凤凰城远得多。但是西雅图的官方时区是America/Los_Angeles,而亚利桑那州使用America/Phoenix

虽然美国西海岸大部分地区使用America/Los_Angeles,但并非所有地区都使用。正如我们说过的,亚利桑那州没有,阿拉斯加州也没有。但请注意它们是如何分别与DST中America/Los_Angeles使用的-07:00和-08:00偏移量重叠的。标准时间变化。(见下文)

所以你必须做功课,了解任何特定地区的官方时区。如果您在业务逻辑中还不知道,则必须询问用户。

使用框架,卢克

你不应该担心夏令时何时开始和结束。使用一个合适的框架来完成日期工作。让框架处理有关DST的基本细节。如果您感兴趣的区域有不断变化的规则,您唯一需要担心的应该是在框架中保持tz数据库的新鲜。

java.time

对于Java 8及以后的版本,选择的框架是新的内置Java。时间框架。(教程)受Joda-Time的启发,由JSR 310定义,由ThreeTen-Extra项目扩展。

ZoneId zoneId_Montréal = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt_Now_Montréal = ZonedDateTime.now( zoneId_Montréal );
String outputNowMontréal = zdt_Now_Montréal.toString( );

outputnow montr: 2015-09-04T01:39:46.962-04:00[America/Montreal]

调整夏令时

夏令时(Daylight Saving Time, DST)是日期时间工作中最常见的异常。当向前跳一小时或向后跳一小时时,这意味着一天中的一些时间值根本不存在或在一天中出现两次。正如ZonedDateTime.of类文档所说:

时区规则,例如夏令时,意味着不是每个本地日期时间都对指定的区域有效,因此可以调整本地日期时间。

该方法解释了java使用的规则。做必要调整的时间。一定要研究它们来理解它们的行为。

文档还说,而不是使用ZonedDateTime.of方法,我们通常应该使用LocalDateTime类从数字创建日期-时间。然后通过使用不同的ZonedDateTime.of静态方法应用ZoneId来获得ZonedDateTime

LocalDateTime localDateTime = LocalDateTime.of( 2015, 9, 29, 10, 0, 0 );
ZoneId zoneId_LosAngeles = ZoneId.of("America/Los_Angeles");
ZonedDateTime zdt_LosAngeles = ZonedDateTime.of( localDateTime, zoneId_LosAngeles ) ;

zdt_LosAngeles: 2015-09-29T10:00-07:00[America/los - angeles]

我们可以将时间轴上的某个时刻表示为两个其他时区。而America/Los_Angeles有标准的&-08:00 &-07:00,America/Phoenix(亚利桑那州)只有-07:00,America/Metlakatla(阿拉斯加)只有-08:00。

ZonedDateTime zdt_Phoenix = zdt_LosAngeles.withZoneSameInstant( ZoneId.of( "America/Phoenix" ) );
ZonedDateTime zdt_Metlakatla = zdt_LosAngeles.withZoneSameInstant( ZoneId.of("America/Metlakatla") );

zdt_Phoenix: 2015-09-29T10:00-07:00[America/Phoenix]

zdt_Metlakatla: 2015-09-29T09:00-08:00[America/Metlakatla]

"Spring Ahead"的夏令时调整规则&"后退"的日子在课程文档中有解释。

将本地日期时间解析为时间线上的单个瞬间。这是通过查找由区域ID规则定义的本地日期时间与UTC/Greenwich的有效偏移量来实现的。

在大多数情况下,本地日期时间只有一个有效的偏移量。在重叠的情况下,当时钟复位时,有两个有效的偏移量。此方法使用通常对应于"summer"的较早偏移量。

在间隙的情况下,当时钟向前跳转时,没有有效的偏移量。相反,本地日期时间将根据间隔的长度调整为较晚。对于典型的一小时夏令时变化,本地日期时间将被移动一小时到通常对应于"summer"的偏移量。

Joda-Time

如果Java 8技术不可用,请使用第三方的Joda-Time框架(它启发了Java .time)。顺便说一下,Joda-Time可以在Android上工作,并且可以从其他人那里获得一些特殊的构建,帮助克服Dalvik类加载器的一些问题。

避免使用旧的日期/日历

避免使用旧的java.util.Date/。Calendar和java.text.SimpleDateFormat类。这些类是业界首次尝试以复杂的方式处理日期时间。但最终它们失败了,被证明是令人困惑的、麻烦的和有缺陷的。

<标题>ISO 8601 h1>

为了这些目的,学习ISO 8601标准字符串格式。java。time和jdbc - time在解析和生成字符串表示时默认使用ISO 8601。

在Java中使用SimpleDateFormat,指定任何一个似乎都是有效的。打印后,您可以看到在解析时发生夏令时转换,即使调用了setLenient(false)

的例子:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy MMMM dd HH:mm:ss z");
sdf.setLenient(false);
Date d = sdf.parse("2015 September 29 10:00:00 PST");
System.out.println(d);

这个输出:

Tue Sep 29 11:00:00 PDT 2015

它接受PST(太平洋标准时间),并在输出时将其转换为PDT(太平洋夏令时)。至少现在是这样。在写这篇文章的时候,夏令时是有效的。

PDT也可以:

Date d2 = sdf.parse("2015 September 29 10:00:00 PDT");
System.out.println(d2);

这个输出:

Tue Sep 29 10:00:00 PDT 2015

注意:这可能取决于是否使用美国语言环境。因为这是我的默认语言环境,所以上面的操作是有效的。如果这不是您的语言环境,请尝试在顶部的SimpleDateFormat构造函数调用中添加第二个参数Locale.US

相关内容

  • 没有找到相关文章