javascript 中的日期解析在 safari 和 chrome 之间是不同的
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6427204/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Date parsing in javascript is different between safari and chrome
提问by bradgonesurfing
I have the following code
我有以下代码
var c = new Date(Date.parse("2011-06-21T14:27:28.593Z"));
console.log(c);
On Chrome it correctly prints out the date on the console. In Safari it fails. Who is correct and more importantly what is the best way to handle this?
在 Chrome 上,它会在控制台上正确打印日期。在 Safari 中它失败了。谁是正确的,更重要的是处理这个问题的最佳方法是什么?
回答by Erik
You can't really use Date.parse. I suggest you use: new Date (year, month [, date [, hours [, minutes [, seconds [, ms ] ] ] ] ] )
你不能真正使用 Date.parse。我建议你使用: new Date (year, month [, date [, hours [, minutes [, seconds [, ms ] ] ] ] ] )
To split the string you could try
要拆分字符串,您可以尝试
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);
回答by Olmstov
My similar issue was caused by Safari not knowing how to read the timezone in a RFC 822 time zone format. I was able to fix this by using the ISO 8601 format. If you have control of the date format I got this working with java's SimpleDateFormat "yyyy-MM-dd'T'HH:mm:ss.sssXXX" which produces for me ie. "2018-02-06T20:00:00.000+04:00". For whatever reason Safari can't read "2018-02-06T20:00:00.000+0400", notice the lack of colon in the timezone format.
我的类似问题是由 Safari 不知道如何以 RFC 822 时区格式读取时区造成的。我能够通过使用 ISO 8601 格式来解决这个问题。如果您可以控制日期格式,我可以使用 java 的 SimpleDateFormat "yyyy-MM-dd'T'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);
回答by jabley
I tend to avoid Date.parse
, as per the other answers for this question. It doesn't seem to be a portable way to reliably deal with dates.
Date.parse
根据这个问题的其他答案,我倾向于避免。它似乎不是可靠处理日期的可移植方式。
Instead, I have used something like the function below. This uses jQuery to map the string array into a number array, but that's a pretty easy dependency to remove / change. I also include what I consider sensible defaults, to allow you to parse 2007-01-09
and 2007-01-09T09:42:00
using the same function.
相反,我使用了类似下面的函数。这使用 jQuery 将字符串数组映射到数字数组,但这是一个非常容易删除/更改的依赖项。我还包括我认为合理的默认值,以允许您解析2007-01-09
和2007-01-09T09:42:00
使用相同的函数。
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);
}
回答by KooiInc
I've checked it in several browsers, and yes, safari returns invalid date
. By the way, you don't have to use Date.parse
here, just new Date([datestring])
will work too. Safari evidently requires more formatting of the datestring you supply. If you replace '-' with '/', remove the T and everything after the dot (.593Z), it will give you a valid date. This code is tested and works in Safari
我在几个浏览器中检查过,是的,safari 返回invalid date
. 顺便说一句,您不必Date.parse
在这里使用,也可以使用new Date([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] );
Or using String.replace(...)
:
或使用String.replace(...)
:
new Date("2016-02-17T00:05:01+0000".replace(/-/g,'/').replace('T',' ').replace(/(\..*|\+.*/,""))
回答by Londeren
I use the following function for parsing dates with timezone. Works fine both Chrome and Safari:
我使用以下函数来解析带时区的日期。Chrome 和 Safari 都可以正常工作:
function parseDate(date) {
const parsed = Date.parse(date);
if (!isNaN(parsed)) {
return parsed;
}
return Date.parse(date.replace(/-/g, '/').replace(/[a-z]+/gi, ' '));
}
console.log(parseDate('2017-02-09T13:22:18+0300')); // 1486635738000 time in ms
回答by AaronSieb
I ended up using a library to offset this:
我最终使用一个库来抵消这一点:
http://zetafleet.com/blog/javascript-dateparse-for-iso-8601
http://zetafleet.com/blog/javascript-dateparse-for-iso-8601
Once that library was included, you use this code to create the new date:
包含该库后,您可以使用此代码创建新日期:
var date = new Date(Date.parse(datestring));
Our project wasn't using millisecond specifiers, but I don't believe that will cause an issue for you.
我们的项目没有使用毫秒说明符,但我认为这不会给您带来问题。
回答by Anky
i tried converted date by truncating it and parsing it like that , its working fine with safari and ios .
我尝试通过截断它并像这样解析它来转换日期,它在 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);
回答by adjwilli
Instead of using 'Z' at the end of the date string, you can add the local client timezone offset. You'll probably want a method to generate that for you:
您可以添加本地客户端时区偏移量,而不是在日期字符串的末尾使用“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;
}
So the end result would be:
所以最终的结果是:
var c = new Date("2011-06-21T14:27:28.593" + timezoneOffset());
var c = new Date("2011-06-21T14:27:28.593" + timezoneOffset());
回答by Adam Leggett
Here is a more robust ISO 8601 parser than what others have posted. It does not handle week format, but it should handle all other valid ISO 8601 dates consistently across all browsers.
这是一个比其他人发布的更强大的 ISO 8601 解析器。它不处理周格式,但它应该在所有浏览器中一致地处理所有其他有效的 ISO 8601 日期。
function newDate(value) {
var field = value.match(/^([+-]?\d{4}(?!\d\d\b))(?:-?(?:(0[1-9]|1[0-2])(?:-?([12]\d|0[1-9]|3[01]))?)(?:[T\s](?:(?:([01]\d|2[0-3])(?::?([0-5]\d))?|24\:?00)([.,]\d+(?!:))?)?(?::?([0-5]\d)(?:[.,](\d+))?)?([zZ]|([+-](?:[01]\d|2[0-3])):?([0-5]\d)?)?)?)?$/) || [];
var result = new Date(field[1], field[2] - 1 | 0, field[3] || 1, field[4] | 0, field[5] | 0, field[7] | 0, field[8] | 0)
if (field[9]) {
result.setUTCMinutes(result.getUTCMinutes() - result.getTimezoneOffset() - ((field[10] * 60 + +field[11]) || 0));
}
return result;
}
console.log(newDate('2011-06-21T14:27:28.593Z'));
console.log(newDate('1970-12-31T06:00Z'));
console.log(newDate('1970-12-31T06:00-1200'));
回答by schnere
Instead of using a 3rd party library, this is my - relatively simple - solution for this:
这是我的 - 相对简单的 - 解决方案,而不是使用 3rd 方库:
function parseDateTime(datetime, timezone) {
base = new Date(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(hoursLocal-hoursUTC);
timeZoneOffset = timeZoneOffsetSign + timeZoneOffset.toString().padStart(2, '0') + ':00';
return new Date(datetime.replace(/\s+/g, 'T') + timeZoneOffset);
}
localDate = parseDateTime('2020-02-25 16:00:00','Europe/Vienna');
console.log(localDate);
console.log(localDate.toLocaleString('de-AT','Europe/Vienna'));