如何使用Java中的DateFormat解析月份完整表单字符串?

tom*_*eng 50 java simpledateformat

我试过了

DateFormat fmt = new SimpleDateFormat("MMMM dd, yyyy");
Date d = fmt.parse("June 27, 2007");
Run Code Online (Sandbox Code Playgroud)

Exception in thread "main" java.text.ParseException: Unparseable date: "June 27, 2007"

java文档说我应该使用四个字符来匹配完整的表单.我只能使用像"Jun"这样的缩写月份成功使用MMM,但我需要匹配完整的表格.

文本:对于格式化,如果模式字母的数量为4或更多,则使用完整形式; 否则,如果可用,则使用简短或缩写形式.对于解析,两种形式都被接受,与模式字母的数量无关.

http://java.sun.com/j2se/1.6.0/docs/api/java/text/SimpleDateFormat.html

Mar*_*ers 118

您可能正在使用月份名称不是"1月","2月"等的区域设置,而是使用您当地语言的其他一些词语.

尝试指定您要使用的语言环境,例如Locale.US:

DateFormat fmt = new SimpleDateFormat("MMMM dd, yyyy", Locale.US);
Date d = fmt.parse("June 27,  2007");
Run Code Online (Sandbox Code Playgroud)

此外,日期字符串中有一个额外的空格,但实际上这对结果没有影响.无论哪种方式都可以.


Ole*_*.V. 13

来自 java.time 的 LocalDate

使用LocalDate现代 Java 日期和时间 API java.time 来获取日期

    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("MMMM d, u", Locale.ENGLISH);
    LocalDate date = LocalDate.parse("June 27, 2007", dateFormatter);
    System.out.println(date);
Run Code Online (Sandbox Code Playgroud)

输出:

2007-06-27

正如其他人已经说过的那样,当您的字符串是英语时,请记住指定英语区域设置。ALocalDate是没有时间的日期,因此比旧类更适合字符串中的日期Date。尽管它的名字aDate并不代表日期,而是代表世界不同时区至少两个不同日期的时间点。

仅当您需要一个老式的DateAPI 而您现在无法升级到 java.time 时,才可以像这样进行转换:

    Instant startOfDay = date.atStartOfDay(ZoneId.systemDefault()).toInstant();
    Date oldfashionedDate = Date.from(startOfDay);
    System.out.println(oldfashionedDate);
Run Code Online (Sandbox Code Playgroud)

我的时区的输出:

2007 年欧洲中部夏令时间 6 月 27 日星期三 00:00:00

关联

Oracle 教程:日期时间解释如何使用 java.time。


gke*_*rus 6

Just to top this up to the new Java 8 API:

DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern("MMMM dd, yyyy").toFormatter();
TemporalAccessor ta = formatter.parse("June 27, 2007");
Instant instant = LocalDate.from(ta).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
Date d = Date.from(instant);
assertThat(d.getYear(), is(107));
assertThat(d.getMonth(), is(5));
Run Code Online (Sandbox Code Playgroud)

A bit more verbose but you also see that the methods of Date used are deprecated ;-) Time to move on.

  • 感谢您展示推荐的现代方式(+1)。详细来说,“TemporalAccessor”接口被认为是低级的,不适合日常使用。最好直接解析为“LocalDate”,如我的答案中所示。此外,您没有解决问题背后的区域设置问题。 (2认同)