Java 使用新的日期时间API格式化日期

Java 使用新的日期时间API格式化日期,java,datetime,java-8,java-time,Java,Datetime,Java 8,Java Time,我正在使用新的日期时间API,但在运行此API时: public class Test { public static void main(String[] args){ String dateFormatted = LocalDate.now() .format(DateTimeFormatter

我正在使用新的日期时间API,但在运行此API时:

public class Test {         
    public static void main(String[] args){
        String dateFormatted = LocalDate.now()
                                        .format(DateTimeFormatter
                                              .ofPattern("yyyy-MM-dd HH:mm:ss"));
        System.out.println(dateFormatted);
    }
}
它抛出:

Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: HourOfDay
    at java.time.LocalDate.get0(LocalDate.java:680)
    at java.time.LocalDate.getLong(LocalDate.java:659)
    at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:298)
    at java.time.format.DateTimeFormatterBuilder$NumberPrinterParser.format(DateTimeFormatterBuilder.java:2543)
    at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2182)
    at java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1745)
    at java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1719)
    at java.time.LocalDate.format(LocalDate.java:1685)
    at Test.main(Test.java:23)
查看LocalDate类的源代码时,我看到:

  private int get0(TemporalField field) {
        switch ((ChronoField) field) {
            case DAY_OF_WEEK: return getDayOfWeek().getValue();
            case ALIGNED_DAY_OF_WEEK_IN_MONTH: return ((day - 1) % 7) + 1;
            case ALIGNED_DAY_OF_WEEK_IN_YEAR: return ((getDayOfYear() - 1) % 7) + 1;
            case DAY_OF_MONTH: return day;
            case DAY_OF_YEAR: return getDayOfYear();
            case EPOCH_DAY: throw new UnsupportedTemporalTypeException("Invalid field 'EpochDay' for get() method, use getLong() instead");
            case ALIGNED_WEEK_OF_MONTH: return ((day - 1) / 7) + 1;
            case ALIGNED_WEEK_OF_YEAR: return ((getDayOfYear() - 1) / 7) + 1;
            case MONTH_OF_YEAR: return month;
            case PROLEPTIC_MONTH: throw new UnsupportedTemporalTypeException("Invalid field 'ProlepticMonth' for get() method, use getLong() instead");
            case YEAR_OF_ERA: return (year >= 1 ? year : 1 - year);
            case YEAR: return year;
            case ERA: return (year >= 1 ? 1 : 0);
        }
        throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
    }
如文件所述:

此方法将基于一个简单的 课程文档中描述的字母和符号

所有这些字母都是


那么为什么模式的DateTimeFormatter.of不允许我们使用一些模式字母呢

LocalDate
只表示一个日期,而不是日期时间。因此,在格式化
LocalDate
时,“HH:mm:ss”毫无意义。使用
LocalDateTime
,假设您希望同时表示日期和时间。

我想在@James\u D的正确答案中添加以下详细信息:

背景:大多数日期和时间库(java中的
java.util.Calendar
,另见JavaScript中的.Net DateTime或
date
,或Perl中的
DateTime
)都基于通用的通用唯一时间类型的概念(德语中有诗意的表达“eierlegende Wollmilchsau”)。在此设计中,不能有不受支持的字段。但代价很高:许多时间问题不能用这种不灵活的方法来充分处理,因为很难找到所有类型的时间对象的共同点

JSR-310选择了另一种方式,即允许不同的时态类型,这些时态类型由特定类型的受支持内置字段集组成。自然的结果是,并非每种类型都支持所有可能的字段(用户甚至可以定义自己的专用字段)。还可以为每个类型为
TemporalAccessor
的对象指定一组支持的字段。对于
LocalDate
我们发现:

•DAY_OF_WEEK 
•ALIGNED_DAY_OF_WEEK_IN_MONTH 
•ALIGNED_DAY_OF_WEEK_IN_YEAR 
•DAY_OF_MONTH 
•DAY_OF_YEAR 
•EPOCH_DAY 
•ALIGNED_WEEK_OF_MONTH 
•ALIGNED_WEEK_OF_YEAR 
•MONTH_OF_YEAR 
•PROLEPTIC_MONTH 
•YEAR_OF_ERA 
•YEAR 
•ERA 
没有HOUR OF DAY字段解释不支持的时间类型异常问题。如果我们查看JSR-310,我们会看到符号H被映射到不受支持的小时数:

