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 日 :似乎人们仍然在这里登陆 - 今天,我将使用 moment
或 date-fns
并完成它。 Date-fns 也非常轻松且无痛。
对我来说,仅仅因为 Safari 不能正确地实现一个新库就太过分了,而且正则表达式是矫枉过正的。这是单线:
console.log (new Date('2011-04-12'.replace(/-/g, "/")));
模式 yyyy-MM-dd
不是 Date
构造函数的官方支持格式。 Firefox 似乎支持它,但不要指望其他浏览器也这样做。
以下是一些受支持的字符串:
MM-dd-yyyy
年年/月/日
月/日/年
MMMM dd, yyyy
嗯 dd, yyyy
DateJS 似乎是解析非标准日期格式的好库。
编辑:刚刚选中 ECMA-262 standard。引用第 15.9.1.15 节:
日期时间字符串格式
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 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");
我面临着类似的问题。 Date.Parse("DATESTRING")
正在使用 Chrome(版本 59.0.3071.115)但不是 Safari(版本 10.1.1 (11603.2.5))
苹果浏览器:
Date.parse("2017-01-22 11:57:00")
NaN
铬合金:
Date.parse("2017-01-22 11:57:00")
1485115020000
对我有用的解决方案是将 dateString 中的空格替换为 "T"
。 (例如:dateString.replace(/ /g,"T")
)
苹果浏览器:
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 中获得两个时间
苹果浏览器:
Date.parse("2017-01-22T11:57:00Z")
1485086220000
铬合金:
Date.parse("2017-01-22T11:57:00Z")
1485086220000
new Date(year, month, date, hours, minutes, seconds, milliseconds)
构造函数。将字符串日期解析为其组件的数组,以便在构造函数中使用这些组件。 @nizantz 如果您认为可以将此类示例添加到您的答案中,那就太好了。
dateString.replace(/ /g,"T")
神奇的代码行对我有用。 :)
我用时刻来解决问题。例如
var startDate = moment('2015-07-06 08:00', 'YYYY-MM-DD HH:mm').toDate();
moment
库现已弃用
要让解决方案适用于大多数浏览器,您应该使用这种格式创建日期对象
(year, month, date, hours, minutes, seconds, ms)
例如:
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)
将字符串转换为日期 fromat(您必须知道服务器时区)
new Date('2015-06-16 11:00:00'.replace(/\s+/g, 'T').concat('.000+08:00')).getTime()
其中 +08:00 = 服务器的时区
我遇到了同样的问题。然后我使用了 moment.Js。问题消失了。
从字符串创建时刻时,我们首先检查字符串是否与已知的 ISO 8601 格式匹配,如果未找到已知格式,则回退到 new Date(string)。警告:浏览器对解析字符串的支持不一致。因为没有关于应该支持哪些格式的规范,所以在某些浏览器中有效的内容在其他浏览器中无效。对于解析除 ISO 8601 字符串以外的任何内容的一致结果,您应该使用 String + Format。
例如
var date= moment(String);
对于使用 date-fns
的人,我们可以 parseISO
日期并使用它来格式化
无效的
import _format from 'date-fns/format';
export function formatDate(date: string, format: string): string {
return _format(new Date(date), format);
}
Safari 上的此函数会使用 Invalid date
引发错误。
解决方案要修复它,我们应该使用:
import _format from 'date-fns/format';
import _parseISO from 'date-fns/parseISO';
export function formatDate(date: string, format: string): string {
return _format(_parseISO(date), format);
}
尽管您可能希望浏览器支持 ISO 8601(或其仅日期子集),但事实并非如此。我知道的所有浏览器(至少在我使用的美国/英语语言环境中)都能够解析可怕的美国 MM/DD/YYYY
格式。
如果您已经有了日期的各个部分,您可能想尝试使用 Date.UTC()。如果你不这样做,但你必须使用 YYYY-MM-DD
格式,我建议使用正则表达式来解析你知道的部分,然后将它们传递给 Date.UTC()
。
我在 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
使用以下格式,它适用于所有浏览器
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, 22 Mar 2016 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”
这将为您提供时间的唯一时间戳
最好的方法是使用以下格式:
new Date(year, month, day, hours, minutes, seconds, milliseconds)
var d = new Date(2018, 11, 24, 10, 33, 30, 0);
所有浏览器都支持此功能,不会给您带来任何问题。请注意,月份是从 0 到 11 书写的。
对我来说,问题是我忘记在 YYYY-MM-DD
格式的单个数字月份或日期之前添加 0
。
我正在解析的内容:2021-11-5
它应该是什么:2021-11-05
因此,我编写了一个小工具,将 YYYY-M-D
转换为 YYYY-MM-DD
,即 2021-1-1
转换为 2021-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);
正如@nizantz 之前提到的,在 Safari 中使用 Date.parse() 对我不起作用。经过一番研究,我了解到 File 对象的 lastDateModified 属性已被弃用,Safari 不再支持。使用 File 对象的 lastModified 属性解决了我的问题。当网上发现不良信息时,肯定不喜欢它。
感谢所有为这篇文章做出贡献的人,他们帮助我走上了了解我的问题所需的道路。如果没有这些信息,我可能永远也不会弄清楚我的根本问题。也许这会帮助我遇到类似情况的其他人。
迟到了,但在我们的例子中,当我们使用 ES6 反引号而不是 String() 来输入强制转换时,我们在 Safari 和 iOS 中遇到了这个问题
这给出了“无效日期”错误
const dateString = '2011-11-18';
const dateObj = new Date(`${dateString}`);
但这有效
const dateObj = new Date(String(dateString));
Safari中面临同样的问题,通过在网页中插入它来解决
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.en"></script>
希望它也适用于您的情况
谢谢
这不起作用alert(new Date('2010-11-29'));
Safari 有一些奇怪/严格的处理日期格式的方式alert(new Date(String('2010-11-29')));
试试这样。
(或者)
使用 Moment js 可以解决这个问题,在 ios 14 之后,safari 变得更加奇怪
试试这个警报(时刻(字符串(“2015-12-31 00:00:00”)));
时刻JS
使用格式“mm/dd/yyyy”。例如:- 新日期('02/28/2015')。它适用于所有浏览器。
这不是最好的解决方案,尽管我只是捕捉到错误并发回当前日期。如果用户想使用不符合标准的浏览器,我个人觉得不解决 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 日期。