当前位置: 首页 > 面试题库 >

当输入日期处于从PDT到PST的过渡期时,如何处理日期?

廉志强
2023-03-14
问题内容

我正在调用一个以两个日期为输入的API.API检查两个日期之间的差是否大于60分钟,然后引发异常。我的输入日期是startDate =
11-06-2016T00:57:01和endDate =
11-06-2016T01:56:01。这两个日期保存在java.util.Datehtml" target="_blank">对象中。现在的问题是,尽管两个日期相差59分钟(不到60分钟),但API仍会引发异常。类似的问题是由于DayLightSaving.11月6日,一旦凌晨2点,DayLightSaving结束(PDT时区结束),时间会向后移动1小时,因此时间现在又变为凌晨1点,但现在是PST时区。这意味着在11月6日,太平洋夏令时间将是凌晨1-2点,两次是PDT,一次是PST时区。在11月7日调用此API时,时区为PST。因此,如果在未指定时区的情况下传递了两个日期,由于PDT和PST本身相差1小时,因此这会相差59分钟,并且会引发异常。当输入日期处于从PDT到PST的过渡期时,该如何处理?

样例代码

SimpleDateFormat formatter1 = new SimpleDateFormat("MM-dd-yyyy hh:mm:ss");
String start="11-06-2016 00:57:01";
String end ="11-06-2016 01:56:01";
Date startdate = formatter1.parse(start);
Date enddate = formatter1.parse(end);
System.out.println("startDate is :"  + startdate);
System.out.println("endDate is :"  +enddate);
long dateRange = enddate.getTime() - startdate.getTime();
//if the difference between the two dates is > than 60 min i.e  3600000 ms, then throw exception.
System.out.println(dateRange);
if (dateRange > (60 * 60 * 1000)){
    throw new Exception("Date time range cannot be greater than 60 minutes.(calculated using millisecond difference)");
}

输出量

[Date Range is = 7140000
Exception in thread "main" java.lang.Exception: Date time range cannot be greater than 60 minutes.(calculated using millisecond difference).
    at Datetest.main(Datetest.java:28)][1]

在PST时区调用时,以上代码段引发异常。


问题答案:

SimpleDateFormat底层也没有Calendar指定在夏令时与标准时间之间重叠的时间内解析没有时区的datetime字符串时会发生什么。

您已经观察到它将返回较晚的时间,即与夏时制相比,它似乎更喜欢标准时间。但是,行为是不确定的,所以…

java.time但是,新类确实指定发生了什么,以及如何选择重叠的另一个“小时”。

在新的API中,由于您的datetime字符串没有时区,因此您可能首先使用进行解析LocalDateTime,然后应用时区来获取ZonedDateTime,例如

LocalDateTime ldtEnd = LocalDateTime.parse("2016-11-06T01:56:01");
ZonedDateTime zdtEnd = ldtEnd.atZone(ZoneId.of("America/Los_Angeles"));
// zdtEnd is now: 2016-11-06T01:56:01-07:00[America/Los_Angeles]

要查看重叠部分,您可以尝试添加一个小时:

ZonedDateTime zdtEnd2 = zdtEnd.plusHours(1);
// zdtEnd2 is now: 2016-11-06T01:56:01-08:00[America/Los_Angeles]

行为是明确定义的,请参见atZone()

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

在间隙中,时钟向前跳,则没有有效的偏移量。取而代之的是,将本地日期时间调整为晚一些间隔时间。对于典型的一小时夏令时更改,本地日期时间将在一小时后移入通常对应于“夏季”的偏移量中。

若要获得 重叠期间 的更高偏移量
请调用ZonedDateTime.withLaterOffsetAtOverlap()此方法的结果。要在存在间隙或重叠时引发异常,请使用ZonedDateTime.ofStrict(LocalDateTime, ZoneOffset, ZoneId)

如您所见,它将始终以重叠的形式返回 较早的 时间,这与观察到的行为相反SimpleDateFormat。如果您希望 以后的
时间重叠,请致电withLaterOffsetAtOverlap()

如果您不想依赖已记录的默认值,则可以始终明确:

