关于如何以字符串格式比较 2 个日期的任何想法?
Any ideas on how I could compare 2 dates in string format?
关于如何以字符串格式比较 2 个日期的任何想法:
String1 = "Wed May 18 00:00:00 CDT 2011"
String2= "May. 18, 2011"
我尝试将 String1
转换为 String2
的日期格式,但不是很成功。
我尝试使用模式 "EEE mmm dd HH:mm:ss z yyyy"
将 String1
转换为日期
public String formatDateTime(Date date, String pattern) {
SimpleDateFormat formatter = new SimpleDateFormat(pattern);
String dateString = formatter.format(date);
return dateString;
}
此解决方案可行,但是,您需要注意计算机 运行 所在的时区。如果第二个日期是在美国东部时间生成的,则第二个日期没有时区会导致问题。
String d1 = "Wed May 18 00:00:00 CDT 2011";
String d2 = "May. 18, 2011";
SimpleDateFormat d1Formatter = new SimpleDateFormat("E MMMM dd HH:mm:ss z yyyy");
SimpleDateFormat d2Formatter = new SimpleDateFormat("MMMM. dd, yyyy");
Date date1 = d1Formatter.parse(d1);
Date date2 = d2Formatter.parse(d2);
date1.equals(date2);
请注意,我使用的所有模式都来自 documentation。我建议创建一个单元测试并测试不同组合的作用。
@Test
public void test_date_experimentation() {
SimpleDateFormat d1Formatter = new SimpleDateFormat("E MMMM dd HH:mm:ss z yyyy");
// Print the current time in the specified format.
System.out.println(d1Formatter.format(Date.from(Instant.now())));
}
要将 String
转换为 Date
,您应该使用 parse
方法。但是您使用的是 format
方法,它的作用恰恰相反(它将 Date
转换为 String
)。
要检查 2 个 String
是否对应于同一日期,您必须为每个 SimpleDateFormat
解析它们。但有两个细节需要牢记:
请注意,月份和星期几是英文的,因此您应该使用 java.util.Locale
来指明您要使用的语言。如果您不指定,它将使用系统默认值,并且不保证始终为英文。
即使是这样,此配置也可以在不通知的情况下更改,即使在运行时也是如此,因此最好明确使用特定的配置。
第一个 String
有时区信息:CDT
- 我假设它是美国的 中部夏令时 (尽管it could also be Cuba Daylight Time)。但是第二个 String
没有任何时区信息,所以我假设它与第一个 String
.
处于同一时区
如果我不指定它,将使用系统的默认值,如果不是 CDT,它可能会给你不同的结果。与发生在语言环境中的情况类似,即使在运行时也可以更改默认设置,恕不另行通知,因此最好指定您使用的是哪一个。
String s1 = "Wed May 18 00:00:00 CDT 2011";
String s2 = "May. 18, 2011";
// use English locale for month and day of week
SimpleDateFormat sdf1 = new SimpleDateFormat("E MMMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
SimpleDateFormat sdf2 = new SimpleDateFormat("MMMM. dd, yyyy", Locale.ENGLISH);
// set timezone, because String 2 has no timezone information
sdf2.setTimeZone(TimeZone.getTimeZone("America/Chicago"));
// parse the dates
Date date1 = sdf1.parse(s1);
Date date2 = sdf2.parse(s2);
// compare them
boolean areDatesEqual = date1.equals(date2);
变量 areDatesEqual
的值将是 true
(日期相同)。
请注意,我使用 America/Chicago
作为时区名称。如果我使用 CDT
,TimeZone
class 无法识别它并给出不正确的结果。
最好使用 IANA timezones names(格式总是 Region/City
,如 America/Chicago
或 Europe/London
)。
避免使用 3 个字母的缩写(如 CDT
或 PST
),因为它们是 ambiguous and not standard.
有more than one timezone that uses CDT,所以您必须选择最适合您系统的那个。
您可以通过调用 TimeZone.getAvailableIDs()
.
获取可用时区的列表
Java新Date/TimeAPI
旧的 classes(Date
、Calendar
和 SimpleDateFormat
)有 lots of problems and design issues,它们正在被新的 APIs.
如果您使用 Java 8,请考虑使用 new java.time API. It's easier, less bugged and less error-prone than the old APIs.
如果您使用 Java <= 7,您可以使用 ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, there's the ThreeTenABP (more on how to use it ).
下面的代码适用于两者。
唯一的区别是包名称(在 Java 8 中是 java.time
,在 ThreeTen Backport(或 Android 的 ThreeTenABP)中是 org.threeten.bp
),但是 classes和方法名称是一样的。
由于您只比较日期 (day/month/year),因此最好只使用这些字段而忽略其余字段(hour/minute/second 和时区信息)。为此,您可以使用 LocalDate
和 DateTimeFormatter
:
String s1 = "Wed May 18 00:00:00 CDT 2011";
String s2 = "May. 18, 2011";
// use English locale for month and day of week
DateTimeFormatter fmt1 = DateTimeFormatter.ofPattern("E MMMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
DateTimeFormatter fmt2 = DateTimeFormatter.ofPattern("MMMM. dd, yyyy", Locale.ENGLISH);
// parse the strings
LocalDate d1 = LocalDate.parse(s1, fmt1);
LocalDate d2 = LocalDate.parse(s2, fmt2);
// compare the dates
boolean areDatesEqual = d1.equals(d2);
因为 LocalDate
只有天、小时和分钟(没有 hours/minutes/seconds 也没有时区信息),你不需要关心在格式化程序中设置时区——尽管关心保留英语语言环境。
结果也将是true
。
关于如何以字符串格式比较 2 个日期的任何想法:
String1 = "Wed May 18 00:00:00 CDT 2011"
String2= "May. 18, 2011"
我尝试将 String1
转换为 String2
的日期格式,但不是很成功。
我尝试使用模式 "EEE mmm dd HH:mm:ss z yyyy"
String1
转换为日期
public String formatDateTime(Date date, String pattern) {
SimpleDateFormat formatter = new SimpleDateFormat(pattern);
String dateString = formatter.format(date);
return dateString;
}
此解决方案可行,但是,您需要注意计算机 运行 所在的时区。如果第二个日期是在美国东部时间生成的,则第二个日期没有时区会导致问题。
String d1 = "Wed May 18 00:00:00 CDT 2011";
String d2 = "May. 18, 2011";
SimpleDateFormat d1Formatter = new SimpleDateFormat("E MMMM dd HH:mm:ss z yyyy");
SimpleDateFormat d2Formatter = new SimpleDateFormat("MMMM. dd, yyyy");
Date date1 = d1Formatter.parse(d1);
Date date2 = d2Formatter.parse(d2);
date1.equals(date2);
请注意,我使用的所有模式都来自 documentation。我建议创建一个单元测试并测试不同组合的作用。
@Test
public void test_date_experimentation() {
SimpleDateFormat d1Formatter = new SimpleDateFormat("E MMMM dd HH:mm:ss z yyyy");
// Print the current time in the specified format.
System.out.println(d1Formatter.format(Date.from(Instant.now())));
}
要将 String
转换为 Date
,您应该使用 parse
方法。但是您使用的是 format
方法,它的作用恰恰相反(它将 Date
转换为 String
)。
要检查 2 个 String
是否对应于同一日期,您必须为每个 SimpleDateFormat
解析它们。但有两个细节需要牢记:
请注意,月份和星期几是英文的,因此您应该使用
java.util.Locale
来指明您要使用的语言。如果您不指定,它将使用系统默认值,并且不保证始终为英文。即使是这样,此配置也可以在不通知的情况下更改,即使在运行时也是如此,因此最好明确使用特定的配置。
第一个
处于同一时区String
有时区信息:CDT
- 我假设它是美国的 中部夏令时 (尽管it could also be Cuba Daylight Time)。但是第二个String
没有任何时区信息,所以我假设它与第一个String
.如果我不指定它,将使用系统的默认值,如果不是 CDT,它可能会给你不同的结果。与发生在语言环境中的情况类似,即使在运行时也可以更改默认设置,恕不另行通知,因此最好指定您使用的是哪一个。
String s1 = "Wed May 18 00:00:00 CDT 2011";
String s2 = "May. 18, 2011";
// use English locale for month and day of week
SimpleDateFormat sdf1 = new SimpleDateFormat("E MMMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
SimpleDateFormat sdf2 = new SimpleDateFormat("MMMM. dd, yyyy", Locale.ENGLISH);
// set timezone, because String 2 has no timezone information
sdf2.setTimeZone(TimeZone.getTimeZone("America/Chicago"));
// parse the dates
Date date1 = sdf1.parse(s1);
Date date2 = sdf2.parse(s2);
// compare them
boolean areDatesEqual = date1.equals(date2);
变量 areDatesEqual
的值将是 true
(日期相同)。
请注意,我使用 America/Chicago
作为时区名称。如果我使用 CDT
,TimeZone
class 无法识别它并给出不正确的结果。
最好使用 IANA timezones names(格式总是 Region/City
,如 America/Chicago
或 Europe/London
)。
避免使用 3 个字母的缩写(如 CDT
或 PST
),因为它们是 ambiguous and not standard.
有more than one timezone that uses CDT,所以您必须选择最适合您系统的那个。
您可以通过调用 TimeZone.getAvailableIDs()
.
Java新Date/TimeAPI
旧的 classes(Date
、Calendar
和 SimpleDateFormat
)有 lots of problems and design issues,它们正在被新的 APIs.
如果您使用 Java 8,请考虑使用 new java.time API. It's easier, less bugged and less error-prone than the old APIs.
如果您使用 Java <= 7,您可以使用 ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, there's the ThreeTenABP (more on how to use it
下面的代码适用于两者。
唯一的区别是包名称(在 Java 8 中是 java.time
,在 ThreeTen Backport(或 Android 的 ThreeTenABP)中是 org.threeten.bp
),但是 classes和方法名称是一样的。
由于您只比较日期 (day/month/year),因此最好只使用这些字段而忽略其余字段(hour/minute/second 和时区信息)。为此,您可以使用 LocalDate
和 DateTimeFormatter
:
String s1 = "Wed May 18 00:00:00 CDT 2011";
String s2 = "May. 18, 2011";
// use English locale for month and day of week
DateTimeFormatter fmt1 = DateTimeFormatter.ofPattern("E MMMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
DateTimeFormatter fmt2 = DateTimeFormatter.ofPattern("MMMM. dd, yyyy", Locale.ENGLISH);
// parse the strings
LocalDate d1 = LocalDate.parse(s1, fmt1);
LocalDate d2 = LocalDate.parse(s2, fmt2);
// compare the dates
boolean areDatesEqual = d1.equals(d2);
因为 LocalDate
只有天、小时和分钟(没有 hours/minutes/seconds 也没有时区信息),你不需要关心在格式化程序中设置时区——尽管关心保留英语语言环境。
结果也将是true
。