Cal*_*ran 2 java datetime date dst
我正在尝试为列表中的对象创建时间限制。这可能意味着物品的保质期可能为 23、24 或 25 小时。有没有有用的 Java 库?这是我到目前为止所拥有的。
我的问题是,例如,当我在上午 9:30 创建记录时,必须在第二天上午 9:30 将其删除。当夏令时生效期间,我会遇到差异。该记录要么在 8:30 要么 10:30 被删除,具体取决于我是向前还是向后跳。
//baseValue = object that I want to check
Date dt = new Date();
Calendar c = Calendar.getInstance();
c.setTime(dt);
c.add(Calendar.DATE, -1);
if(baseValue.getTime() < c.getTime()){
array.remove(baseValue);
}
Run Code Online (Sandbox Code Playgroud)
小智 5
旧的类(Date、Calendar和SimpleDateFormat)有很多问题和设计问题,包括难以处理 DST 更改,并且它们正在被新的 API 取代。
如果您使用的是Java 8,请考虑使用新的 java.time API。与旧的 API 相比,它更简单、故障更少、更不容易出错。
\n\n如果您使用的是Java <= 7,则可以使用ThreeTen Backport,它是 Java 8 新日期/时间类的绝佳向后移植。对于Android,有 ThreeTenABP (更多关于如何使用它的信息请点击这里)。
\n\n下面的代码适用于两者。\n唯一的区别是包名称(在 Java 8 中是java.time,在 ThreeTen Backport(或 Android\'s ThreeTenABP)中是org.threeten.bp),但类和方法名称是相同的。
为了处理 DST 更改,理想的类是ZonedDateTime,它表示特定时区的日期和时间。我还使用ZoneId代表时区本身的类。
我正在使用我的时区 ( America/Sao_Paulo),因为这里也有 DST,但您可以用您的时区替换(更多内容如下):
// create a date 1 day before DST change in Sao Paulo, at 9 AM\nZoneId zone = ZoneId.of("America/Sao_Paulo");\nZonedDateTime z = ZonedDateTime.of(2017, 10, 14, 9, 0, 0, 0, zone);\n\n// get the next day, at 9 AM\nZonedDateTime nextDay = z.plusDays(1);\n\nSystem.out.println(z);\nSystem.out.println(nextDay);\nRun Code Online (Sandbox Code Playgroud)\n\n输出是:
\n\n\n\n\n2017-10-14T09:00-03:00[美国/圣保罗]
\n
\n 2017-10-15T09:00-02:00[美国/圣保罗]
请注意,偏移量从-03:00变为-02:00- 这是由于 DST 在 S\xc3\xa3o 保罗时区开始(时钟向前移动 1 小时)。但还要注意,时间(上午 9 点)已正确保存。
如果我们计算小时数的差异,我们可以看到它是正确的:
\n\nSystem.out.println(ChronoUnit.HOURS.between(z, nextDay));\nRun Code Online (Sandbox Code Playgroud)\n\n输出是:
\n\n\n\n\n23
\n
这正确地意味着这两个日期之间已经过去了 23 小时(由于时钟向前移动 1 小时,因此“丢失”了 1 小时)。
\n\n对于您的情况,您需要知道 1 天是否已经过去,因此您只需调用:
\n\nlong days = ChronoUnit.DAYS.between(z, nextDay);\nRun Code Online (Sandbox Code Playgroud)\n\n在这种情况下,days将为 1(即使上面计算的小时数差异为 23,因为 API 足够智能,可以考虑 DST 影响)。
因此,就您而言,您只需检查天数差异是否为 1(或大于 1,我不知道)并执行所有需要完成的操作。
\n\n如果您需要获取当前日期/时间,可以调用ZonedDateTime.now(zone).
要使用您的时区而不是我的时区,请首先注意 API 使用IANA 时区名称(始终采用 格式Continent/City,如America/Sao_Paulo或Europe/Berlin)。\n避免使用 3 个字母缩写(如CST或PST),因为它们不明确且不标准。
您可以使用 - 获取时区名称列表,ZoneId.getAvailableZoneIds()然后选择最适合您情况的一个。
您还可以使用ZoneId.systemDefault()- 它返回系统的默认时区。但这可能会在不通知的情况下更改 - 即使在运行时 - 因此建议使用显式时区。
| 归档时间: |
|
| 查看次数: |
1261 次 |
| 最近记录: |