我在PHP中遇到了奇怪的行为:
(strtotime("2017-11-05 00:00:00") - strtotime("2017-11-06 00:00:00")) / 24//3600
(strtotime("2017-11-06 00:00:00") - strtotime("2017-11-05 00:00:00")) / 24//3750
(strtotime("2017-11-07 00:00:00") - strtotime("2017-11-06 00:00:00")) / 24//3600正如我所发现的,它与从夏季到冬季的时间转换(https://www.timeanddate.com/time/change/usa/new-york)有关。行为正确吗?我在文档里看不到任何与它有关的东西。有人有联系吗?
至少,在java中,它可以像我预期的那样工作:
System.out.println(((new Date(2017, 11, 6).getTime()) - (new Date(2017, 11, 5).getTime())) / 24);//3600000现在是个问题。我如何定义,这一天是25小时,我应该以特殊的方式处理这个日期?
发布于 2017-11-25 01:52:48
虽然我不能回答您问题的PHP部分,但我可以更正您的Java代码。
tl;dr
Duration.between(
LocalDate.of( 2017 , Month.NOVEMBER , 5 ).atStartOfDay( ZoneId.of( "America/New_York" ) ) ,
LocalDate.of( 2017 , Month.NOVEMBER , 5 ).plusDays( 1 ).atStartOfDay( ZoneId.of( "America/New_York" ) )
).toString()PT25H
Duration.between(
LocalDate.of( 2017 , Month.NOVEMBER , 5 ).atStartOfDay( ZoneOffset.UTC ) ,
LocalDate.of( 2017 , Month.NOVEMBER , 5 ).plusDays( 1 ).atStartOfDay( ZoneOffset.UTC )
).toString()PT24H
在,UTC的一天总是24小时的长度。在中,一些时区的一天可能是23、24、25或其他一些小时,甚至可能包括部分(小数)小时。
详细信息
您对Java使用了错误的类,而忽略了时区这一关键问题。java.util.Date类令人困惑、麻烦,幸运的是,现在是遗留的。现代的java.time类取代了那些旧的日期时间类。
您将忽略示例代码中的时区这一关键问题。遗留的Date类总是位于UTC,但您关心的是America/New_York时区。您的代码是计算一般24小时一天(UTC)的24小时,而在America/New_York中的2017-11-05实际上是25小时而不是24小时。
您的Java示例代码对我来说没有任何意义,因为您正在计算一个以毫秒为单位的持续时间,然后除以24。我看不出这个部门有多大帮助。
一般24小时一天中的毫秒数=( 24 * 60 * 60 * 1,000 )= 86400000。这是使用java.util.Date的代码返回的数字,如果除数为24。
long millis = ((new Date(2017, 11, 6).getTime()) - (new Date(2017, 11, 5).getTime())) ;
System.out.println( millis ); 86400000
看到那个在IdeOne.com现场运行的代码了。
LocalDate
LocalDate类表示一个日期纯值,没有一天的时间,也没有时区.
LocalDate ld = LocalDate.of( 2017 , Month.NOVEMBER , 5 ) ;时区
时区是确定日期的关键。在任何特定时刻,全球各地的日期因地区而异。例如,午夜后几分钟在法国巴黎是一个新的一天,而仍然“昨天”在魁北克省。以continent/region格式指定continent/region,如America/Montreal、Africa/Casablanca或Pacific/Auckland。不要使用3-4字母的缩写,如EST或IST,因为它们不是真正的时区,不标准化,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/New_York" ) ; ZonedDateTime
让java.time决定一天中的第一个时刻。不要以为一天从00:00开始。日照节约时间(DST)等异常意味着一天可能从01:00这样的时间开始。
ZonedDateTime start = ld.atStartOfDay( z ) ;通常,半开放方法是定义时间跨度的最佳方法。在这种方法中,开头是包容性的,而结尾是排他性的。因此,一整天被定义为从一天的第一分钟开始,一直持续到第二天的第一分钟,但不包括在内。
ZonedDateTime stop = ld.plusDays( 1 ).atStartOfDay( z ) ;计算那一天的长度,11月5日在纽约地区。
Duration d = Duration.between( start , stop ) ;PT25H
所以,是的,我们看到的一天是25个小时,因为DST切割。
来自Duration::toString的输出以标准ISO 8601格式表示。
关于java.time
java.time框架内置到Java8和更高版本中。这些类取代了麻烦的旧遗赠日期时间类,如java.util.Date、Calendar和SimpleDateFormat。
尤达-时间项目现在在维护模式中,建议迁移到java.time类。
要了解更多信息,请参见Oracle教程。并搜索堆栈溢出以获得许多示例和解释。规范是JSR 310。
在哪里获得java.time类?
三次-额外项目使用其他类扩展java.time。这个项目是将来可能加入java.time的试验场。您可以在这里找到一些有用的类,如Interval、YearWeek、YearQuarter和更多。
https://stackoverflow.com/questions/47472293
复制相似问题