2009-09-23 41 views
16

Quiero guardar un objeto Date en una cadena legible (por ejemplo 22/10/2009 21:13:14) que también se puede volver a procesar en un objeto Date.Formato de fecha legible y procesable por el ser humano en Java

He intentado muchas cosas y lo mejor que pude encontrar fue utilizar DateFormater para analizar y formatear, pero tiene un revés. Cuando formatea una fecha, pierde información de segundos. Traté de encontrar si había una opción para formatearlo y mostrar los segundos (incluso mejor sería al nivel de milisegundo, ya que esa es la resolución que el objeto Date le permite tener), pero me quedé corto.

¿Alguna idea?

Respuesta

37

Tome un vistazo a java.text.SimpleDateFormat

SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss.SSS"); 
Date dt = new Date(); 
String S = sdf.format(dt); // formats to 09/23/2009 13:53:28.238 
Date dt2 = sdf.parse(S); // parses back 
+0

Cuando esta respuesta fue escrito en 2009 , 'SimpleDateFormat' era lo que teníamos para este propósito. Ha resultado problemático y afortunadamente ha sido reemplazado por 'java.time', la moderna API de fecha y hora de Java, y su clase' DateTimeFormatter' en 2014. Recomiendo que nunca vuelva a utilizar 'SimpleDateFormat'. –

4

SimpleDateFormat puede formatear y analizar una fecha basada en un sistema de patrón muy simple que incluye segundas e incluso milisegundos.

+1

@Unihedron Actualizado el enlace. Los revisores, tenga en cuenta que esta NO es una respuesta de solo enlace: la respuesta todavía tiene significado sin el enlace, y el enlace en sí es a la documentación oficial. –

2

Un poco fuera de tema, pero siempre siento la necesidad de recordar a la gente que DateFormat y SimpleDateFormat no son seguros para subprocesos. La documentación de Sun lo dice claramente, pero sigo encontrando código en la naturaleza donde las personas pegan un SimpleDateFormat en un archivo estático ...

+0

Es por eso que todo el mundo debería usar Joda Time y ahorrarse dolores de cabeza :) – Nick

+0

Estoy totalmente de acuerdo. Por otro lado, quiero que Sun arregle estas clases, así que, si nada más, no tengo que sentarme a otra sesión de "lecciones aprendidas de concurrencia" con personas que me advierten sobre ellas. (Oh, la ironía ... Acabo de hacer exactamente lo mismo aquí en StackOverflow :-)) –

4

Otras respuestas son todas buenas.

Pero cuando se hace este tipo de cosas favor recoger un formato que tipo adecuadamente cuando se codifican como una cadena .... "aaaa/MM/dd hh: mm: ss" está muy bien. Siempre me sorprende cuando los ingenieros de software eligen un formato de fecha que no ordena de la manera obvia y conveniente.

se ahorrará al resto de desarrolladores mucho dolor en un punto distante en el futuro - pensar en él como un buen karma :-)

+0

"aaaa/dd/MM" no ordena bien. Considere que 2015/21/10, 2015/20/11 y 2015/22/11 se ordenan en 2015/20/11, 2015/21/10, 2015/22/11 como cadenas. –

+2

Lo siento, quise decir aaaa/MM/dd. Fijo. – mikera

1

ISO 8601

Usar formato ISO 8601.

  • Es flexible, que incluye segundos y fracción de segundo, si los hay, pero también se puede dejar fuera si son 0.
  • Es normal, por lo que más y más herramientas de formato y analizarlo. Ideal para serialización para almacenamiento o intercambio de datos.
  • Suena como 2009-10-22T21:13:14, debería decir que es bastante legible por humanos (aunque el T en el medio que denota el comienzo de la parte de tiempo puede parecer inusual al principio).
  • Las cadenas separado la ropa adecuadamente, tal como se solicita en mikera another answer, siempre que los años están en el rango de cuatro dígitos desde 1000 a 9999.
  • Las clases de java.time, la fecha de Java API moderna y tiempo, así como los de Joda Time analizan ISO 8601 como su valor predeterminado, es decir, sin ningún formateador explícito, y producen el mismo formato de sus métodos toString.

Una modesta demostración de la utilización de java.time:

LocalDateTime dateTime = LocalDateTime.of(2009, 10, 22, 21, 13, 14); 
String readableString = dateTime.toString(); 
System.out.println(readableString); 
LocalDateTime parsedBack = LocalDateTime.parse(readableString); 
System.out.println(parsedBack); 

Esto imprime dos líneas idénticas:

2009-10-22T21:13:14 
2009-10-22T21:13:14 

Este último System.out.println() CALL llama implícitamente toString() una vez más, así que esto no debería sorprender.

0

Si desea hacerlo un poco más simple, y estar a salvo de hacer su propio DateFormat que la mayoría de otras respuestas implican, puede aprovechar el formato por defecto en java.time.Instant:

(new Date()).toInstant.toString(); 
Cuestiones relacionadas