JavaScriptで特定の日時のDateオブジェクトのインスタンスを生成する方法には、いくつかあって、以下のように文字列を入れたり、年・月・日...を数値として渡す方法などがある。
new Date('December 17, 1995 03:24:00');
new Date(1995, 11, 17, 3, 24, 0);
しかしながら、文字列を渡してインスタンスを生成する場合罠があって、例えば以下のようなフォーマットの場合、ChromeやFirefoxなら正常にインスタンス生成できても、Safariだとエラーになるということがある。
new Date('2019-11-08 11:25')
// Firefox → Date Fri Nov 08 2019 11:25:00 GMT+0900 (日本標準時)
// Chrome → Fri Nov 08 2019 11:25:00 GMT+0900 (日本標準時)
// Safari → Invalid Date
以上から、文字列から直接Dateオブジェクトのインスタンスを生成するのは危険なので、文字列をパースして、new Date(yyyy,MM,dd,HH,mm,ss,SSS)
の形式で生成してくれるラッパーを作成した。
function constructDate (datetimeString, format){
function extract(datetimeString, expression){
var start = format.search(expression);
if(start < 0){
return '';
}
var extracted = datetimeString.substr(start, expression.length);
if(expression !== 'MM'){
return datetimeString.substr(start, expression.length);
} else{
var month = Number(extracted) - 1;
return ('0' + month).slice(-2);
}
}
var dt ={
yyyy: extract(datetimeString, 'yyyy'),
MM: extract(datetimeString, 'MM'),
dd: extract(datetimeString, 'dd'),
HH: extract(datetimeString, 'HH'),
mm: extract(datetimeString, 'mm'),
ss: extract(datetimeString, 'ss'),
SSS: extract(datetimeString, 'SSS')
};
var constructCommand = 'new Date(';
for(var key in dt){
if(dt[key] !== ''){
constructCommand += dt[key] + ',';
}
}
constructCommand +=')';
return eval(constructCommand);
};
// 使用例
constructDate('2019-11-26 11:25:39', "yyyy-MM-dd HH:mm:ss")
// Date Tue Nov 26 2019 11:25:00 GMT+0900 (日本標準時)
constructDate('2019/11/26 11:25', "yyyy-MM-dd HH:mm")
// Date Tue Nov 26 2019 11:25:39 GMT+0900 (日本標準時)
constructDate('20191126', 'yyyyMMdd')
// Date Tue Nov 26 2019 00:00:00 GMT+0900 (日本標準時)
おそらくN番煎じかつ、適切なライブラリを使えば解決できそうな気もするけど、参考になれば。