Javascript Safari 中的日期无效

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4310953/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 11:50:45  来源:igfitidea点击:

Invalid date in safari

javascriptdatesafari

提问by Shrinath

 alert(new Date('2010-11-29'));

chrome, ff doesn't have problems with this, but safari cries "invalid date". Why ?

chrome,ff 对此没有问题,但是 safari 会喊“无效日期”。为什么 ?

edit : ok, as per the comments below, I used string parsing and tried this :

编辑:好的,根据下面的评论,我使用字符串解析并尝试了这个:

alert(new Date('11-29-2010')); //doesn't work in safari
alert(new Date('29-11-2010')); //doesn't work in safari
alert(new Date('2010-29-11')); //doesn't work in safari

edit Mar 22 2018: Seems like people are still landing here - Today, I would use momentor date-fnsand be done with it. Date-fns is very much pain free and light as well.

2018 年 3 月 22 日编辑:似乎人们仍然在这里登陆 - 今天,我会使用momentdate-fns完成它。Date-fns 也非常无痛且轻便。

回答by Elzo Valugi

For me implementing a new library just because Safari cannot do it correctly is too much and a regex is overkill. Here is the oneliner:

对我来说,仅仅因为 Safari 无法正确执行新库而实施新库太多了,而正则表达式太过分了。这是oneliner

console.log (new Date('2011-04-12'.replace(/-/g, "/")));

回答by darioo

The pattern yyyy-MM-ddisn't an officially supported format for Dateconstructor. Firefox seems to support it, but don't count on other browsers doing the same.

该模式yyyy-MM-dd不是Date构造函数的官方支持格式。Firefox 似乎支持它,但不要指望其他浏览器也会这样做。

Here are some of supported strings, taken from this site:

以下是一些受支持的字符串,取自该站点

  • MM-dd-yyyy
  • yyyy/MM/dd
  • MM/dd/yyyy
  • MMMM dd, yyyy
  • MMM dd, yyyy
  • MM-dd-yyyy
  • 年年/月/日
  • 月/日/年
  • MMMM dd, yyyy
  • MMM dd, yyyy

DateJSseems like a good library for parsing non standard date formats.

DateJS似乎是解析非标准日期格式的好库。

Edit: just checked ECMA-262 standard. Quoting from section 15.9.1.15:

编辑:刚刚检查了ECMA-262 标准。引自第 15.9.1.15 节:

Date Time String Format

日期时间字符串格式

ECMAScript defines a string interchange format for date-times based upon a simplification of the ISO 8601 Extended Format. The format is as follows: YYYY-MM-DDTHH:mm:ss.sssZ Where the fields are as follows:

  • YYYY is the decimal digits of the year in the Gregorian calendar.
  • "-" (hyphon) appears literally twice in the string.
  • MM is the month of the year from 01 (January) to 12 (December).
  • DD is the day of the month from 01 to 31.
  • "T" appears literally in the string, to indicate the beginning of the time element.
  • HH is the number of complete hours that have passed since midnight as two decimal digits.
  • ":" (colon) appears literally twice in the string.
  • mm is the number of complete minutes since the start of the hour as two decimal digits.
  • ss is the number of complete seconds since the start of the minute as two decimal digits.
  • "." (dot) appears literally in the string.
  • sss is the number of complete milliseconds since the start of the second as three decimal digits. Both the "." and the milliseconds field may be omitted.
  • Z is the time zone offset specified as "Z" (for UTC) or either "+" or "-" followed by a time expression hh:mm

This format includes date-only forms:

  • YYYY
  • YYYY-MM
  • YYYY-MM-DD

It also includes time-only forms with an optional time zone offset appended:

  • THH:mm
  • THH:mm:ss
  • THH:mm:ss.sss

Also included are "date-times" which may be any combination of the above.

ECMAScript 基于 ISO 8601 扩展格式的简化定义了日期时间的字符串交换格式。格式如下: YYYY-MM-DDTHH:mm:ss.sssZ 其中字段如下:

  • YYYY 是公历中年份的十进制数字。
  • “-”(连字符)在字符串中出现两次。
  • MM 是一年中从 01(一月)到 12(十二月)的月份。
  • DD 是从 01 到 31 的月份中的第几天。
  • “T”字面出现在字符串中,表示时间元素的开始。
  • HH 是自午夜以来经过的完整小时数,以两位十进制数字表示。
  • “:”(冒号)在字符串中出现两次。
  • mm 是从一小时开始算起的完整分钟数,以两位十进制数字表示。
  • ss 是自分钟开始以来的完整秒数,为两位十进制数字。
  • “。” (点)字面出现在字符串中。
  • sss 是从秒开始的完整毫秒数,以三位十进制数字表示。这俩 ”。” 毫秒字段可以省略。
  • Z 是指定为“Z”(对于 UTC)或“+”或“-”后跟时间表达式 hh:mm 的时区偏移量

