javascript中的日期解析在safari和chrome中有所不同
Date parsing in javascript is different between safari and chrome
我有以下代码
var c = new Date(Date.parse("2011-06-21T14:27:28.593Z"));
console.log(c);
在Chrome上,它会在控制台上正确地打印出日期。在Safari中它失败了。谁是正确的,更重要的是什么是最好的方法处理这个?
您不能真正使用Date.parse。我建议您使用:new Date (year, month [, date [, hours [, minutes [, seconds [, ms ] ] ] ] ] )
要拆分字符串,您可以尝试
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);
我的类似问题是由Safari不知道如何读取RFC 822时区格式的时区引起的。我能够通过使用ISO8601格式来解决这个问题。如果你可以控制日期格式,我使用java的SimpleDateFormat"yyyy-MM-dd’TH:MM:ss.sssXXX"获得了这个,它为我生成了"2018-02-06T2:00:00.000+04:00"。无论出于什么原因,Safari都无法读取"2018-0206T2:00:0.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);
根据这个问题的其他答案,我倾向于避免Date.parse
。这似乎不是一种可靠处理日期的便携方式。
相反,我使用了类似下面的函数。这使用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);
}
我在几个浏览器中检查过它,是的,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] );
或使用String.replace(...)
:
new Date("2016-02-17T00:05:01+0000".replace(/-/g,'/').replace('T',' ').replace(/('..*|'+.*/,""))
我使用以下函数来解析带时区的日期。适用于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
我最终使用了一个库来抵消这一点:
http://zetafleet.com/blog/javascript-dateparse-for-iso-8601
一旦该库包含在内,您就可以使用此代码创建新日期:
var date = new Date(Date.parse(datestring));
我们的项目没有使用毫秒说明符,但我不认为这会给您带来问题。
您可以添加本地客户端时区偏移量,而不是在日期字符串的末尾使用"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 = new Date("2011-06-21T14:27:28.593" + timezoneOffset());
这里有一个比其他人发布的更健壮的ISO8601解析器。它不处理周格式,但它应该在所有浏览器中一致地处理所有其他有效的ISO8601日期。
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'));
两者都使用(Safari/Chrome):
Date.parse("2018-02-06T20:00:00.000-03:00")
我尝试通过截断日期并像这样解析它来转换日期,它在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);
这不是使用第三方库,而是我的相对简单的解决方案:
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'));
- 在Safari执行javascript之前对其进行修改
- Safari(Mac OS)上的jQuery平滑滚动问题
- $(document).height()在刷新时随机化值(Safari 5.1.10)
- jQuery Datepicker可以在Safari中工作,但不能在FF或Chrome中工作
- document.applet.method在Mounatin Lion上抛出safari 6+JDK7异常
- 主干网.与Safari同步问题
- jQuery表单验证适用于Mozilla和Internet Explorer,但不适用于Chrome或Safari
- 以编程方式选择文本Mobile Safari
- onbeforeunload和asp:Safari和FireFox中的更新面板
- 为什么我的JavaScript在Safari上的严格模式下不能正常工作
- 防止在移动Safari(iPad/iPhone)中长按/长按默认上下文菜单
- 如何在关闭窗口之前在Safari扩展中捕获窗口关闭
- safari扩展中的重定向url
- JS代码在jsbin中有效,在jsfiddle或Chrome/Safari中无效
- SQLite插件适用于Mac和Windows,但不适用于手机上的Safari
- window.open(url).print()在Safari中不起作用
- 无法在Safari中加载跨源映像(来自CloudFront)
- iOS Safari Javascript设置超时问题
- Safari扩展中的注入脚本;不要在Youtube上开火
- javascript中的日期解析在safari和chrome中有所不同