Safari中的日期无效

时间:2010-11-30 05:58:18

标签: javascript date safari

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

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

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

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

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

19 个答案:

答案 0 :(得分:179)

对于我实施一个新库只是因为Safari无法正确执行它太多而且正则表达式是过度的。 这是 oneliner

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

答案 1 :(得分:134)

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

以下是一些受支持的字符串,取自this site

  • MM-DD-YYYY
  • YYYY / MM / DD
  • MM / DD / YYYY
  • MMMM dd,yyyy
  • MMM dd,yyyy

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

修改:刚检查ECMA-262 standard。引自第15.9.1.15节:

日期时间字符串格式

  

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

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

此格式包含仅限日期的表格:

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

它还包括仅限时间的表格   附加的可选时区偏移量:

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

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

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

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

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");

答案 2 :(得分:26)

我遇到了类似的问题。 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

铬:

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

对我有用的解决方案是用"T"替换dateString中的空格。 (例如:dateString.replace(/ /g,"T")

Safari浏览器:

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

铬:

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

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

同时获得相同TZ的时间

Safari浏览器:

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

铬:

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

答案 3 :(得分:8)

我用时间来解决问题。 例如

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

答案 4 :(得分:7)

要在大多数浏览器上运行解决方案,您应该使用此格式创建日期对象

(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

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

IE Dev Center: Date Object (JavaScript)

Mozilla Dev Network: Date

答案 5 :(得分:6)

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

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

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

答案 6 :(得分:4)

我遇到了同样的问题。然后我使用了moment.Js。问题已经消失了。

  

从字符串创建片刻时,我们首先检查字符串   匹配已知的ISO 8601格式,然后回退到新的日期(字符串)if   找不到已知的格式。

     

警告:浏览器对解析字符串的支持不一致。因为   没有关于应该支持哪种格式的规范   在某些浏览器中工作不适用于其他浏览器。

     

为了解析除ISO 8601字符串以外的任何内容的一致结果,   你应该使用String + Format。

<强> e.g。

var date= moment(String);

答案 7 :(得分:3)

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

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

答案 8 :(得分:1)

如何用fix-date劫持Date?无依赖关系,min + gzip = 280 B

答案 9 :(得分:1)

迟到派对,但是在我们的案例中,使用ES6倒钩代替String()进行强制转换时,在Safari和iOS中出现了此问题

这是“无效日期”错误

const dateString = '2011-11-18';
const dateObj = new Date(`${dateString}`); 

但这可行

const dateObj = new Date(String(dateString)); 

答案 10 :(得分:1)

最好的方法是使用以下格式:

new Date(year, month, day, hours, minutes, seconds, milliseconds)
var d = new Date(2018, 11, 24, 10, 33, 30, 0);

所有浏览器都支持此功能,不会给您带来任何问题。 请注意,月份写在0到11之间。

答案 11 :(得分:1)

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

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); 

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

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

alert(dateObj.toUTCSting);

//您的输出现在想要“Tue,2016年3月22日18:30:00 GMT”

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

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

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

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

alert(dateObj.getTime());

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

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

答案 12 :(得分:0)

Safari中遇到的同样问题,通过在网页中插入

解决了这个问题
 <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.en"></script> 

希望它也适用于你的情况

由于

答案 13 :(得分:0)

正如@nizantz先前提到的那样,使用Date.parse()在Safari中对我不起作用。经过一些研究,我了解到File对象的lastDateModified属性已被弃用,Safari不再支持。使用File对象的lastModified属性解决了我的问题。当在网上发现错误信息时,一定会不喜欢它。

感谢所有对此帖子做出贡献的人,这些帮助我走了学习我的问题所需要的道路。如果没有此信息,我可能永远也找不到我的根本问题。也许这会帮助我类似情况的其他人。

答案 14 :(得分:0)

我在Safari浏览器中也遇到相同的问题

var date = new Date("2011-02-07");
console.log(date) // IE you get ‘NaN’ returned and in Safari you get ‘Invalid Date’

这里是解决方案:

var d = new Date(2011, 01, 07); // yyyy, mm-1, dd  
var d = new Date(2011, 01, 07, 11, 05, 00); // yyyy, mm-1, dd, hh, mm, ss  
var d = new Date("02/07/2011"); // "mm/dd/yyyy"  
var d = new Date("02/07/2011 11:05:00"); // "mm/dd/yyyy hh:mm:ss"  
var d = new Date(1297076700000); // milliseconds  
var d = new Date("Mon Feb 07 2011 11:05:00 GMT"); // ""Day Mon dd yyyy hh:mm:ss GMT/UTC 

答案 15 :(得分:0)

这不是最佳解决方案,尽管我只是捕捉到错误并发回当前日期。我个人觉得如果用户要使用不符合sh * t标准的浏览器,就不能解决Safari问题-他们必须忍受怪癖。

function safeDate(dateString = "") {
  let date = new Date();
  try {
    if (Date.parse(dateString)) {
      date = new Date(Date.parse(dateString))
    }
  } catch (error) {
    // do nothing.
  }
  return date;
}

我建议您的后端发送ISO日期。

答案 16 :(得分:0)

这将无法正常工作alert(new Date('2010-11-29')); Safari浏览器具有一些处理日期格式alert(new Date(String('2010-11-29')));的怪异/严格的方法。

(或)

使用Moment js可以解决此问题,在ios 14之后,Safari甚至变得很奇怪

尝试此警报(moment(String(“ 2015-12-31 00:00:00”)));

时刻JS

答案 17 :(得分:0)

对我来说,问题是我忘记在 0 格式的个位数月份或日期之前添加 YYYY-MM-DD
我正在解析的内容:2021-11-5
它应该是什么:2021-11-05

所以,我写了一个小实用程序将 YYYY-M-D 转换为 YYYY-MM-DD,即 2021-1-12021-01-01

const date = "2021-1-1"
const YYYY = date.split("-")[0];

    //convert M->MM i.e. 2->02
    const MM =
      date.split("-")[1].length == 1
        ? "0" + date.split("-")[1]
        : date.split("-")[1];

    //convert D->DD i.e. 2->02
    const DD =
      date.split("-")[2].length == 1
        ? "0" + date.split("-")[2]
        : date.split("-")[2];

    // YYYY-MM-DD
    const properDateString = `${YYYY + "-" + MM + "-" + DD}`;

    const dateObj = new Date(properDateString);

答案 18 :(得分:-1)

使用'mm / dd / yyyy'格式。例如: - 新日期('02 / 28/2015')。它适用于所有浏览器。