2008-08-06 12 views
19

Ich habe versucht, eine sehr schnelle Möglichkeit zu finden, JJJJ-MM-TT [hh: mm: ss] in ein Date-Objekt zu analysieren. Hier sind die 3 Möglichkeiten, die ich versucht habe, und die Zeiten, die jede Methode benötigt, um 50.000 Datum-Zeit-Strings zu parsen.Actionscript 3 - Schnellste Methode zum Analysieren von JJJJ-MM-TT hh: mm: ss zu einem Date-Objekt?

Kennt jemand schnellere Vorgehensweisen oder Tipps, um die Methoden zu beschleunigen?

castMethod1 takes 3673 ms 
castMethod2 takes 3812 ms 
castMethod3 takes 3931 ms 

Code:

private function castMethod1(dateString:String):Date { 
    if (dateString == null) { 
     return null; 
    } 

    var year:int = int(dateString.substr(0,4)); 
    var month:int = int(dateString.substr(5,2))-1; 
    var day:int = int(dateString.substr(8,2)); 

    if (year == 0 && month == 0 && day == 0) { 
     return null; 
    } 

    if (dateString.length == 10) { 
     return new Date(year, month, day); 
    } 

    var hour:int = int(dateString.substr(11,2)); 
    var minute:int = int(dateString.substr(14,2)); 
    var second:int = int(dateString.substr(17,2)); 

    return new Date(year, month, day, hour, minute, second); 
} 

-

private function castMethod2(dateString:String):Date { 
    if (dateString == null) { 
     return null; 
    } 

    if (dateString.indexOf("0000-00-00") != -1) { 
     return null; 
    } 

    dateString = dateString.split("-").join("/"); 

    return new Date(Date.parse(dateString)); 
} 

-

private function castMethod3(dateString:String):Date { 
    if (dateString == null) { 
     return null; 
    } 

    var mainParts:Array = dateString.split(" "); 
    var dateParts:Array = mainParts[0].split("-"); 

    if (Number(dateParts[0])+Number(dateParts[1])+Number(dateParts[2]) == 0) { 
     return null; 
    } 

    return new Date(Date.parse(dateParts.join("/")+(mainParts[1]?" "+mainParts[1]:" "))); 
} 

Nein, Date.parse nicht behandeln Bindestriche standardmäßig. Und ich muss null für Datum Zeit Zeichenfolgen wie "0000-00-00" zurückgeben.

Antwort

17

Ich habe die folgende snipplet wurden unter Verwendung von Zeichenketten UTC-Datum zu analysieren:

private function parseUTCDate(str : String) : Date { 
    var matches : Array = str.match(/(\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)Z/); 

    var d : Date = new Date(); 

    d.setUTCFullYear(int(matches[1]), int(matches[2]) - 1, int(matches[3])); 
    d.setUTCHours(int(matches[4]), int(matches[5]), int(matches[6]), 0); 

    return d; 
} 

Entfernen Sie einfach die Zeit Teil und es sollte für Ihre Bedürfnisse funktionieren:

private function parseDate(str : String) : Date { 
    var matches : Array = str.match(/(\d\d\d\d)-(\d\d)-(\d\d)/); 

    var d : Date = new Date(); 

    d.setUTCFullYear(int(matches[1]), int(matches[2]) - 1, int(matches[3])); 

    return d; 
} 

keine Ahnung von die Geschwindigkeit, darüber habe ich mir in meinen Anwendungen keine Sorgen gemacht. 50K Iterationen in deutlich weniger als einer Sekunde auf meiner Maschine.

+2

Bitte sagen Sie uns, wie lange 50K Iterationen für die 3 Beispielfunktionen benötigt haben, damit wir Ihre "weniger als eine Sekunde" relativieren können. – bzlm

+0

Ich frage mich, ob es eine zusätzliche Leistung geben wird, wenn Sie var Übereinstimmungen und d durch const Schlüsselwort ersetzen. – UnknownJoe

2

Ich vermute, Date.Parse() funktioniert nicht?

+0

nein, es tut! ! –

1

Na dann Methode 2 scheint der beste Weg:

private function castMethod2(dateString:String):Date { 
    if (dateString == null) { 
     return null; 
    } 

    if (dateString.indexOf("0000-00-00") != -1) { 
     return null; 
    } 

    dateString = dateString.split("-").join("/"); 

    return new Date(Date.parse(dateString)); 
} 
5

Das war die schnellste, die ich mit nach einiger Fummelei einfiel:

private function castMethod4(dateString:String):Date {   
    if (dateString == null) 
     return null;  
    if (dateString.length != 10 && dateString.length != 19) 
     return null; 

    dateString = dateString.replace("-", "/"); 
    dateString = dateString.replace("-", "/"); 

    return new Date(Date.parse(dateString)); 
} 

I 470ms für castMethod2 in etwa 50k Iterationen erhalten () auf meinem Computer und 300 ms für meine Version (das ist die gleiche Menge an Arbeit in 63% der Zeit getan). Ich würde definitiv sagen, beide sind "gut genug", es sei denn, Sie analysieren dumme Mengen von Daten.

1

Da Date.parse() nicht alle möglichen Formate annehmen, können wir vorformatieren können den übergebenen Wert mit datestring DateFormatter mit format dass Data.parse() verstehen, z

// English formatter 
var stringValue = "2010.10.06" 
var dateCommonFormatter : DateFormatter = new DateFormatter(); 
dateCommonFormatter.formatString = "YYYY/MM/DD"; 

var formattedStringValue : String = dateCommonFormatter.format(stringValue);         
var dateFromString : Date = new Date(Date.parse(formattedStringValue)); 
+2

Anstatt diese 2 Schritte auszuführen, könnten wir [DateFormatter.parseDateString() '] (http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/formatters/DateFormatter.html#parseDateString verwenden % 28% 29). – approxiblue

0

Hier ist meine Implementierung. Probieren Sie es aus.

public static function dateToUtcTime(date:Date):String { 
    var tmp:Array = new Array(); 
    var char:String; 
    var output:String = ''; 

    // create format YYMMDDhhmmssZ 
    // ensure 2 digits are used for each format entry, so 0x00 suffuxed at each byte 

    tmp.push(date.secondsUTC); 
    tmp.push(date.minutesUTC); 
    tmp.push(date.hoursUTC); 
    tmp.push(date.getUTCDate()); 
    tmp.push(date.getUTCMonth() + 1); // months 0-11 
    tmp.push(date.getUTCFullYear() % 100); 


    for(var i:int=0; i < 6/* 7 items pushed*/; ++i) { 
    char = String(tmp.pop()); 
    trace("char: " + char); 
    if(char.length < 2) 
     output += "0"; 
    output += char; 
    } 

    output += 'Z'; 

    return output; 
} 
1
var strDate:String = "2013-01-24 01:02:40"; 

function dateParser(s:String):Date{ 
    var regexp:RegExp = /(\d{4})\-(\d{1,2})\-(\d{1,2}) (\d{2})\:(\d{2})\:(\d{2})/; 
    var _result:Object = regexp.exec(s); 

    return new Date(
     parseInt(_result[1]), 
     parseInt(_result[2])-1, 
     parseInt(_result[3]), 
     parseInt(_result[4]), 
     parseInt(_result[5]), 
     parseInt(_result[6]) 
    ); 
} 

var myDate:Date = dateParser(strDate);