Java 确定日期夏令时的算法?

Java 确定日期夏令时的算法?,java,actionscript,Java,Actionscript,最初,我正在寻找Actionscript中的解决方案。这个问题的关键是算法,当一个时钟必须切换夏时制时,它会检测精确的分钟数 因此,例如,在10月25日和31日之间,我们必须检查,如果实际日期是星期日,则是2点之前或之后…没有处理夏令时的真正算法。基本上,每个国家都可以自行决定DST的开始和结束时间。作为开发人员,我们唯一能做的就是使用某种表来查找它。大多数计算机语言在语言中集成了这样一个表 在Java中,可以使用类的inDaylightTime方法。如果您想知道DST在某一年开始或结束的确切日

最初,我正在寻找Actionscript中的解决方案。这个问题的关键是算法,当一个时钟必须切换夏时制时,它会检测精确的分钟数


因此,例如,在10月25日和31日之间,我们必须检查,如果实际日期是星期日,则是2点之前或之后…

没有处理夏令时的真正算法。基本上,每个国家都可以自行决定DST的开始和结束时间。作为开发人员,我们唯一能做的就是使用某种表来查找它。大多数计算机语言在语言中集成了这样一个表

在Java中,可以使用类的
inDaylightTime
方法。如果您想知道DST在某一年开始或结束的确切日期和时间,我建议使用。我看不到一个干净的方法来找出这个仅仅使用标准库

下面的程序就是一个例子:(注意,如果某个时区在某一年内没有DST,它可能会产生意外的结果)

这是正确的,应该被接受

正如里希特所指出的那样,没有任何逻辑可以解释这一现象或其他异常现象。政客们武断地重新定义了他们在政治生活中使用的权力。他们在做出这些改变时,往往没有什么预警,甚至像几周前那样没有任何预警

java.time 下面是一些进一步的想法,以及使用现代java.time类的示例代码,这些类继承了他的答案中所示的Joda time类

这些变化在一个由Olson数据库维护的列表中进行跟踪。您的Java实现、主机操作系统和数据库系统可能都有自己的数据副本,当您关心的区域发生更改时,必须根据需要替换这些副本。这些更改没有逻辑,因此无法通过编程预测更改。您的代码必须调用tzdata的新副本

例如,在10月25日和31日之间,我们必须检查,如果实际日期是星期天,那么它是在2点之前或之后

实际上,您不需要确定切换点。一个好的日期时间库会自动为您处理这些信息

Java拥有最好的此类库,业界领先的Java.time类。当您在某个地区(时区)的某个日期询问某个时间时,如果该时间无效,则会自动进行调整。阅读
ZoneDateTime
的文档,了解该调整中使用的算法

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate ld = LocalDate.of( 2018 , Month.MARCH , 11 );  // 2018-03-11.
LocalTime lt = LocalTime.of( 2 , 0 );  // 2 AM.
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z );
请注意,结果是凌晨3点,而不是要求的凌晨2点。那天在那个区域没有凌晨2点。所以java.time被调整为凌晨3点,因为时钟“提前”了一个小时

zdt.toString():2018-03-11T03:00-04:00[美国/蒙特利尔]

如果您觉得需要调查为时区定义的规则,请使用该类

获取当前时刻使用的DST偏移量

Duration d = z.getRules().getDaylightSavings​( Instant.now() ) ;
获取下一个计划更改,以对象表示

区域:美国/蒙特利尔,2018-11-04T02:00时长变更:PT-1H至2018-11-04T01:00

大陆/地区
的格式指定,例如,或
太平洋/奥克兰
。切勿使用3-4个字母的缩写,如
EST
IST
,因为它们不是真正的时区,也不是标准化的,甚至不是唯一的(!)


关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

该项目现已启动,建议迁移到类

要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
java.sql.*

从哪里获得java.time类

  • 然后
    • 内置的
    • 标准JavaAPI的一部分,带有捆绑实现
    • Java9添加了一些次要功能和修复
    • 大部分java.time功能都在中向后移植到Java6和Java7
    • 更高版本的Android捆绑包实现了java.time类

    • 对于早期的Android(因此joda中没有内置的方法,它采用“DateTime”和“DateTimeZone”并告诉我日期时间是否为白天?@russau(a)是的,russau,joda Time 2.3中有这样一个内置方法。请看另一个问题。(B)你问的问题与这张原始海报不同。
      Duration d = z.getRules().getDaylightSavings​( Instant.now() ) ;
      
      ZoneId z = ZoneId.of( "America/Montreal" );
      ZoneOffsetTransition t = z.getRules().nextTransition( Instant.now() );
      String output = "For zone: " + z + ", on " + t.getDateTimeBefore() + " duration change: " + t.getDuration() + " to " + t.getDateTimeAfter();