javascript中的日期解析在safari和chrome之间是不同的

javascript中的日期解析在safari和chrome之间是不同的,javascript,parsing,date,google-chrome,safari,Javascript,Parsing,Date,Google Chrome,Safari,我有以下代码 var c = new Date(Date.parse("2011-06-21T14:27:28.593Z")); console.log(c); 在Chrome上,它可以在控制台上正确打印日期。狩猎 它失败了。谁是正确的,更重要的是什么是最好的方法 要处理这个问题?您不能真正使用Date.parse。我建议您使用:新日期(年、月[、日期[、小时[、分钟[、秒[、毫秒]]]) 要拆分字符串,可以尝试 var s = '2011-06-21T14:27:28.593Z'; var

我有以下代码

var c = new Date(Date.parse("2011-06-21T14:27:28.593Z"));
console.log(c);
在Chrome上,它可以在控制台上正确打印日期。狩猎 它失败了。谁是正确的,更重要的是什么是最好的方法
要处理这个问题?

您不能真正使用Date.parse。我建议您使用:
新日期(年、月[、日期[、小时[、分钟[、秒[、毫秒]]])

要拆分字符串,可以尝试

var s = '2011-06-21T14:27:28.593Z';
var a = s.split(/[^0-9]/);
//for (i=0;i<a.length;i++) { alert(a[i]); }
var d=new Date (a[0],a[1]-1,a[2],a[3],a[4],a[5] );
alert(s+ " "+d);
var s='2011-06-21T14:27:28.593Z';
var a=s.split(/[^0-9]/);

//对于(i=0;i我已经在多个浏览器中检查过它,是的,safari返回
无效日期
。顺便说一下,您不必使用
日期。在这里解析
,只需
新日期([datestring])
也可以。Safari显然需要对您提供的日期字符串进行更多格式设置。如果将“-”替换为“/”,删除T和点(.593Z)后的所有内容,它将为您提供一个有效的日期。此代码已在Safari中测试并可用

var datestr = '2011-06-21T14:27:28.593Z'.split(/[-T.]/);
var safdat = new Date( datestr.slice(0,3).join('/')+' '+datestr[3] );
或使用
字符串。替换(…)


我最终使用了一个库来抵消这一点:

包含该库后,您可以使用以下代码创建新日期:

var date = new Date(Date.parse(datestring));

我们的项目没有使用毫秒说明符,但我不认为这会给您带来问题。

我倾向于避免使用日期。根据这个问题的其他答案,解析日期。它似乎不是可靠处理日期的可移植方式

相反,我使用了如下函数:使用jQuery将字符串数组映射成一个数字数组,但这是一个非常简单的删除/更改依赖项。我还包括了我认为的合理缺省值,允许您使用相同的函数解析<代码> 2007—01-09 和<代码> 2007—01-09T09:42OW/COD>。

function dateFromString(str) {
  var a = $.map(str.split(/[^0-9]/), function(s) { return parseInt(s, 10) });
  return new Date(a[0], a[1]-1 || 0, a[2] || 1, a[3] || 0, a[4] || 0, a[5] || 0, a[6] || 0);
}

我试图通过截短日期并像那样解析它来转换日期,它在safari和ios上运行良好

var dateString = "2016-01-22T08:18:10.000+0000";
 var hours = parseInt(dateString.split("+")[1].substr("0","2"));
 var mins = parseInt(dateString.split("+")[1].substr("2"));
 var date = new Date(dateString.split("+")[0]);
 date.setHours(date.getHours()-hours);
 date.setMinutes(date.getMinutes()-mins);

我使用以下函数解析带有时区的日期。Chrome和Safari都可以正常工作:

函数解析日期(日期){
const parsed=Date.parse(日期);
如果(!isNaN(已解析)){
返回解析;
}
返回Date.parse(Date.replace(/-/g,“/”).replace(/[a-z]+/gi,”);
}

console.log(parseDate('2017-02-09T13:22:18+0300');/1486635738000毫秒时间
我的类似问题是由Safari不知道如何读取RFC 822时区格式的时区引起的。我可以通过使用ISO 8601格式来解决这个问题。如果您可以控制日期格式,我可以使用java的SimpleDataFormat来解决这个问题“yyyy-MM-dd'HH:MM:ss.sssXXX”为我生成,即“2018-02-06T20:00:00.000+04:00”。无论出于何种原因,Safari无法读取“2018-02-06T20:00:00.000+0400”,请注意时区格式中缺少冒号

// Works
var c = new Date("2018-02-06T20:00:00.000+04:00"));
console.log(c);

// Doesn't work
var c = new Date("2018-02-06T20:00:00.000+0400"));
console.log(c);

您可以添加本地客户端时区偏移量,而不是在日期字符串末尾使用“Z”。您可能需要一个方法来为您生成该偏移量:

let timezoneOffset = () => {
    let date = new Date(),
        timezoneOffset = date.getTimezoneOffset(),
        hours = ('00' + Math.floor(Math.abs(timezoneOffset/60))).slice(-2),
        minutes = ('00' + Math.abs(timezoneOffset%60)).slice(-2),
        string = (timezoneOffset >= 0 ? '-' : '+') + hours + ':' + minutes;
    return string;
}
因此,最终结果将是:


var c=newdate(“2011-06-21T14:27:28.593”+timezoneOffset());

这是一个比其他人发布的更健壮的ISO 8601解析器。它不处理星期格式,但应该在所有浏览器中一致地处理所有其他有效的ISO 8601日期

函数newDate(值){
(3)以下:(:::(0[1-1-9]1[1-1-9]1[0-1-9]1[0-0-2]1[0-2-0-0-2])((((::::-(((:::::((::::((([12[12]3[12]3 \124;[121240[1-9]0[1-9]0[1-1-1-1[1-9]1-9]1-1[1-9]1[1[1-9]1[1-9]1[1-9]1[1[1-9]1[1-9]1-1[1[1[1[1-9]1[1[1-9]3[1-3[1[1[1[1[1[1[1[1-3[1[1[1[1[1[1[1[1[1[1[1[-](?:[01]\d | 2[0-3]):?([0-5]\d)?)?)?$/)|[];
var结果=新日期(字段[1],字段[2]-1 | 0,字段[3]| 1,字段[4]| 0,字段[5]| 0,字段[7]| 0,字段[8]| 0)
如果(字段[9]){
result.setUTCMinutes(result.getUTCMinutes()-result.getTimezoneOffset()-((字段[10]*60++字段[11])| | 0));
}
返回结果;
}
控制台日志(newDate('2011-06-21T14:27:28.593Z');
控制台日志(newDate('1970-12-31T06:00Z');

console.log(newDate('1970-12-31T06:00-1200');
不使用第三方库,这是我的-相对简单的-解决方案:

函数parseDateTime(日期时间,时区){
base=新日期(datetime.replace(/\s+/g,'T')+'Z');
hoursUTC=base.toLocaleTimeString('de-AT',{timeZone:'UTC'}).split(':')[0];
hoursLocal=base.toLocaleTimeString('de-AT',{timeZone:'Europe/Vienna'}).split(':')[0];
timeZoneOffsetSign=(hoursLocal hoursUTC)<0?'-':“+”;
timeZoneOffset=Math.abs(小时本地小时UTC);
timeZoneOffset=timeZoneOffsetSign+timeZoneOffset.toString();
返回新日期(datetime.replace(/\s+/g,'T')+时区偏移);
}
localDate=parseDateTime('2020-02-25 16:00:00','Europe/Vienna');
log(localDate);
console.log(localDate.tolocalString('de-AT','Europe/Vienna'));
将此用于两者(Safari/Chrome):


他们都给我
2011年6月21日星期二10:27:28 GMT-0400(东部夏令时)
你确定。在safari版本5.0.4(6533.20.27)上运行会在控制台中给我一个“无效日期”的输出。为什么要创建两次日期对象?正确的定义是什么?你可以使用'date.toISOString()'方法。但请注意:较旧的浏览器不支持该方法。Javascript日期支持2个时区,UTC和操作系统中的本地时区。您无法确定本地时区设置是否正确。由于Javascript是客户端,您无法真正相信它做了任何正确的事情,甚至无法解析日期。任何关键应用程序的计算都应该完成服务器端。@Erik评论不错,浏览器中的日期非常不可靠。在
新日期(Date.parse(string))
中使用Date.parse是多余的,因为如果使用字符串调用,它将传递给Date.parse。此外,Safari在创建日期方面存在一些错误,这些错误很难(如果不是不可能的话)解决方法。这些日期字符串来自服务器。如果您有办法将它们解析为单独的组件,我将非常高兴听到。我将使用split funktion:date.parse,这是我刚刚用旧safari发现的,谢谢您的回复
let timezoneOffset = () => {
    let date = new Date(),
        timezoneOffset = date.getTimezoneOffset(),
        hours = ('00' + Math.floor(Math.abs(timezoneOffset/60))).slice(-2),
        minutes = ('00' + Math.abs(timezoneOffset%60)).slice(-2),
        string = (timezoneOffset >= 0 ? '-' : '+') + hours + ':' + minutes;
    return string;
}
Date.parse("2018-02-06T20:00:00.000-03:00")