gpt4 book ai didi

java - 比较不同时区的两个日期对象并获取精确的时间差(以秒为单位)

转载 作者:行者123 更新时间:2023-12-03 00:57:11 25 4
gpt4 key购买 nike

我正在尝试将电子邮件(日期对象)的接收日期与 JSONObject 中的日期(字符串)进行比较。这两个日期将属于不同时区,相差 1 小时。

我的情况是,我必须在几秒钟内获得它们之间的确切差异,如果差异为 +/- 10 秒,我就会找到匹配项。为此,我决定将两者都转换为“UTC”,然后进行区别。这是我的代码:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));

String MsgDtStr = sdf.format(messagesToBeProcessed.getReceivedDate());

Date MsgDt = sdf.parse(MsgDtStr);

Date ObjDt = sdf.parse((JsonObj.get("date").toString()));

int DiffInSecs = (int) (ObjDt.getTime() - MsgDt.getTime()) / 1000 % 60;

if (DiffInSecs >= -10 && DiffInSecs <= 10) {
System.out.println("Found a match!");
MatchedList.add(i);
}

这似乎给了我正确的结果。应该与 json 对象匹配的邮件匹配。即差异为 +/- 10 秒。但是,当我尝试在上述逻辑之后打印日期和 DiffInSecs 时,我得到如下值:

date in object: 2017-06-22 19:47:25
date in message: 2017-06-22 23:47:30
DiffInSecs: -5

........

date in object: 2017-06-22 17:50:38
date in message: 2017-06-22 21:50:39
DiffInSecs: -1

我发现两个时间相差 4 小时。现在我很困惑我的逻辑是如何运作的。对此有何解释?我解决问题的方法是否正确?

这些是我应该使用的邮件和 jsonobject 的示例日期值,它们应该匹配:(我如何以任何方式实现这一点,而不仅仅是我发布的方法)

messagesToBeProcessed[i].getReceivedDate():2017 年 6 月 22 日星期四 01:03:13 CDT
messagesToBeProcessed[i].getReceivedDate().getTime(): 1498111393000

Obj.get('日期'): 2017-06-22 02:03:03
ObjDt.getTime(): 1498096983000

编辑:

正如 JBNizet 在评论中所指出的,我需要删除 %60 才能获得以秒为单位的精确差异。

好吧,现在我觉得坚持旧的 API 没有意义。现在,我在消息对象中的日期不再像我在上面的结果中发布的那样转换为 UTC。我不确定为什么它以前有效但现在不再有效(欢迎对此进行任何解释/评论)。正如 Hugo 在他的回答中指出的,使用新的 Java.Time API 更好。

希望这个帖子可以帮助人们在未来找到出路。

最佳答案

我不确定您使用的是哪个 Java 版本,但无论如何:旧类(DateCalendarSimpleDateFormat)有lots of problemsdesign issues ,并且它们正在被新的日期/时间 API 取代。

如果您使用的是 Java 8,请考虑使用 new java.time API 。更容易,less bugged and less error-prone than the old APIs .

如果您使用的是 Java <= 7,则可以使用 ThreeTen Backport ,Java 8 新日期/时间类的一个很好的向后移植。对于 Android,有 ThreeTenABP (更多关于如何使用它 here )。

下面的代码适用于两者。唯一的区别是包名称(在 Java 8 中是 java.time,在 ThreeTen Backport(或 Android 的 ThreeTenABP)中是 org. Threeten.bp),但是类和方法名称相同。

<小时/>

根据 getReceivedDate() 的输出,您的默认时区是 CDT。但是这些短时区名称(例如 ESTCDT)是 ambiguous and not standard .

新 API 使用 Continent/City 格式的长名称(由 IANA database 使用。因此,CDT 可以位于许多不同的位置,例如美国/芝加哥美国/哈瓦那。您必须首先检查哪一个最适合您的上下文 - 您可以使用 ZoneId.getAvailableZoneIds() 获取所有可用名称的列表。

对于下面的示例,我随机选择了其中一个(美国/芝加哥),只是为了展示它是如何工作的。我使用 DateTimeFormatter 来解析输入 String 并使用 ZoneId 将其转换为时区。

// parse jsonInput
String jsonInput = "2017-06-22 02:03:03";
// formatter
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// parse the input to a LocalDateTime
LocalDateTime dt = LocalDateTime.parse(jsonInput, fmt); // 2017-06-22T02:03:03
// convert it to the EDT timezone (using America/Chicago as it's currently in CDT)
ZonedDateTime z = dt.atZone(ZoneId.of("America/Chicago")); // 2017-06-22T02:03:03-05:00[America/Chicago]

// convert the java.util.Date object to the new API
Date date = new Date(1498111393000L); // using your timestamp = 2017-06-22T06:03:13 UTC
// for Java >= 8, use toInstant method
Instant instant = date.toInstant();
// for Java <= 7, use org.threeten.bp.DateTimeUtils
Instant instant = DateTimeUtils.toInstant(date);

// get the difference between them
long diffSecs = ChronoUnit.SECONDS.between(instant, z);

差异将为 3590 秒 - 这是因为 CDT(在我的示例中为芝加哥)中的 2017-06-22 02:03:03 等于 UTC 2017-06-22T07:03:03Z。您的日期(1498111393000 毫秒)等于 UTC 2017-06-22T06:03:13Z

在您的代码中,您使用 sdf 解析输入 2017-06-22 02:03:03,但是 sdf设置为 UTC(而不是 CDT),导致结果不正确(假设 JSON 输入也在 CDT 中)。

<小时/>

如果要将 JSON 输入转换为 UTC,可以使用 ZoneOffset.UTC 而不是 ZoneId

实际上,您必须检查输入是否确实是 UTC 格式,并相应地更改代码(上面的代码假设 JSON 输入是 CDT 格式)。

<小时/>

当然,您可以使用 SimpleDateFormat 执行相同的操作:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("America/Chicago"));

Date jsonDate = sdf.parse("2017-06-22 02:03:03"); // 2017-06-22 02:03:03 in Chicago, or 2017-06-22T07:03:03 in UTC

然后以与您相同的方式计算差异 ((jsonDate.getTime() - date.getTime())/1000)。结果将与上面相同:3590 秒。

关于java - 比较不同时区的两个日期对象并获取精确的时间差(以秒为单位),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44722209/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com