要将 a 转换String
为 a Date
,您应该使用该parse
方法。但是您使用的format
是相反的方法(它将 a 转换Date
为 a String
)。
要检查 2 是否String
对应于同一日期,您必须使用 aSimpleDateFormat
来解析它们。但是有两个细节要记住:
请注意,一周中的月份和日期是英文的,因此您应该使用 ajava.util.Locale
来指示您要使用的语言。如果不指定,则使用系统默认,不保证始终为英文。
即使是这样,即使在运行时,也可以在不通知的情况下更改此配置,因此最好明确使用特定配置。
第一个有时String
区信息:CDT
- 我假设它是美国的中央夏令时间(尽管它也可能是古巴夏令时)。但是第二个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
该类无法识别它并且它给出了不正确的结果。
最好使用IANA 时区名称(始终采用格式Region/City
,例如America/Chicago
或Europe/London
)。避免使用 3 个字母的缩写(如CDT
or PST
),因为它们模棱两可且不标准。
使用 CDT 的时区不止一个,因此您必须选择最适合您系统的时区。您可以通过调用获取可用时区列表TimeZone.getAvailableIDs()
。
Java 新的日期/时间 API
旧的类(Date
和Calendar
)SimpleDateFormat
有很多问题和设计问题,它们正在被新的 API 取代。
如果您使用的是Java 8,请考虑使用新的 java.time API。与旧的 API 相比,它更容易、错误更少且不易出错。
如果您使用的是Java <= 7,则可以使用ThreeTen Backport,这是 Java 8 的新日期/时间类的一个很好的向后端口。对于Android,还有ThreeTenABP(更多关于如何使用它的信息)。
下面的代码适用于两者。唯一的区别是包名(在 Java 8 中是java.time
,在 ThreeTen Backport(或 Android 的 ThreeTenABP)中是org.threeten.bp
),但类和方法名是相同的。
当您只比较日期(日/月/年)时,最好只使用这些字段并忽略其余字段(小时/分钟/秒和时区信息)。为此,您可以使用 aLocalDate
和 a 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
只有日、小时和分钟(没有小时/分钟/秒,也没有时区信息),您不需要关心在格式化程序中设置时区 - 尽管对英语语言环境的关注仍然存在。
结果也会true
。