php一天25小时

时间:2017-11-24 11:24:45

标签: php datetime

我在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小时,我应该通过特殊方法处理这个日期?

1 个答案:

答案 0 :(得分:1)

虽然我不能对你的问题的PHP部分说话,但我可以更正你的Java代码。

TL;博士

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小时通用24小时制(UTC),而实际2017-11-05 America/New_York则为25小时而不是24小时。

Java的示例代码对我来说毫无意义,因为您正在计算持续时间(以毫秒为单位)然后除以24.我不知道该除法如何帮助。

一般24小时工作日内的毫秒数=(24 * 60 * 60 * 1,000)= 86400000.如果我们将除法除以24,则使用java.util.Date代码返回的数字。

long millis = ((new Date(2017, 11, 6).getTime()) - (new Date(2017, 11, 5).getTime())) ;
System.out.println( millis ); 
  

86400000

code run live at IdeOne.com

LocalDate

LocalDate类表示没有时间且没有时区的仅限日期的值。

LocalDate ld = LocalDate.of( 2017 , Month.NOVEMBER , 5 ) ;

时区

时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因地区而异。例如,Paris France午夜后的几分钟是Montréal Québec中仍然是“昨天”的新一天。 以continent/region格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用诸如ESTIST之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

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

所以,是的,我们看到由于DST切换而导致一天长达25小时。

请参阅此code run live at IdeOne.com

Duration::toString的输出位于standard ISO 8601 format

关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore