2010-01-25 21 views
9

Tengo que usar un formato de fecha personalizado en Java. Contiene microsegundos, aunque Java no proporciona soporte para microsegundos. Debido a eso llené el patrón de tiempo con ceros, que funcionan bien al formatear, pero no puedo analizar las cadenas de fechas con ese patrón.El formato de fecha personalizado no se puede analizar. (Java)

¿Hay una solución simple o debo manejar microsegundos por mi cuenta (con funciones de cadena)?

@Test 
public void testDateFormat() throws ParseException { 
    DateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss.SSS000"); 
    String theDate = format.format(new Date()); 
    // this will fail: 
    format.parse(theDate); 
} 

java.text.ParseException: Fecha unparseable: "2010-01-25-12.40.35.769000"

+0

FYI, las viejas clases problemáticas de fecha y hora como ['java.util.Date'] (https://docs.oracle.com/javase/8/docs/api/java/util/Date.html) , ['java.util.Calendar'] (https://docs.oracle.com/javase/8/docs/api/java/util/Calendar.html), y' java.text.SimpleTextFormat' son ahora [herencia ] (https://en.wikipedia.org/wiki/Legacy_system), suplantado por [java.time] (https://docs.oracle.com/javase/8/docs/api/java/time/package- summary.html) classes. Consulte [Tutorial de Oracle] (https://docs.oracle.com/javase/tutorial/datetime/TOC.html). –

Respuesta

11

Su problema es que el patrón utilizado en SimpleDateFormat lamentablemente tiene diferentes significados dependiendo de si se usa como analizador o como formateador. Como un formateador, su patrón no lo que se espera, la salida se cerrará con el valor de milisegundos con formato de tres dígitos seguido de tres caracteres 0, por ejemplo:

2010-01-25-14.17.47.307000

Se utiliza como un analizador sintáctico, el patrón "SSS" sin embargo coincidirá con un número arbitrario de dígitos y analizará el ejemplo anterior como 307000 ms. Después de haber analizado el campo ms, el analizador aún buscará una subcadena "000" y producirá un error con una excepción, ya que ha llegado al final de la cadena de entrada, sin cumplir los requisitos del patrón.

Dado que no hay un patrón para un valor μs en SimpleDateFormat, tendrá que escribir su propio contenedor para eliminar la cadena de entrada de los últimos tres 0 caracteres, antes de pasarlo a SimpleDateFormat.

0

Añadir un '' alrededor de los ceros, así: "yyyy-MM-dd-HH.mm.ss.SSS'000'"

Los formatos de fecha y hora están especificados por cadenas de patrón de fecha y hora. Dentro de cadenas de patrón de fecha y hora, letras no citadas de 'A' a 'Z' y de 'a' a 'z' se interpretan como letras de patrón que representan los componentes de una cadena de fecha u hora. El texto puede citarse utilizando comillas simples (') para evitar la interpretación. "''" representa una comilla simple. El resto de los caracteres no se interpretan; simplemente se copian en la cadena de salida durante el formateo o coinciden con con la cadena de entrada durante el análisis .

+5

Mi caso de prueba con comillas simples aún arroja una ParseException. –

+1

Porque '000' no son "letras de 'A' a 'Z' y de 'a' a 'z'". – Marboni

3

Además de la respuesta de jarnbjo, si necesita los microsegundos, es posible que pueda utilizar java.sql.Timestamp:

Date dateToMillis = format.parse(theDate.substring(0, 23)); 
DateFormat timestampFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 
Timestamp timestamp = Timestamp.valueOf(timestampFormat.format(dateToMillis) + theDate.substring(23,26)); 
1

tl; dr

LocalDateTime.parse( 
    "2010-01-25-12.40.35.769000" , 
    DateTimeFormatter.ofPattern("uuuu-MM-dd-HH.mm.ss.SSSSSS") 
) 

Usando java.time

Está utilizando antiguas clases problemáticas de fecha y hora que ahora son heredadas, suplantadas por las clases java.time.

Estas clases antiguas se limitaban a rastrear milliseconds, tres dígitos de la fracción decimal. La java moderna.las clases de tiempo se resuelven en nanoseconds, para nueve dígitos de fracción decimal.

DateTimeFormatter f = DateTimeFormatter.ofPattern("uuuu-MM-dd-HH.mm.ss.SSSSSS") ; 
LocalDateTime ldt = LocalDateTime.parse("2010-01-25-12.40.35.769000"); 

ldt.toString(): 2010-01-25T12: 40: 35,769

ISO 8601

Consejo: En lugar de inventar su propio formato para representar textualmente una fecha- valor de tiempo, se adhieren a los formatos estándar ISO 8601.

Las clases java.time usan los formatos estándar de forma predeterminada. Puede ver ese formato en el resultado anterior. El T separa la porción de fecha de la porción de hora del día.


Sobre java.time

El marco java.time está incorporado en Java 8 y versiones posteriores. Estas clases suplantan a las viejas y problemáticas clases de fecha y hora legacy, como java.util.Date, Calendar, & SimpleDateFormat.

El proyecto Joda-Time, ahora en maintenance mode, recomienda la migración a las clases java.time.

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

¿Dónde obtener las clases java.time?

El proyecto se extiende ThreeTen-Extra 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.

Cuestiones relacionadas