Actionscript 3 - Fastest way to parse yyyy-mm-dd hh:mm:ss to a Date object?

33,031

Solution 1

I've been using the following snipplet to parse UTC date strings:

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;
}

Just remove the time part and it should work fine for your needs:

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;
}

No idea about the speed, I haven't been worried about that in my applications. 50K iterations in significantly less than a second on my machine.

Solution 2

This was the fastest I could come up with after some fiddling:

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 get 50k iterations in about 470ms for castMethod2() on my computer and 300 ms for my version (that's the same amount of work done in 63% of the time). I'd definitely say both are "Good enough" unless you're parsing silly amounts of dates.

Solution 3

I'm guessing Date.Parse() doesn't work?

Solution 4

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);

Solution 5

Well then method 2 seems the best way:

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 ));
}
Share:
33,031
Matt MacLean
Author by

Matt MacLean

Working backwards to achieve customer outcomes.

Updated on December 16, 2020

Comments

  • Matt MacLean
    Matt MacLean over 3 years

    I have been trying to find a really fast way to parse yyyy-mm-dd [hh:mm:ss] into a Date object. Here are the 3 ways I have tried doing it and the times it takes each method to parse 50,000 date time strings.

    Does anyone know any faster ways of doing this or tips to speed up the methods?

    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]:" ") ) );
    }
    

    No, Date.parse will not handle dashes by default. And I need to return null for date time strings like "0000-00-00".