/** Map of letters to fields. */  
private static final Map<Character, TemporalField> FIELD_MAP = new HashMap<>();
static {
  FIELD_MAP.put('G', ChronoField.ERA);
  FIELD_MAP.put('y', ChronoField.YEAR_OF_ERA);
  FIELD_MAP.put('u', ChronoField.YEAR);
  FIELD_MAP.put('Q', IsoFields.QUARTER_OF_YEAR);
  FIELD_MAP.put('q', IsoFields.QUARTER_OF_YEAR);
  FIELD_MAP.put('M', ChronoField.MONTH_OF_YEAR);
  FIELD_MAP.put('L', ChronoField.MONTH_OF_YEAR);
  FIELD_MAP.put('D', ChronoField.DAY_OF_YEAR);
  FIELD_MAP.put('d', ChronoField.DAY_OF_MONTH);
  FIELD_MAP.put('F', ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH);
  FIELD_MAP.put('E', ChronoField.DAY_OF_WEEK);
  FIELD_MAP.put('c', ChronoField.DAY_OF_WEEK);
  FIELD_MAP.put('e', ChronoField.DAY_OF_WEEK);
  FIELD_MAP.put('a', ChronoField.AMPM_OF_DAY);
  FIELD_MAP.put('H', ChronoField.HOUR_OF_DAY);
  FIELD_MAP.put('k', ChronoField.CLOCK_HOUR_OF_DAY);
  FIELD_MAP.put('K', ChronoField.HOUR_OF_AMPM);
  FIELD_MAP.put('h', ChronoField.CLOCK_HOUR_OF_AMPM);
  FIELD_MAP.put('m', ChronoField.MINUTE_OF_HOUR);
  FIELD_MAP.put('s', ChronoField.SECOND_OF_MINUTE);
  FIELD_MAP.put('S', ChronoField.NANO_OF_SECOND);
  FIELD_MAP.put('A', ChronoField.MILLI_OF_DAY);
  FIELD_MAP.put('n', ChronoField.NANO_OF_SECOND);
  FIELD_MAP.put('N', ChronoField.NANO_OF_DAY);    
}
/**字母到字段的映射。*/
私有静态最终映射字段_Map=new HashMap();
静止的{
场地图放置('G',计时场纪元);
场地图放置('y',年代场年);
现场地图放置('u',计时现场年份);
场地图put('Q',等场。年的季度);
场地图put('q',等场。年的季度);
字段地图放置('M',时间字段。年份月份);
字段地图放置('L',时间字段。年份月份);
现场地图放置('D',时间现场日期);
字段地图放置('d',时间字段。每月的日期);
字段地图放置('F',时间字段对齐,以周为单位,以月为单位);
现场地图放置('E',计时现场。每周的第天);
现场地图放置('c',计时现场。每周的第天);
现场地图放置('e',计时现场。每周的第天);
场地图放置('a',计时场地图日期);
现场地图放置('H',时间现场小时);
现场地图放置('k',计时现场时钟(每天的小时);
现场地图放置('K',计时现场小时);
场地图输入('h',场时钟小时);
场地图放置('m',计时场。分钟/小时);
场地图放置('s',计时场。秒/分钟);
场地图放置('S',计时场。纳米秒);
场地图放置('A',计时场。百万天);
场地图放置('n',计时场。纳米秒);
场地图放置('N',计时场。纳米日);
}

此字段映射并不意味着该字段受具体类型的支持。解析分为几个步骤。字段映射只是第一步。第二步是解析到类型为
TemporalAccessor
的原始对象。最后,解析目标类型的委托(这里:
LocalDate
),让它决定是否接受解析的中间对象中的所有字段值。

对我来说正确的类是,它包括Time和Time Zone

LocalDate
没有时间信息,因此您会得到一个
UnsupportedTemporalTypeException:Unsupported字段:HourOfDay


您可以使用
LocalDateTime
,但是您没有时区信息,因此如果您尝试访问该信息(即使使用一个预定义的格式化程序),您将得到一个
不支持的时间类型异常:不支持的字段:OffsetSeconds

(字面意思是“产卵羊毛牛奶母猪”)只有(或声称拥有)积极属性,并且能够(或试图)使用多种专用工具工作的一体式设备或人员。:-)我怎样才能向上投票这个答案,向下投票一个LocalDate和一个LocalDateTime对象……我只想使用LocalTime,如何执行格式化而不遇到此异常
java.time.temporal.UnsupportedTemporalTypeException:Unsupported字段:DayOfWeek
没关系:这工作
DateTimeFormatter.ofPattern(“HH:mm:ss”)
@samuelowino对我来说这工作:
DateTimeFormatter.ofPattern(“HH:mm”).withZone(ZoneId.systemDefault()).format(…)