simple parse example java date simpledateformat iso8601

parse - Carácter de patrón "T" ilegal al analizar una cadena de fecha a java.util.Date



simpledateformat timezone (2)

tl; dr

Instant.parse( "2010-10-02T12:23:23Z" )

ISO 8601

Ese formato está definido por el ISO8601 para formatos de cadena de fecha y hora.

Ambos:

... use los formatos ISO 8601 por defecto para analizar y generar cadenas.

En general, debe evitar el uso de las antiguas clases java.util.Date /.Calendar y java.text.SimpleDateFormat, ya que son notoriamente problemáticas, confusas y defectuosas. Si es necesario para la interoperación, puede convertir de aquí para allá.

java.time

Incorporado en Java 8 y posterior es el nuevo marco java.time . Inspirado por Joda-Time , definido por JSR 310 , y extendido por el proyecto ThreeTen-Extra .

Instant instant = Instant.parse( "2010-10-02T12:23:23Z" ); // `Instant` is always in UTC.

Convierte a la clase anterior.

java.util.Date date = java.util.Date.from( instant ); // Pass an `Instant` to the `from` method.

Zona horaria

Si es necesario, puede asignar un huso horario.

ZoneId zoneId = ZoneId.of( "America/Montreal" ); // Define a time zone rather than rely implicitly on JVM’s current default time zone. ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId ); // Assign a time zone adjustment from UTC.

Convertir.

java.util.Date date = java.util.Date.from( zdt.toInstant() ); // Extract an `Instant` from the `ZonedDateTime` to pass to the `from` method.

Joda-Time

ACTUALIZACIÓN: El proyecto Joda-Time ahora está en modo de mantenimiento. El equipo aconseja la migración a las clases java.time .

Aquí hay un código de ejemplo en Joda-Time 2.8.

org.joda.time.DateTime dateTime_Utc = new DateTime( "2010-10-02T12:23:23Z" , DateTimeZone.UTC ); // Specifying a time zone to apply, rather than implicitly assigning the JVM’s current default.

Convierte a la clase anterior. Tenga en cuenta que la zona horaria asignada se pierde en la conversión, ya que a juDate no se le puede asignar una zona horaria.

java.util.Date date = dateTime_Utc.toDate(); // The `toDate` method converts to old class.

Zona horaria

Si es necesario, puede asignar un huso horario.

DateTimeZone zone = DateTimeZone.forID( "America/Montreal" ); DateTime dateTime_Montreal = dateTime_Utc.withZone ( zone );

Acerca de java.time

El marco java.time está integrado en Java 8 y posterior. Estas clases suplantan a las problemáticas antiguas clases legacy fecha y hora como java.util.Date , Calendar y SimpleDateFormat .

El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a las clases java.time .

Para obtener más información, consulte el Tutorial . Y busque Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .

Puede intercambiar objetos java.time directamente con su base de datos. Use un controlador JDBC que cumpla con JDBC 4.2 o posterior. Sin necesidad de cadenas, sin necesidad de clases java.sql.* .

¿Dónde obtener las clases de java.time?

  • Java SE 8 , Java SE 9 y posterior
    • Incorporado.
    • Parte de la API Java estándar con una implementación integrada.
    • Java 9 agrega algunas características y correcciones menores.
  • Java SE 6 y Java SE 7
    • Gran parte de la funcionalidad de java.time se transfiere a Java 6 y 7 en ThreeTen-Backport .
  • Android
    • Versiones posteriores de las implementaciones del paquete de Android de las clases java.time.
    • Para Android anterior (<26), el proyecto ThreeTenABP adapta ThreeTen-Backport (mencionado anteriormente). Consulte Cómo utilizar ThreeTenABP ....

El proyecto ThreeTen-Extra amplía java.time con clases adicionales. Este proyecto es un terreno de prueba para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí, como Interval , YearWeek , YearQuarter y more .

Tengo una cadena de fecha y quiero analizarla en una fecha normal, use la API de fecha de Java, el siguiente es mi código:

