将不同时区的两个日期字符串与 Java 中的 SimpleDateFormat 进行比较

Compare two date strings in different time zones with SimpleDateFormat in Java

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

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);

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

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

false

详情

如评论所述,您的格式设置模式与您的数据不匹配。您最后没有使用正确的代码来表示与 UTC 的偏移量。那不是带有加号和减号的时间。

永远不要使用那些可怕的过时日期时间 类。他们多年前被现代 java.time 类.

所取代

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

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() ;

正如其他人指出的那样,避免使用被 java.time 类 取代的遗留日期时间 类(DateSimpleDateFormat) .

如果您仍想使用 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

是正确的推荐解决方案。您可以将此答案作为他的答案的补充。

java.time

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

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

现代日期时间 API 基于 ISO 8601 并且不需要明确使用 DateTimeFormatter 对象,只要日期时间字符串符合 ISO 8601 标准.您的两个日期时间字符串都符合带时区偏移的日期时间的 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 represents an instantaneous point on the timeline, normally represented in UTC time. The Z in the output is the timezone designator。它代表祖鲁语并指定 Etc/UTC 时区(时区偏移量为 +00:00 小时)。

Trail: Date Time.

了解有关现代日期时间 API 的更多信息

* 无论出于何种原因,如果您必须坚持Java 6 或Java 7,您可以使用ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and