我只是想在Java 8中将日期字符串转换为DateTime对象。运行以下几行代码:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDateTime dt = LocalDateTime.parse("20140218", formatter);

我得到以下错误:

Exception in thread "main" java.time.format.DateTimeParseException: 
Text '20140218' could not be parsed: 
Unable to obtain LocalDateTime from TemporalAccessor: 
{},ISO resolved to 2014-02-18 of type java.time.format.Parsed
    at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1918)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1853)
    at java.time.LocalDateTime.parse(LocalDateTime.java:492)

语法与这里建议的完全相同,但是我遇到了一个异常。我使用的是JDK-8u25。


事实证明,Java不接受裸Date值作为DateTime。使用LocalDate而不是LocalDateTime解决了这个问题:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate dt = LocalDate.parse("20140218", formatter);

这是一个非常不清楚且毫无帮助的错误消息。经过多次尝试和错误后,我发现如果您不尝试解析时间,LocalDateTime将给出上述错误。通过使用LocalDate,它可以正常工作而不会出错。

这没有很好的记录,相关的异常也没有什么帮助。


如果你真的需要将日期转换为LocalDateTime对象,你可以使用LocalDate.atStartOfDay()。这将给你一个指定日期的LocalDateTime对象,将小时、分钟和秒字段设置为0:

final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDateTime time = LocalDate.parse("20140218", formatter).atStartOfDay();

对于值得的是,如果有人应该再次阅读这个主题(像我一样),正确的答案将在DateTimeFormatter定义中,例如:

private static DateTimeFormatter DATE_FORMAT =  
            new DateTimeFormatterBuilder().appendPattern("dd/MM/yyyy[ [HH][:mm][:ss][.SSS]]")
            .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
            .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
            .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
            .toFormatter(); 

如果将出现可选字段,则应该设置可选字段。其余的代码应该完全相同。

编辑:有用的东西从wittyameta评论:

记住在调用appendPattern之后添加parsedefaults。否则它会给出DateTimeParseException


扩展retrography的答案..:我有同样的问题,即使使用LocalDate而不是LocalDateTime。问题是,我已经创建了我的DateTimeFormatter使用. withresolverstyle (ResolverStyle.STRICT);,所以我必须使用日期模式uuuuMMdd而不是yyyyMMdd(即。“year”而不是“year-of-era”)!

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
  .parseStrict()
  .appendPattern("uuuuMMdd")
  .toFormatter()
  .withResolverStyle(ResolverStyle.STRICT);
LocalDate dt = LocalDate.parse("20140218", formatter);

(这个解决方案最初是对retrography的答案的评论,但我被鼓励将其作为一个独立的答案发布,因为它显然对许多人都很有效。)


如果日期字符串不包括任何小时、分钟等值,则不能直接将其转换为LocalDateTime。您只能将其转换为LocalDate,因为字符串只表示年、月和日期组件,这将是正确的做法。

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate ld = LocalDate.parse("20180306", dtf); // 2018-03-06

无论如何,你可以将它转换为LocalDateTime。

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate ld = LocalDate.parse("20180306", dtf);
LocalDateTime ldt = LocalDateTime.of(ld, LocalTime.of(0,0)); // 2018-03-06T00:00

对于那些像我一样犯了这个错误的人:

无法从TemporalAccessor获取LocalDateTime: {HourOfAmPm=0, MinuteOfHour=0}

它来自于下面这句话:

LocalDateTime.parse(date, DateTimeFormatter.ofPattern("M/d/yy h:mm"));

事实证明,这是因为我在0小时上使用了12小时的模式,而不是24小时的模式。

通过使用大写H将小时改为24小时模式可以修复它:

LocalDateTime.parse(date, DateTimeFormatter.ofPattern("M/d/yy H:mm"));

试试这个:

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MM-dd-yyyy"); 
LocalDate fromLocalDate = LocalDate.parse(fromdstrong textate, dateTimeFormatter);

你可以添加任何你想要的格式。这对我很有用!


这很好

public class DateDemo {
    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy hh:mm");
        String date = "16-08-2018 12:10";
        LocalDate localDate = LocalDate.parse(date, formatter);
        System.out.println("VALUE="+localDate);

        DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
        LocalDateTime parse = LocalDateTime.parse(date, formatter1);
        System.out.println("VALUE1="+parse);
    }
}

输出:

VALUE=2018-08-16
VALUE1=2018-08-16T12:10

我遇到这个问题是因为我的输入字符串中没有年份:

输入字符串:周二,6月8日10:00 PM 格式化程序:DateTimeFormatter。ofPattern("EEEE, mm d 'at' h:mm a", Locale.US);

我知道年份,所以我只是把它附加到:

输入字符串:2021年6月8日星期二下午6:30 格式化程序:DateTimeFormatter。ofPattern("EEEE, mm d 'at' h:mm a uuuu", Locale.US);


 DateTimeFormatter format = new DateTimeFormatterBuilder()
                            .appendPattern("yyyy-MM-dd")
                            .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
                            .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
                            .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
                            .parseDefaulting(ChronoField.MILLI_OF_SECOND, 0)
                            .toFormatter();

对我有用


如果您只是想采用一种格式(无论它是否有时间),并希望解析为LocalDateTime,您可以执行以下操作。

LocalDateTime parseDateTime(String dateTime, DateTimeFormatter fmt) {
  return fmt.parse(dateTime, t -> {
    LocalDate date = t.query(TemporalQueries.localDate());
    LocalTime time = t.query(TemporalQueries.localTime());
    return LocalDateTime.of(date, time != null ? time : LocalTime.MIDNIGHT);
  });
}

我需要这个,因为我要将日期/时间模式作为自定义Spark UDF的参数。


您不需要定义DateTimeFormatter

您不需要定义DateTimeFormatter来解析给定的日期字符串。您可以使用OOTB(开箱即用)、DateTimeFormatter。BASIC_ISO_DATE解析它。

演示:

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        LocalDate date = LocalDate.parse("20140218", DateTimeFormatter.BASIC_ISO_DATE);
        System.out.println(date);

        // In case you need an instance of LocalDateTime
        LocalDateTime ldt = date.atTime(LocalTime.MIN);
        System.out.println(ldt);
    }
}

输出:

2014-02-18
2014-02-18T00:00

在线演示

了解更多关于现代日期时间API*从Trail: Date Time。


*如果你正在为一个Android项目工作,而你的Android API级别仍然不兼容Java-8,检查Java 8+ API通过desugaring可用。注意,Android 8.0 Oreo已经提供了对java.time的支持。检查这个答案和这个答案,学习如何使用java。使用JDBC的时间API。