public static void main(String[] args) { String date="2010-10-02T12:23:23Z"; String pattern="yyyy-MM-ddThh:mm:ssZ"; SimpleDateFormat sdf=new SimpleDateFormat(pattern); try { Date d=sdf.parse(date); System.out.println(d.getYear()); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } }

Sin embargo, obtuve una excepción: java.lang.IllegalArgumentException: Illegal pattern character ''T''

Entonces, me pregunto si tengo que dividir la cadena y analizarla manualmente.

Por cierto, he intentado agregar un solo carácter de comillas a cada lado de la T:

String pattern="yyyy-MM-dd''T''hh:mm:ssZ";

Tampoco funciona.


Actualización para Java 8 y superior

Ahora puede simplemente hacer Instance.parse("2015-04-28T14:23:38.521Z") y obtener lo correcto ahora, especialmente debido a que debe utilizar Instance lugar del java.util.Date roto con las versiones más recientes. de Java.

Debería utilizar DateTimeFormatter lugar de SimpleDateFormatter también.

La siguiente explicación sigue siendo válida como lo que representa el formato.

Esto funciona con la entrada con la Z final como se demuestra:

En el patrón, la T se escapa con '' en cualquier lado.

El patrón para la Z al final es en realidad XXX tal como se documenta en SimpleDateFormat para SimpleDateFormat , simplemente no es muy claro sobre cómo usarlo, ya que Z es el marcador de la antigua información TimeZone .

Q2597083.java

import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.TimeZone; public class Q2597083 { /** * All Dates are normalized to UTC, it is up the client code to convert to the appropriate TimeZone. */ public static final TimeZone UTC; /** * @see <a href="http://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations">Combined Date and Time Representations</a> */ public static final String ISO_8601_24H_FULL_FORMAT = "yyyy-MM-dd''T''HH:mm:ss.SSSXXX"; /** * 0001-01-01T00:00:00.000Z */ public static final Date BEGINNING_OF_TIME; /** * 292278994-08-17T07:12:55.807Z */ public static final Date END_OF_TIME; static { UTC = TimeZone.getTimeZone("UTC"); TimeZone.setDefault(UTC); final Calendar c = new GregorianCalendar(UTC); c.set(1, 0, 1, 0, 0, 0); c.set(Calendar.MILLISECOND, 0); BEGINNING_OF_TIME = c.getTime(); c.setTime(new Date(Long.MAX_VALUE)); END_OF_TIME = c.getTime(); } public static void main(String[] args) throws Exception { final SimpleDateFormat sdf = new SimpleDateFormat(ISO_8601_24H_FULL_FORMAT); sdf.setTimeZone(UTC); System.out.println("sdf.format(BEGINNING_OF_TIME) = " + sdf.format(BEGINNING_OF_TIME)); System.out.println("sdf.format(END_OF_TIME) = " + sdf.format(END_OF_TIME)); System.out.println("sdf.format(new Date()) = " + sdf.format(new Date())); System.out.println("sdf.parse(/"2015-04-28T14:23:38.521Z/") = " + sdf.parse("2015-04-28T14:23:38.521Z")); System.out.println("sdf.parse(/"0001-01-01T00:00:00.000Z/") = " + sdf.parse("0001-01-01T00:00:00.000Z")); System.out.println("sdf.parse(/"292278994-08-17T07:12:55.807Z/") = " + sdf.parse("292278994-08-17T07:12:55.807Z")); } }

Produce el siguiente resultado:

sdf.format(BEGINNING_OF_TIME) = 0001-01-01T00:00:00.000Z sdf.format(END_OF_TIME) = 292278994-08-17T07:12:55.807Z sdf.format(new Date()) = 2015-04-28T14:38:25.956Z sdf.parse("2015-04-28T14:23:38.521Z") = Tue Apr 28 14:23:38 UTC 2015 sdf.parse("0001-01-01T00:00:00.000Z") = Sat Jan 01 00:00:00 UTC 1 sdf.parse("292278994-08-17T07:12:55.807Z") = Sun Aug 17 07:12:55 UTC 292278994