我有一个日期字符串,格式如下:
2012-09-20T01:36:51.556Z
它是从mongodb返回的日期字段。 Chrome,FF和IE都可以解析此字符串,但是,Safari失败并显示错误Invalid Date
。我试过DateJS,但它也无法解析这个日期。任何想法如何轻松解析这个日期?或者,什么特别的东西导致Safari失败?
我正在使用mongodb的本机节点驱动程序。它以上述格式将日期作为字符串返回。
答案 0 :(得分:1)
我的DateExtensions应解析:
http://depressedpress.com/javascript-extensions/dp_dateextensions/
将库添加到页面后,您将使用静态Date.parseIso8601( date )方法解析日期。
这方面的扩展有点沉重(尽管你可以根据需要提取数据解析内容)。
我很惊讶Safari有这样的问题,因为日期对我来说是完全有效的ISO 8601日期(如此定义:http://www.w3.org/TR/NOTE-datetime)。这和日期一样普通。总猜测,但您是否尝试用空格替换“T”分隔符?它不是标准的,但我已经看到很多实现以这种方式使用它(我的组件允许它)。
对于它的价值,这是我从DP_DateExtensions中提取的方法 - 我认为它会为你做到这一点:
// parseIso8601
// Attempts to convert ISO8601 input to a date
Date.parseIso8601 = function(CurDate) {
// Check the input parameters
if ( typeof CurDate != "string" || CurDate == "" ) {
return null;
};
// Set the fragment expressions
var S = "[\\-/:.]";
var Yr = "((?:1[6-9]|[2-9][0-9])[0-9]{2})";
var Mo = S + "((?:1[012])|(?:0[1-9])|[1-9])";
var Dy = S + "((?:3[01])|(?:[12][0-9])|(?:0[1-9])|[1-9])";
var Hr = "(2[0-4]|[01]?[0-9])";
var Mn = S + "([0-5]?[0-9])";
var Sd = "(?:" + S + "([0-5]?[0-9])(?:[.,]([0-9]+))?)?";
var TZ = "(?:(Z)|(?:([\+\-])(1[012]|[0]?[0-9])(?::?([0-5]?[0-9]))?))?";
// RegEx the input
// First check: Just date parts (month and day are optional)
// Second check: Full date plus time (seconds, milliseconds and TimeZone info are optional)
var TF;
if ( TF = new RegExp("^" + Yr + "(?:" + Mo + "(?:" + Dy + ")?)?" + "$").exec(CurDate) ) {} else if ( TF = new RegExp("^" + Yr + Mo + Dy + "[Tt ]" + Hr + Mn + Sd + TZ + "$").exec(CurDate) ) {};
// If the date couldn't be parsed, return null
if ( !TF ) { return null };
// Default the Time Fragments if they're not present
if ( !TF[2] ) { TF[2] = 1 } else { TF[2] = TF[2] - 1 };
if ( !TF[3] ) { TF[3] = 1 };
if ( !TF[4] ) { TF[4] = 0 };
if ( !TF[5] ) { TF[5] = 0 };
if ( !TF[6] ) { TF[6] = 0 };
if ( !TF[7] ) { TF[7] = 0 };
if ( !TF[8] ) { TF[8] = null };
if ( TF[9] != "-" && TF[9] != "+" ) { TF[9] = null };
if ( !TF[10] ) { TF[10] = 0 } else { TF[10] = TF[9] + TF[10] };
if ( !TF[11] ) { TF[11] = 0 } else { TF[11] = TF[9] + TF[11] };
// If there's no timezone info the data is local time
if ( !TF[8] && !TF[9] ) {
return new Date(TF[1], TF[2], TF[3], TF[4], TF[5], TF[6], TF[7]);
};
// If the UTC indicator is set the date is UTC
if ( TF[8] == "Z" ) {
return new Date(Date.UTC(TF[1], TF[2], TF[3], TF[4], TF[5], TF[6], TF[7]));
};
// If the date has a timezone offset
if ( TF[9] == "-" || TF[9] == "+" ) {
// Get current Timezone information
var CurTZ = new Date().getTimezoneOffset();
var CurTZh = TF[10] - ((CurTZ >= 0 ? "-" : "+") + Math.floor(Math.abs(CurTZ) / 60))
var CurTZm = TF[11] - ((CurTZ >= 0 ? "-" : "+") + (Math.abs(CurTZ) % 60))
// Return the date
return new Date(TF[1], TF[2], TF[3], TF[4] - CurTZh, TF[5] - CurTZm, TF[6], TF[7]);
};
// If we've reached here we couldn't deal with the input, return null
return null;
};
我确信你可以创建一个更小,更简化的版本(我的代码编写的更多是为了可维护性而不是紧凑性) - 但这将管理ISO8601日期时间的的最大的数据,并且从未让我失望。 ; ^)
希望这有帮助!
答案 1 :(得分:0)
在将日期发送到客户端之前,我最终将日期转换为服务器端的TimeStamp。 NodeJS(当然,基于Chrome的JavaScript引擎)解析这种格式就好了。
答案 2 :(得分:0)
我遇到了同样的问题,这对我有用:https://github.com/csnover/js-iso8601
它会覆盖Date.parse函数。