Bir çok insanın yapmak istediği şey JSON tarih dizelerini ayrıştırmak. Bu sayfaya gelirseniz, bir JavaScript JSON tarihini bir Java tarihine dönüştürmek isteyebilirsiniz.
JSON tarih dizesinin neye benzediğini göstermek için:
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)
JSON tarih dizesi 2013-12-14T01: 55: 33.412Z'dir.
Tarihler JSON spesifikasyonları tarafından kapsanmamaktadır, ancak yukarıda belirtilenler çok özel bir ISO 8601 formatı iken, ISO_8601 çok daha büyüktür ve bu çok önemli olsa da sadece bir alt kümedir.
Bkz. Http://www.json.org
Bkz. Http://en.wikipedia.org/wiki/ISO_8601
Bkz. Http://www.w3.org/TR/NOTE-datetime
Olduğu gibi, her ikisi de ISO-8601 kullanan ancak aynı bitleri olmayan bir JSON ayrıştırıcısı ve bir PLIST ayrıştırıcısı yazdım.
/*
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);
}
Projem için bunu yapmanın iki yolunu yazdım. Bir standart, bir hızlı.
Yine, JSON tarih dizesi ISO 8601'in çok özel bir uygulamasıdır ....
(Diğerini farklı bir ISO 8601 formatı olan PLIST tarihleri için çalışması gereken diğer cevapta yayınladım).
JSON tarihi aşağıdaki gibidir:
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);
}
}
PLIST dosyaları (GNUNext olmayan ASCII) de ISO 8601 kullanıyor ancak milisaniye yok, bu yüzden ... ISO-8601 tarihlerinin hepsi aynı değil. (En azından henüz milis kullanan bir tane bulamadım ve gördüğüm ayrıştırıcı saat dilimini tamamen atlıyor OMG).
Şimdi hızlı sürüm için (Boon'da bulabilirsiniz).
public static Date fromJsonDate( String string ) {
return fromJsonDate ( Reflection.toCharArray ( string ), 0, string.length () );
}
Reflection.toCharArray öğesinin kullanılabiliyorsa güvensiz kullandığını, ancak varsayılan olarak string.toCharArray öğesini kullandığını unutmayın.
(Reflection.toCharArray (string) öğesini string.toCharArray () ile değiştirerek örnekten çıkarabilirsiniz).
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;
}
}
İsJsonDate aşağıdaki gibi uygulanır:
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;
}
Her neyse ... Tahminimce buraya gelen birkaç kişi JSON Date String'i arıyor olabilir ve bir ISO-8601 tarihi olmasına rağmen, çok özel bir ayrıştırmaya ihtiyaç duyan çok özel bir tanesidir.
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;
}
Bkz. Https://github.com/RichardHightower/boon
Boon'un bir PLIST ayrıştırıcısı (ASCII) ve bir JSON ayrıştırıcısı vardır.
JSON ayrıştırıcısı, bildiğim en hızlı Java JSON ayrıştırıcısıdır.
Gatling Performance dostları tarafından bağımsız olarak doğrulandı.
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
Akışlar, okuyucular, bayt [], char [], CharSequence (StringBuilder, CharacterBuffer) ve String için en hızlı JSON ayrıştırıcısına sahiptir.
Diğer ölçütlere bakın:
https://github.com/RichardHightower/json-parsers-benchmark