【发布时间】:2019-09-17 17:50:50
【问题描述】:
我有 dd-mmm-yy 或 d-mmm-y 形式的文本格式的日期,其中月份是字母的缩写(例如,2009 年 11 月 4 日或 05 年 12 月 12 日等... ) 我想解析它以产生一个 java.util.Date 对象。
这可以通过利用 java.text.DateFormat 类来实现吗?或者有其他简单的方法吗?
【问题讨论】:
我有 dd-mmm-yy 或 d-mmm-y 形式的文本格式的日期,其中月份是字母的缩写(例如,2009 年 11 月 4 日或 05 年 12 月 12 日等... ) 我想解析它以产生一个 java.util.Date 对象。
这可以通过利用 java.text.DateFormat 类来实现吗?或者有其他简单的方法吗?
【问题讨论】:
您可能需要使用 SimpleDateFormat 来解析自定义格式。这个article 解释了格式化的细节。
"d-MMM-yyyy" corresponds to 4-Nov-2009
【讨论】:
parse方法。
SimpleDateFormat 是通常用于此的类。请注意,这个类不是线程安全的(有点违反直觉),如果您在线程上下文中使用它,那么研究Joda 及其DateTimeFormatter 是值得的。
【讨论】:
您可以使用java.text.SimpleDateFormat 完成此操作。点击链接,你会看到所有的模式。
对于 1-2 位数的日子,您可以使用 d 模式。对于 3 个字符的月份缩写,您可以使用 MMM 模式。对于 2 位数年份,您可以使用 yy 模式。
所以以下应该做:
String dateString = "4-Nov-09";
SimpleDateFormat sdf = new SimpleDateFormat("d-MMM-yy");
Date date = sdf.parse(dateString);
【讨论】:
无论您做什么,请使用区域设置。这样,当输入带有法语月份名称时,您仍然可以获得合理的结果。
【讨论】:
这是现代答案。问题中提到的DateFormat 类及其在大多数旧答案中使用的SimpleDateFormat 子类是出了名的麻烦且早已过时。不要使用其中任何一个。也不要使用Date,它的设计很糟糕,而且也已经过时了。
由于您有两位数的年份(在您的示例中为 09 和 05),因此您需要确定一个世纪。在第一轮中,我假设年份在 2000 年到 2099 年之间。
首先我们需要一个格式化程序:
static DateTimeFormatter dateFormatter
= DateTimeFormatter.ofPattern("d-MMM-uu", Locale.ENGLISH);
DateTimeFormatter 是线程安全的,所以我们很高兴有一个实例供所有人使用。 @shoover 是正确的,我们应该提供一个语言环境。像这样使用格式化程序:
String text = "4-Nov-09";
LocalDate date = LocalDate.parse(text, dateFormatter);
System.out.println("Date: " + date);
输出是:
日期:2009-11-04
为了验证,特别是对两位数年份的正确解释,我建议您添加范围检查。例如,要验证解析的日期不超过过去或未来 10 年:
LocalDate today = LocalDate.now(ZoneId.systemDefault());
if (date.isBefore(today.minusYears(10))
|| date.isAfter(today.plusYears(10))) {
System.err.println("This date can’t be right");
}
出于许多目的,您将提前知道日期是过去还是将来,并且可以比我的示例进一步缩小有效间隔。
如果年份可以超出 20xx 范围,我们通过DateTimeFormatterBuilder 及其appendValueReduced 方法控制年份的解释。请参阅以下链接列表中的相关答案之一。
【讨论】:
【讨论】:
你可以试试这个库dateparser。
它可以自动识别任何String,并将其解析为Date、Calendar、LocalDateTime、 >OffsetDateTime正确。
有了它,你不必准备任何合适的模式:
Date date = DateParserUtils.parseDate("12-Dec-05");
date 将是 Mon Dec 12 00:00:00 CST 2005
很酷吗?
【讨论】:
12-Dec-05 获得的是LocalDate(这是一个没有时间的日期)。这是不受支持的吗?有些人可能还期望从您的字符串中获得 2012 年 12 月 5 日,我对不指定我们想要的内容感到不舒服。
12-Dec-05和Dec, 12, 05差不多,不知道哪个用得更广。但是dateparser可以自定义,你可以很容易地改变它。关于LocalDate,可以使用LocalDateTime#toLocalDate获取。