此格式包括仅日期格式:

  • YYYY
  • YYYY-MM
  • YYYY-MM-DD

它还包括带有可选时区偏移量的仅时间形式:

  • 高:毫米
  • 高:毫米:秒
  • THH:mm:ss.sss

还包括“日期时间”,它可以是上述的任意组合。

So, it seems that YYYY-MM-DD is included in the standard, but for some reason, Safari doesn't support it.

因此,似乎 YYYY-MM-DD 包含在标准中,但出于某种原因,Safari 不支持它。

Update: after looking at datejs documentation, using it, your problem should be solved using code like this:

更新:在查看datejs 文档后,使用它,您的问题应该使用如下代码解决:

var myDate1 = Date.parseExact("29-11-2010", "dd-MM-yyyy");
var myDate2 = Date.parseExact("11-29-2010", "MM-dd-yyyy");
var myDate3 = Date.parseExact("2010-11-29", "yyyy-MM-dd");
var myDate4 = Date.parseExact("2010-29-11", "yyyy-dd-MM");

回答by nizantz

I was facing a similar issue. Date.Parse("DATESTRING")was working on Chrome (Version 59.0.3071.115 ) but not of Safari (Version 10.1.1 (11603.2.5) )

我面临着类似的问题。Date.Parse("DATESTRING")正在使用 Chrome(版本 59.0.3071.115 )而不是 Safari(版本 10.1.1 (11603.2.5) )

Safari:

苹果浏览器:

Date.parse("2017-01-22 11:57:00")
NaN

Chrome:

铬合金:

Date.parse("2017-01-22 11:57:00")
1485115020000

The solution that worked for me was replacing the space in the dateString with "T". ( example : dateString.replace(/ /g,"T"))