ZoneId PT = ZoneId.of("America/Los_Angeles");

LocalDateTime ldtStart = LocalDateTime.parse("2016-11-06T00:57:01");
ZonedDateTime zdtStartEarly = ldtStart.atZone(PT).withEarlierOffsetAtOverlap();
ZonedDateTime zdtStartLater = ldtStart.atZone(PT).withLaterOffsetAtOverlap();
System.out.println(zdtStartEarly); // 2016-11-06T00:57:01-07:00[America/Los_Angeles]
System.out.println(zdtStartLater); // 2016-11-06T00:57:01-07:00[America/Los_Angeles]

LocalDateTime ldtEnd = LocalDateTime.parse("2016-11-06T01:56:01");
ZonedDateTime zdtEndEarly = ldtEnd.atZone(PT).withEarlierOffsetAtOverlap();
ZonedDateTime zdtEndLater = ldtEnd.atZone(PT).withLaterOffsetAtOverlap();
System.out.println(zdtEndEarly); // 2016-11-06T01:56:01-07:00[America/Los_Angeles]
System.out.println(zdtEndLater); // 2016-11-06T01:56:01-08:00[America/Los_Angeles]

如您所见,对于00:57时间而言,这没有什么区别,因为该时间不在重叠时间内。



 类似资料:
  • 主要内容:1 局部处理日期,2 全局处理日期Fastjson默认情况下对日期格式是没有做格式化处理的,默认输出日期的毫秒数。如下: 运行结果为: 如果希望对日期进行格式化输出,可以使用以下方式进行。 1 局部处理日期 局部处理日期,是指可以把toJSONString() 方法换成toJSONStringWithDateFormat() 方法 1.1 编写测试类 MainApp: 1.2 运行结果 2 全局处理日期 全局处理日期,是指统一对需

  • 使用 Servlet 的最重要的优势之一是,可以使用核心 Java 中的大多数可用的方法。本章将讲解 Java 提供的 java.util 包中的 Date 类,这个类封装了当前的日期和时间。 Date 类支持两个构造函数。第一个构造函数初始化当前日期和时间的对象。 Date( ) 下面的构造函数接受一个参数,该参数等于 1970 年 1 月 1 日午夜以来经过的毫秒数。 Date(long

  • 使用JSP最重要的优势之一,就是可以使用所有Java  API。本章将会详细地讲述Java中的Date类,它在java.util包下,封装了当前日期和时间。 Date类有两个构造函数。第一个构造函数使用当前日期和时间来初始化对象。 Date( ) 第二个构造函数接受一个参数,这个参数表示从1970年1月1日凌晨至所要表示时间的毫秒数。 Date(long millisec) 获取Date对

  • 主要内容:日期,时间,日期格式化:年-月-日DOS脚本中的日期和时间具有以下两个用于检索系统日期和时间的基本命令。 日期 该命令获取系统日期。 语法 示例 当前日期将显示在命令提示符下。 例如, 时间 该命令设置或显示时间。 语法 示例 当前时间将显示在命令提示符下。 例如, 以下是一些可用于以不同格式获取日期和时间的实现。 日期格式化:年-月-日 示例 以上命令产生以下输出 -

  • 主要内容:Date 类,Calendar 类在 Java 中获取当前时间,可以使用 java.util.Date 类和 java.util.Calendar 类完成。其中, Date 类主要封装了系统的日期和时间的信息,Calendar 类则会根据系统的日历来解释 Date 对象。下面详细介绍这两个类的具体使用。 Date 类 Date 类表示系统特定的时间戳,可以精确到毫秒。Date 对象表示时间的默认顺序是星期、月、日、小时、分、秒、年

  • 使用DateTime 类。 在 PHP 糟糕的老时光里,我们必须使用 date(), gmdate(), date_timezone_set(), strtotime()等等令人迷惑的 组合来处理日期和时间。悲哀的是现在你仍旧会找到很多在线教程在讲述这些不易使用的老式函数。 幸运的是,我们正在讨论的 PHP 版本包含友好得多的 DateTime 类。 该类封装了老式日期函数所有功能,甚至更多,在一