Actionscript 3 - أسرع طريقة لتحليل yyyy-mm-dd hh:mm:ss إلى كائن التاريخ؟

StackOverflow https://stackoverflow.com/questions/3163

  •  08-06-2019
  •  | 
  •  

سؤال

لقد كنت أحاول العثور على طريقة سريعة جدًا لتحليل yyyy-mm-dd [hh:mm:ss] في كائن التاريخ.فيما يلي الطرق الثلاث التي حاولت القيام بها والأوقات التي تستغرقها كل طريقة لتحليل 50000 سلسلة زمنية.

هل يعرف أحد أي طرق أسرع للقيام بذلك أو نصائح لتسريع هذه الطرق؟

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

شفرة:

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

لا، لن يتعامل Date.parse مع الشرطات بشكل افتراضي.وأحتاج إلى إرجاع قيمة فارغة لسلاسل التاريخ والوقت مثل "0000-00-00".

هل كانت مفيدة؟

المحلول

لقد كنت أستخدم المقتطف التالي لتحليل سلاسل تاريخ UTC:

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

ما عليك سوى إزالة الجزء الزمني وسيعمل بشكل جيد مع احتياجاتك:

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

ليس لدي أي فكرة عن السرعة، ولم أقلق بشأن ذلك في طلباتي. 50 ألف تكرار في أقل من ثانية على جهازي.

نصائح أخرى

كان هذا هو أسرع ما يمكنني التوصل إليه بعد بعض العبث:

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

أحصل على 50 ألف تكرار في حوالي 470 مللي ثانية لـ castMethod2() على جهاز الكمبيوتر الخاص بي و300 مللي ثانية للإصدار الخاص بي (وهذا هو نفس مقدار العمل المنجز في 63٪ من الوقت).سأقول بالتأكيد أن كلاهما "جيد بما فيه الكفاية" إلا إذا كنت تقوم بتحليل كميات سخيفة من التواريخ.

أعتقد أن Date.Parse() لا يعمل؟

حسنًا، تبدو الطريقة الثانية هي أفضل طريقة:

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

نظرًا لأن Date.parse() لا يقبل جميع التنسيقات الممكنة، فيمكننا تنسيق قيمة dateString التي تم تمريرها مسبقًا باستخدام DateFormatter مع formatString التي يمكن لـ Data.parse() فهمها، على سبيل المثال

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

هنا هو التنفيذ الخاص بي.جرب هذه.

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;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top