使用 Java 中的 SimpleDateFormat 比较不​​同时区的两个日期字符串 正如其他人所指出的,避免使用被 Date 类取代的旧日期时间类(SimpleDateFormat 和 java.time)。如果您仍希望使用 Date 和 SimpleDateFormat,请继续阅读。

我有两个来自不同时区的日期:

String s1 = "2021-08-07T03:00:01-07:00";
String s2 = "2021-08-07T15:30:00+05:30";

我想比较两个日期。我正在解析如下日期:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss-hh:mm");
Date d = null;
try {
    d = sdf.parse(s1);
} catch (ParseException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
System.out.println(d);

如何使用字符串中提供的区域偏移量向日期添加时区?

kutianoo 回答:使用 Java 中的 SimpleDateFormat 比较不​​同时区的两个日期字符串 正如其他人所指出的,避免使用被 Date 类取代的旧日期时间类(SimpleDateFormat 和 java.time)。如果您仍希望使用 Date 和 SimpleDateFormat,请继续阅读。

tl;博士

OffsetDateTime
.parse( "2021-08-07T03:00:01-07:00" )
.isBefore(
    OffsetDateTime.parse( "2021-08-07T15:30:00+05:30" )
)

看到这个code run live at IdeOne.com

详情

正如所评论的,您的格式模式与您的数据不匹配。最后,您没有使用正确的 UTC 偏移代码。这不是带有加号和减号的一天中的时间。

永远不要使用那些糟糕的过时日期时间类。它们多年前被现代 java.time 类所取代。

默认情况下可以使用 OffsetDateTime 类解析您的 ISO 8601 标准输入。无需定义格式模式。

String s1="2021-08-07T03:00:01-07:00";
String s2="2021-08-07T15:30:00+05:30";
OffsetDateTime odt1 = OffsetDateTime.parse( s1 ) ;
OffsetDateTime odt2 = OffsetDateTime.parse( s2 ) ;
boolean odt1IsEarlier = odt1.isBefore( odt2 ) ;

看到这个code run live at IdeOne.com

您可以选择将两个对象调整为 UTC,偏移为零时分秒。只需提取一个 Instant

Instant i1 = odt1.toInstant() ;
Instant i2 = odt2.toInstant() ;
,

正如其他人所指出的,避免使用被 Date 类取代的旧日期时间类(SimpleDateFormatjava.time)。

如果您仍希望使用 DateSimpleDateFormat,请继续阅读。

尝试-

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public static void main(String[] args) {
    String inputDateString1 = "2021-08-07T03:00:01-07:00";
    String inputDateString2 = "2021-08-07T15:30:00+05:30";
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
    Date d1 = null,d2 = null;
    try {
        d1 = sdf.parse(inputDateString1);
        d2 = sdf.parse(inputDateString2);
        System.out.println("Date 1 = " + d1);
        System.out.println("Date 2 = " + d2);
        System.out.println("Date 1 - Date 2 in milliseconds = " + (d1.getTime() - d2.getTime()));
    } catch (ParseException e) {
        e.printStackTrace();
    }
}

以上代码片段的输出是:-

Date 1 = Sat Aug 07 15:30:01 IST 2021
Date 2 = Sat Aug 07 15:30:00 IST 2021
Date 1 - Date 2 in milliseconds = 1000
,

answer by Basil Bourque 是正确的,也是推荐的解决方案。你可以把这个回答作为他回答的补充。

java.time

java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用它们并切换到 modern Date-Time API*

使用 java.time(现代日期时间 API)的解决方案:

现代日期时间 API 基于 ISO 8601,只要日期时间字符串符合 ISO 8601 标准,就不需要明确使用 DateTimeFormatter 对象。您的两个日期时间字符串都符合带时区偏移的日期时间的 ISO 8601 格式,因此直接使用 OffsetDateTime 解析它们是非常有意义的。但是,从 Java SE 12 开始,您可以将它们直接解析为 Instant

演示:

import java.time.Instant;

public class Main {
    public static void main(String[] args) {
        String s1 = "2021-08-07T03:00:01-07:00";
        String s2 = "2021-08-07T15:30:00+05:30";

        Instant instant1 = Instant.parse(s1);
        Instant instant2 = Instant.parse(s2);

        System.out.println(s1 + " represents " + instant1);
        System.out.println(s1 + " represents " + instant2);

        if (instant1.isBefore(instant2)) {
            System.out.println(s1 + " is before " + s2);
        } else if (instant1.isAfter(instant2)) {
            System.out.println(s1 + " is after " + s2);
        } else {
            System.out.println("The strings represent the same instants.");
        }
    }
}

输出:

2021-08-07T03:00:01-07:00 represents 2021-08-07T10:00:01Z
2021-08-07T03:00:01-07:00 represents 2021-08-07T10:00:00Z
2021-08-07T03:00:01-07:00 is after 2021-08-07T15:30:00+05:30

ONLINE DEMO

Instant 表示时间线上的瞬时点,通常以 UTC 时间表示。输出中的 Z 是零时区偏移的 timezone designator。它代表祖鲁语并指定 Etc/UTC 时区(时区偏移为 +00:00 小时)。

Trail: Date Time 了解有关现代 Date-Time API 的更多信息。


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

本文链接:https://www.f2er.com/2893.html

大家都在问