usuario2336315
Estaba jugando con la nueva API de fecha y hora, pero cuando ejecuté 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);
}
}
lanza:
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 son definido.
Entonces por qué DateTimeFormatter.ofPattern
no nos permite usar algunas letras patrón?
LocalDate
representa solo una fecha, no un DateTime. Así que “HH:mm:ss” no tiene sentido al formatear un LocalDate
. Utilizar una LocalDateTime
en su lugar, suponiendo que desea representar tanto una fecha como una hora.
-
¿Cómo puedo votar a favor de esta respuesta y rechazar el hecho de que hay un objeto LocalDate y LocalDateTime …
– Xiales
4 oct 2019 a las 21:47
-
Me gustaría trabajar simplemente con LocalTime, ¿cómo realiza el formateo sin encontrarse con esta excepción?
java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: DayOfWeek
– Samuel Owino
11 de enero de 2020 a las 23:11
-
No importa: esto funciona
DateTimeFormatter.ofPattern("HH:mm:ss")
– Samuel Owino
11 de enero de 2020 a las 23:22
-
@samuelowino Para mí esto funcionó:
DateTimeFormatter.ofPattern("HH:mm").withZone(ZoneId.systemDefault()).format(...)
. .withZone(…).– Ene
12 oct 2020 a las 16:15
-
he utilizado
DateTime dateTime = DateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.RFC_1123_DATE_TIME.withLocale(defaultLocale).withZone(defaultTimeZone.toZoneId());
esto me poneException in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: OffsetSeconds
Como @isapir abajo, a la derecha: ZonedDateTime. Entonces también sirve para esto. Así que terminé conZonedDateTime dateTime = ZonedDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.RFC_1123_DATE_TIME.withLocale(defaultLocale).withZone(defaultTimeZone.toZoneId());
– usuario637338
17 dic 2021 a las 23:49
Me gustaría agregar los siguientes detalles a la respuesta correcta de @James_D:
Fondo: La mayoría de las bibliotecas de fecha y hora (java.util.Calendar
en Java, consulte también .Net-DateTime o Date
en JavaScript o DateTime
en Perl) se basan en el concepto de un tipo temporal único universal para todo uso (en alemán existe la expresión poética “eierlegende Wollmilchsau”). En este diseño no puede haber un campo no soportado. Pero el precio es alto: muchos problemas de tiempo no se pueden manejar adecuadamente con un enfoque tan poco flexible porque es difícil o imposible encontrar un denominador común para todo tipo de objetos temporales.
JSR-310 ha elegido otro camino, es decir, para permitir diferentes tipos temporales que consisten en conjuntos específicos de tipo de campos incorporados 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 preguntar programáticamente cada objeto de tipo TemporalAccessor
para su conjunto específico de campos admitidos. Para LocalDate
encontramos:
•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
No hay campo HOUR_OF_DAY que explique el problema de UnsupportedTemporalTypeException
. Y si nos fijamos en el JSR-310-asignación de símbolos de patrones a campos vemos que el símbolo H está asignado a HOUR_OF_DAY no compatible:
/** 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);
}
Esta asignación de campo no significa que el campo sea compatible con el tipo concreto. El análisis ocurre en varios pasos. El mapeo de campos es solo el primer paso. El segundo paso es analizar un objeto sin formato de tipo 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.
-
en.wiktionary.org/wiki/eierlegende_Wollmilchsau (literalmente “lana-leche-cerda que pone huevos”) Un dispositivo o persona todo en uno que tiene (o dice tener) solo atributos positivos y que puede (o intenta) hacer el trabajo de varias herramientas especializadas. 🙂
– Trevor Robinson
11 mayo 2017 a las 20:32
isapir
La clase correcta para mí fue ZonedDateTime
que incluye Hora y Zona horaria.
LocalDate
no tiene la información de tiempo, por lo que obtiene un UnsupportedTemporalTypeException: Unsupported field: HourOfDay
.
Puedes usar LocalDateTime
pero luego 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á un UnsupportedTemporalTypeException: Unsupported field: OffsetSeconds
.
-
Esta respuesta debe ser la respuesta aceptada o debe agregarse a la respuesta aceptada actual.
– gourabix
1 de febrero a las 14:10
-
Inconvertible types; cannot cast 'java.time.LocalDateTime' to 'java.time.ZonedDateTime'
:/– MarkHu
26 de febrero a las 0:53
Tuve un problema similar con este código:
DateTimeFormatter.RFC_1123_DATE_TIME.format(new Date().toInstant())
java.time.temporal.UnsupportedTemporalTypeException: campo no admitido: DayOfMonth
Lo resolví de esta manera:
DateTimeFormatter.RFC_1123_DATE_TIME.format(
ZonedDateTime.ofInstant(new Date().toInstant(), ZoneId.systemDefault()))