我有以下代码
var c = new Date(Date.parse("2011-06-21T14:27:28.593Z"));
console.log(c);
在 Chrome 上,它会在控制台上正确打印出日期。在 Safari 中它失败了。谁是正确的,更重要的是,处理这个问题的最佳方法是什么?
Tue Jun 21 2011 10:27:28 GMT-0400 (Eastern Daylight Time)
new Date(Date.parse(string))
中使用 Date.parse 是多余的,因为如果使用字符串调用 Date constructor,它无论如何都会传递给 Date.parse。此外,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 时区格式读取时区。我能够通过使用 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);
The UTC offset is appended to the time in the same way that 'Z' was above, in the form ±[hh]:[mm], ±[hh][mm], or ±[hh].
实际上,Chrome & Firefox 能够解析没有冒号的偏移量
new Date("2020-04-16T20:00+04:00"))
也适用于各种浏览器(Chrome、Firefox、Safari、Edge)。
根据此问题的其他答案,我倾向于避免 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(/(\..*|\+.*/,""))
new Date("2016-02-17T00:05:01+0000".replace(/-/g,'/').replace('T',' ').replace(/\..*|\+.*/,""))
.replace(/-/g,'/')
即可。我的日期字符串是这样的“2019-06-26 23:59:59”
我使用以下函数来解析带有时区的日期。 Chrome 和 Safari 都可以正常工作:
函数 parseDate(date) { const parsed = Date.parse(date); if (!isNaN(parsed)) { 返回已解析; } return Date.parse(date.replace(/-/g, '/').replace(/[az]+/gi, ' ')); } console.log(parseDate('2017-02-09T13:22:18+0300')); // 1486635738000 毫秒
/[a-z]+/gi
之类的内容,以匹配更广泛的受众,例如使用 UTC 而不是仅 T 的日期。
我最终使用了一个库来抵消这一点:
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());
这是一个比其他人发布的更强大的 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)) ; } 返回结果; } 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 和 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);
将其用于两者(Safari / Chrome):
Date.parse("2018-02-06T20:00:00.000-03:00")
这是我的 - 相对简单的 - 解决方案,而不是使用 3rd 方库:
函数 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','欧洲/维也纳');控制台.log(localDate); console.log(localDate.toLocaleString('de-AT','Europe/Vienna'));