将不同时区的两个日期字符串与 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
类 取代的遗留日期时间 类(Date
和 SimpleDateFormat
) .
如果您仍想使用 Date
和 SimpleDateFormat
,请继续阅读。
尝试-
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
零时区偏移的 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
小时)。
了解有关现代日期时间 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 。
我有两个来自不同时区的日期:
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
类 取代的遗留日期时间 类(Date
和 SimpleDateFormat
) .
如果您仍想使用 Date
和 SimpleDateFormat
,请继续阅读。
尝试-
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
零时区偏移的 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
小时)。
* 无论出于何种原因,如果您必须坚持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