对我有用的解决方案是用"T". (例如:dateString.replace(/ /g,"T")

Safari:

苹果浏览器:

Date.parse("2017-01-22T11:57:00")
1485086220000

Chrome:

铬合金:

Date.parse("2017-01-22T11:57:00")
1485115020000

Note that the response from Safari browser is 8hrs (28800000ms) less than the response seen in Chrome browser because Safari returned the response in local TZ (which is 8hrs behind UTC)

请注意,来自 Safari 浏览器的响应比在 Chrome 浏览器中看到的响应少 8 小时(28800000 毫秒),因为 Safari 在本地 TZ 中返回响应(比 UTC 晚 8 小时)

To get both the times in same TZ

在同一个 TZ 中获得两个时间

Safari:

苹果浏览器:

Date.parse("2017-01-22T11:57:00Z")
1485086220000

Chrome:

铬合金:

Date.parse("2017-01-22T11:57:00Z")
1485086220000

回答by liwp_Stephen

I use moment to solve the problem. For example

我用 moment 来解决问题。例如

var startDate = moment('2015-07-06 08:00', 'YYYY-MM-DD HH:mm').toDate();

回答by Luxx

To have a solution working on most browsers, you should create your date-object with this format

要获得适用于大多数浏览器的解决方案,您应该使用这种格式创建日期对象

(year, month, date, hours, minutes, seconds, ms)

e.g.:

例如:

dateObj = new Date(2014, 6, 25); //UTC time / Months are mapped from 0 to 11
alert(dateObj.getTime()); //gives back timestamp in ms

works fine with IE, FF, Chrome and Safari. Even older versions.

适用于 IE、FF、Chrome 和 Safari。甚至旧版本。

IE Dev Center: Date Object (JavaScript)

IE 开发中心:日期对象 (JavaScript)

Mozilla Dev Network: Date

Mozilla 开发网络:日期

回答by Anja Ishmukhametova

convert string to Date fromat (you have to know server timezone)

将字符串转换为日期 fromat(您必须知道服务器时区)

new Date('2015-06-16 11:00:00'.replace(/\s+/g, 'T').concat('.000+08:00')).getTime()  

where +08:00 = timeZone from server

其中 +08:00 = 来自服务器的时区

回答by Sampath

I had the same issue.Then I used moment.Js.Problem has vanished.

我有同样的问题。然后我使用了moment.Js .Problem消失了。

When creating a moment from a string, we first check if the string matches known ISO 8601 formats, then fall back to new Date(string) if a known format is not found.

Warning: Browser support for parsing strings is inconsistent. Because there is no specification on which formats should be supported, what works in some browsers will not work in other browsers.

For consistent results parsing anything other than ISO 8601 strings, you should use String + Format.

从字符串创建时刻时,我们首先检查字符串是否与已知的 ISO 8601 格式匹配,如果未找到已知格式,则回退到 new Date(string)。

警告:浏览器对解析字符串的支持不一致。因为没有关于应该支持哪些格式的规范,所以在某些浏览器中有效的方法在其他浏览器中无效。

对于解析除 ISO 8601 字符串以外的任何内容的一致结果,您应该使用字符串 + 格式。

e.g.

例如

var date= moment(String);

回答by Phrogz

Though you might hope that browsers would support ISO 8601(or date-only subsets thereof), this is not the case. All browsers that I know of (at least in the US/English locales I use) are able to parse the horrible US MM/DD/YYYYformat.

尽管您可能希望浏览器支持ISO 8601(或其中仅包含日期的子集),但事实并非如此。我知道的所有浏览器(至少在我使用的美国/英语语言环境中)都能够解析可怕的美国MM/DD/YYYY格式。

If you already have the parts of the date, you might instead want to try using Date.UTC(). If you don't, but you must use the YYYY-MM-DDformat, I suggest using a regular expression to parse the pieces you know and then pass them to Date.UTC().

如果您已经拥有日期的各个部分,您可能想尝试使用Date.UTC()。如果你不知道,但你必须使用YYYY-MM-DD格式,我建议使用正则表达式来解析你知道的部分,然后将它们传递给Date.UTC().

回答by Abhay Aradhya

Use the below format, it would work on all the browsers

使用以下格式,它适用于所有浏览器

var year = 2016;
var month = 02;           // month varies from 0-11 (Jan-Dec)
var day = 23;

month = month<10?"0"+month:month;        // to ensure YYYY-MM-DD format
day = day<10?"0"+day:day;

dateObj = new Date(year+"-"+month+"-"+day);

alert(dateObj); 

//Your output would look like this "Wed Mar 23 2016 00:00:00 GMT+0530 (IST)"

//您的输出将如下所示“Wed Mar 23 2016 00:00:00 GMT+0530 (IST)”

//Note this would be in the current timezone in this case denoted by IST, to convert to UTC timezone you can include

//注意这将在当前时区中,在这种情况下由 IST 表示,要转换为 UTC 时区,您可以包括

alert(dateObj.toUTCSting);

//Your output now would like this "Tue, 22 Mar 2016 18:30:00 GMT"

//您现在的输出是“2016 年 3 月 22 日星期二 18:30:00 GMT”

Note that now the dateObj shows the time in GMT format, also note that the date and time have been changed correspondingly.

请注意,现在 dateObj 以 GMT 格式显示时间,还要注意日期和时间已相应更改。

The "toUTCSting" function retrieves the corresponding time at the Greenwich meridian. This it accomplishes by establishing the time difference between your current timezone to the Greenwich Meridian timezone.

“toUTCSting”函数检索格林威治子午线的相应时间。这是通过建立您当前时区与格林威治子午线时区之间的时差来实现的。

In the above case the time before conversion was 00:00 hours and minutes on the 23rd of March in the year 2016. And after conversion from GMT+0530 (IST) hours to GMT (it basically subtracts 5.30 hours from the given timestamp in this case) the time reflects 18.30 hours on the 22nd of March in the year 2016 (exactly 5.30 hours behind the first time).

在上述情况下,转换前的时间是 2016 年 3 月 23 日的 00:00 小时和分钟。并且在从 GMT+0530 (IST) 小时转换为 GMT 之后(它基本上从给定的时间戳中减去 5.30 小时)案例)时间反映了 2016 年 3 月 22 日的 18.30 小时(正好比第一次晚 5.30 小时)。

Further to convert any date object to timestamp you can use

进一步将任何日期对象转换为时间戳,您可以使用

alert(dateObj.getTime());

//output would look something similar to this "1458671400000"

//输出看起来类似于“1458671400000”

This would give you the unique timestamp of the time

这将为您提供时间的唯一时间戳

回答by kenberkeley

How about hiHyman Datewith fix-date? No dependencies, min + gzip = 280 B

如何劫持Date修复最新的?无依赖,min + gzip = 280 B