Estaba jugando con la nueva API de fecha y hora, pero al ejecutar esto:
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);
}
}
Arroja:
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)
Al mirar el código fuente de la clase LocalDate, veo:
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);
}
Como se describe en el documento:
Este método creará un formateador basado en un patrón simple de letras y símbolos como se describe en la documentación de la clase.
Y todas estas letras están definidas .
Entonces, ¿por qué DateTimeFormatter.ofPattern
no nos permite usar algunos patrones de letras?
java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: DayOfWeek
DateTimeFormatter.ofPattern("HH:mm:ss")
Me gustaría agregar los siguientes detalles a la respuesta correcta de @James_D:
Antecedentes: la mayoría de las bibliotecas de fecha y hora (
java.util.Calendar
en Java, consulte también .Net-DateTime oDate
en JavaScript oDateTime
en Perl) se basan en el concepto de un tipo temporal único universal y universal (en alemán existe la expresión poética " eierlegende Wollmilchsau "). En este diseño no puede haber un campo no admitido. Pero el precio es alto: muchos problemas de tiempo no pueden manejarse adecuadamente con un enfoque tan inflexible porque es difícil o imposible encontrar un denominador común para todo tipo de objetos temporales.JSR-310 ha elegido otra forma , a saber, permitir diferentes tipos temporales que consisten en conjuntos específicos de tipos de campos integrados admitidos. La consecuencia natural es que no todos los campos posibles son compatibles con todos los tipos (y los usuarios pueden incluso definir sus propios campos especializados). También es posible solicitar mediante programación a cada objeto de tipo
TemporalAccessor
su conjunto específico de campos admitidos. PorqueLocalDate
encontramos:No hay ningún campo HOUR_OF_DAY que explique el problema de
UnsupportedTemporalTypeException
. Y si miramos el mapeo JSR-310- de símbolos de patrón a campos , vemos que el símbolo H está mapeado a HOUR_OF_DAY no admitido:Este mapeo de campo no significa que el campo sea compatible con el tipo concreto. El análisis se realiza en varios pasos. El mapeo de campo es solo el primer paso. El segundo paso es analizar un objeto de tipo sin formato
TemporalAccessor
. Y finalmente, analizar los delegados al tipo de destino (aquíLocalDate
:) y dejar que decida si acepta todos los valores de campo en el objeto intermedio analizado.fuente
La clase adecuada para mí fue la
ZonedDateTime
que incluye tanto la hora como la zona horaria.LocalDate
no tiene la información de la hora, por lo que obtiene unUnsupportedTemporalTypeException: Unsupported field: HourOfDay
.Puede usar,
LocalDateTime
pero no tiene la información de la zona horaria, por lo que si intenta acceder a eso (incluso usando uno de los formateadores predefinidos) obtendrá unUnsupportedTemporalTypeException: Unsupported field: OffsetSeconds
.fuente