Creo que lo que mucha gente quiere hacer es analizar cadenas de fechas JSON. Si viene a esta página, es muy probable que desee convertir una fecha JSON de JavaScript en una fecha Java.
Para mostrar cómo se ve una cadena de fecha JSON:
var d=new Date();
var s = JSON.stringify(d);
document.write(s);
document.write("<br />"+d);
"2013-12-14T01:55:33.412Z"
Fri Dec 13 2013 17:55:33 GMT-0800 (PST)
La cadena de fecha JSON es 2013-12-14T01: 55: 33.412Z.
Las fechas no están cubiertas por la especificación JSON por ejemplo, pero lo anterior es un formato ISO 8601 muy específico, mientras que ISO_8601 es mucho más grande y ese es un mero subconjunto, aunque muy importante.
Ver http://www.json.org
Ver http://en.wikipedia.org/wiki/ISO_8601
Ver http://www.w3.org/TR/NOTE-datetime
Resulta que escribí un analizador JSON y un analizador PLIST que usan ISO-8601 pero no los mismos bits.
/*
var d=new Date();
var s = JSON.stringify(d);
document.write(s);
document.write("<br />"+d);
"2013-12-14T01:55:33.412Z"
Fri Dec 13 2013 17:55:33 GMT-0800 (PST)
*/
@Test
public void jsonJavaScriptDate() {
String test = "2013-12-14T01:55:33.412Z";
Date date = Dates.fromJsonDate ( test );
Date date2 = Dates.fromJsonDate_ ( test );
assertEquals(date2.toString (), "" + date);
puts (date);
}
Escribí dos formas de hacer esto para mi proyecto. Un estándar, uno rápido.
Nuevamente, la cadena de fecha JSON es una implementación muy específica de ISO 8601 ...
(Publiqué el otro en la otra respuesta que debería funcionar para las fechas PLIST, que son un formato ISO 8601 diferente).
La fecha JSON es la siguiente:
public static Date fromJsonDate_( String string ) {
try {
return new SimpleDateFormat ( "yyyy-MM-dd'T'HH:mm:ss.SSSXXX").parse ( string );
} catch ( ParseException e ) {
return Exceptions.handle (Date.class, "Not a valid JSON date", e);
}
}
Los archivos PLIST (ASCII no GNUNext) también usan ISO 8601 pero no milisegundos, así que ... no todas las fechas ISO-8601 son iguales. (Al menos aún no he encontrado uno que use milis y el analizador que he visto omite la zona horaria OMG).
Ahora para la versión rápida (puedes encontrarla en Boon).
public static Date fromJsonDate( String string ) {
return fromJsonDate ( Reflection.toCharArray ( string ), 0, string.length () );
}
Tenga en cuenta que Reflection.toCharArray usa inseguro si está disponible, pero por defecto es string.toCharArray si no.
(Puede sacarlo del ejemplo reemplazando Reflection.toCharArray (string) con string.toCharArray ()).
public static Date fromJsonDate( char[] charArray, int from, int to ) {
if (isJsonDate ( charArray, from, to )) {
int year = CharScanner.parseIntFromTo ( charArray, from + 0, from + 4 );
int month = CharScanner.parseIntFromTo ( charArray, from +5, from +7 );
int day = CharScanner.parseIntFromTo ( charArray, from +8, from +10 );
int hour = CharScanner.parseIntFromTo ( charArray, from +11, from +13 );
int minute = CharScanner.parseIntFromTo ( charArray, from +14, from +16 );
int second = CharScanner.parseIntFromTo ( charArray, from +17, from +19 );
int miliseconds = CharScanner.parseIntFromTo ( charArray, from +20, from +23 );
TimeZone tz = TimeZone.getTimeZone ( "GMT" );
return toDate ( tz, year, month, day, hour, minute, second, miliseconds );
} else {
return null;
}
}
El isJsonDate se implementa de la siguiente manera:
public static boolean isJsonDate( char[] charArray, int start, int to ) {
boolean valid = true;
final int length = to -start;
if (length != JSON_TIME_LENGTH) {
return false;
}
valid &= (charArray [ start + 19 ] == '.');
if (!valid) {
return false;
}
valid &= (charArray[ start +4 ] == '-') &&
(charArray[ start +7 ] == '-') &&
(charArray[ start +10 ] == 'T') &&
(charArray[ start +13 ] == ':') &&
(charArray[ start +16 ] == ':');
return valid;
}
De todos modos ... supongo que algunas personas que vienen aquí ... podrían estar buscando la cadena de fecha JSON y, aunque es una fecha ISO-8601, es muy específica y necesita un análisis muy específico.
public static int parseIntFromTo ( char[] digitChars, int offset, int to ) {
int num = digitChars[ offset ] - '0';
if ( ++offset < to ) {
num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
if ( ++offset < to ) {
num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
if ( ++offset < to ) {
num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
if ( ++offset < to ) {
num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
if ( ++offset < to ) {
num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
if ( ++offset < to ) {
num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
if ( ++offset < to ) {
num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
if ( ++offset < to ) {
num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
}
}
}
}
}
}
}
}
return num;
}
Consulte https://github.com/RichardHightower/boon
Boon tiene un analizador PLIST (ASCII) y un analizador JSON.
El analizador JSON es el analizador Java JSON más rápido que conozco.
Verificado independientemente por los muchachos de Gatling Performance.
https://github.com/gatling/json-parsers-benchmark
Benchmark Mode Thr Count Sec Mean Mean error Units
BoonCharArrayBenchmark.roundRobin thrpt 16 10 1 724815,875 54339,825 ops/s
JacksonObjectBenchmark.roundRobin thrpt 16 10 1 580014,875 145097,700 ops/s
JsonSmartBytesBenchmark.roundRobin thrpt 16 10 1 575548,435 64202,618 ops/s
JsonSmartStringBenchmark.roundRobin thrpt 16 10 1 541212,220 45144,815 ops/s
GSONStringBenchmark.roundRobin thrpt 16 10 1 522947,175 65572,427 ops/s
BoonDirectBytesBenchmark.roundRobin thrpt 16 10 1 521528,912 41366,197 ops/s
JacksonASTBenchmark.roundRobin thrpt 16 10 1 512564,205 300704,545 ops/s
GSONReaderBenchmark.roundRobin thrpt 16 10 1 446322,220 41327,496 ops/s
JsonSmartStreamBenchmark.roundRobin thrpt 16 10 1 276399,298 130055,340 ops/s
JsonSmartReaderBenchmark.roundRobin thrpt 16 10 1 86789,825 17690,031 ops/s
Tiene el analizador JSON más rápido para secuencias, lectores, bytes [], char [], CharSequence (StringBuilder, CharacterBuffer) y String.
Ver más puntos de referencia en:
https://github.com/RichardHightower/json-parsers-benchmark