Is the Javascript date object always one day off?
在我的Java Script应用程序中,我将日期存储为如下格式:
1 | 2011-09-24 |
现在,当我尝试使用上面的值来创建一个新的Date对象(所以我可以以不同的格式检索日期)时,日期总会在一天后返回。 见下文:
1 2 | var doo = new Date("2011-09-24"); console.log(doo); |
日志:
1 | Fri Sep 23 2011 20:00:00 GMT-0400 (Eastern Daylight Time) |
使用转换字符串的JS DATE对象会发生一些疯狂的事情,例如考虑您提供的以下日期
Note: The following examples may or may not be ONE DAY OFF depending on YOUR timezone and current time.
1 2 | new Date("2011-09-24"); // Year-Month-Day // => Fri Sep 23 2011 17:00:00 GMT-0700 (MST) - ONE DAY OFF. |
However, if we rearrange the string format to Month-Day-Year...
1 2 | new Date("09-24-2011"); => // Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE. |
Another strange one
1 2 3 4 5 | new Date("2011-09-24"); // => Fri Sep 23 2011 17:00:00 GMT-0700 (MST) - ONE DAY OFF AS BEFORE. new Date("2011/09/24"); // change from"-" to"/". => // Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE. |
We could easily change hyphens in your date"2011-09-24" when making a new date
1 2 | new Date("2011-09-24".replace(/-/g, '\/')); // =>"2011/09/24". => // Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE. |
What if we had a date string like"2011-09-24T00:00:00"
1 2 | new Date("2011-09-24T00:00:00"); // => Fri Sep 23 2011 17:00:00 GMT-0700 (MST) - ONE DAY OFF. |
Now change hyphen to forward slash as before; what happens?
1 2 | new Date("2011/09/24T00:00:00"); // => Invalid Date |
I typically have to manage the date format 2011-09-24T00:00:00 so this is what I do.
1 2 | new Date("2011-09-24T00:00:00".replace(/-/g, '\/').replace(/T.+/, '')); // => Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE. |
UPDATE
如果为Date构造函数提供单独的参数,则可以获得其他有用的输出,如下所述
注意:参数可以是Number或String类型。我将展示具有混合值的示例。
Get the first month and day of a given year
1 2 | new Date(2011, 0); // Normal behavior as months in this case are zero based. => // Sat Jan 01 2011 00:00:00 GMT-0700 (MST) |
Get the last month and day of a year
1 2 | new Date((2011 + 1), 0, 0); // The second zero roles back one day into the previous month's last day. => // Sat Dec 31 2011 00:00:00 GMT-0700 (MST) |
Example of Number, String arguments. Note the month is March because zero based months again.
1 2 | new Date(2011,"02"); => // Tue Mar 01 2011 00:00:00 GMT-0700 (MST) |
If we do the same thing but with a day of zero, we get something different.
1 2 | new Date(2011,"02", 0); // again the zero roles back from March to the last day of February. => // Mon Feb 28 2011 00:00:00 GMT-0700 (MST) |
Adding a day of zero to any year and month argument will get the last day of the previous month. If you continue with negative numbers you can continue rolling back another day
1 2 | new Date(2011,"02", -1); => // Sun Feb 27 2011 00:00:00 GMT-0700 (MST) |
请注意,东部夏令时
1 | 20h + 4h = 24h |
这是2011-09-24的午夜。
你得到了正确的约会,你从未指定过正确的时区。
如果需要访问日期值,可以使用
1 2 3 4 5 | var d, days; d = new Date('2011-09-24'); days = ['Sun', 'Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat']; console.log(days[d.getUTCDay()]); |
规范化日期并消除不需要的偏移量(在此测试:https://jsfiddle.net/7xp1xL5m/):
1 2 3 | var doo = new Date("2011-09-24"); console.log( new Date( doo.getTime() + Math.abs(doo.getTimezoneOffset()*60000) ) ); // Output: Sat Sep 24 2011 00:00:00 GMT-0400 (Eastern Daylight Time) |
这也完成了相同的功能并归功于@tpartee(在此测试:https://jsfiddle.net/7xp1xL5m/1/):
1 2 | var doo = new Date("2011-09-24"); console.log( new Date( doo.getTime() - doo.getTimezoneOffset() * -60000 ) ); |
如果要在本地时区中获取某个日期的小时0,请将各个日期部分传递给
1 | new Date(2011,08,24); // month value is 0 based, others are 1 based. |
只是想补充一点,显然在字符串末尾添加一个空格将使用UTC进行创建。
1 2 3 4 5 | new Date("2016-07-06") > Tue Jul 05 2016 17:00:00 GMT-0700 (Pacific Daylight Time) new Date("2016-07-06") > Wed Jul 06 2016 00:00:00 GMT-0700 (Pacific Daylight Time) |
编辑:这不是推荐的解决方案,只是一个替代答案。请不要使用这种方法,因为很不清楚发生了什么。有很多方法可以让人意外地重构这个错误。
我认为这与时区调整有关。您创建的日期是GMT,默认时间是午夜,但您的时区是EDT,因此减去4小时。试试这个来验证:
1 | var doo = new Date("2011-09-25 EDT"); |
您的问题特别针对时区。注意部分
1 2 | var doo = new Date("2011-09-24"); console.log(doo.toUTCString()); |
这是通过我循环,在zzzBov的答案+1。以下是使用UTC方法为我工作的日期的完整转换:
1 2 3 4 5 6 7 8 | //myMeeting.MeetingDate = '2015-01-30T00:00:00' var myDate = new Date(myMeeting.MeetingDate); //convert to JavaScript date format //returns date of 'Thu Jan 29 2015 19:00:00 GMT-0500 (Eastern Standard Time)' <-- One Day Off! myDate = new Date(myDate.getUTCFullYear(), myDate.getUTCMonth(), myDate.getUTCDate()); //returns date of 'Fri Jan 30 2015 00:00:00 GMT-0500 (Eastern Standard Time)' <-- Correct Date! |
这可能不是一个好的答案,但我只想分享我对这个问题的经验。
我的应用程序全局使用格式为'YYYY-MM-DD'的utc日期,而我使用的datepicker插件只接受js日期,我很难同时考虑utc和js。因此,当我想将'YYYY-MM-DD'格式的日期传递给我的datepicker时,我首先使用moment.js或任何你喜欢的方式将其转换为'MM / DD / YYYY'格式,并且datepicker上的日期现在显示正确。以你为榜样
1 2 | var d = new Date('2011-09-24'); // d will be 'Fri Sep 23 2011 20:00:00 GMT-0400 (EDT)' for my lacale var d1 = new Date('09/24/2011'); // d1 will be 'Sat Sep 24 2011 00:00:00 GMT-0400 (EDT)' for my lacale |
显然d1是我想要的。希望这对某些人有所帮助。
它意味着
就个人而言,我得到
虽然在OP的情况下时区是EDT,但是不能保证执行脚本的用户将在EDT时区内,因此对偏移量进行硬编码不一定有效。我找到的解决方案拆分日期字符串并使用Date构造函数中的单独值。
1 2 3 | var dateString ="2011-09-24"; var dateParts = dateString.split("-"); var date = new Date(dateParts[0], dateParts[1] - 1, dateParts[2]); |
请注意,您必须考虑另一个JS怪异:月份是从零开始的。
不使用更多转换方法处理此问题的最佳方法,
1 2 3 | var mydate='2016,3,3'; var utcDate = Date.parse(mydate); console.log(" You're getting back are 20. 20h + 4h = 24h ::"+utcDate); |
现在只需在您的日期添加GMT,或者您可以追加它。
1 2 3 | var mydateNew='2016,3,3'+ 'GMT'; var utcDateNew = Date.parse(mydateNew); console.log("the right time that you want:"+utcDateNew) |
直播:https://jsfiddle.net/gajender/2kop9vrk/1/
我遇到了这样的问题。但我的问题是从数据库获取日期时的偏离。
这是在数据库中,它是UTC格式。
2019-03-29 19:00:00.0000000 +00:00
因此,当我从数据库获取并检查日期时,它会添加偏移并发送回javascript。
它正在添加+05:00,因为这是我的服务器时区。我的客户在+07:00的不同时区。
2019-03-28T19:00:00+05:00 // this is what i get in javascript.
所以这是我的解决方案,我对这个问题做了什么。
1 2 3 | var dates = price.deliveryDate.split(/-|T|:/); var expDate = new Date(dates[0], dates[1] - 1, dates[2], dates[3], dates[4]); var expirationDate = new Date(expDate); |
因此,当日期来自服务器并具有服务器偏移量时,我将分割日期并删除服务器偏移量,然后转换为日期。它解决了我的问题。
我遇到了这个问题,我的客户是在大西洋标准时间。客户端检索的日期值为"2018-11-23",当代码将其传递到
1 2 3 4 5 6 7 8 9 | var normalizeDate = function(date) { date.setMinutes(date.getMinutes() + date.getTimezoneOffset()); return date; }; var date = new Date("2018-11-23"); document.getElementById("default").textContent = date; document.getElementById("normalized").textContent = normalizeDate(date); |
1 2 3 4 5 6 7 8 9 | Calling new Date("2018-11-23") <label>Default : </label> <span id="default"></span> <label>Normalized : </label> <span id="normalized"></span> |
您使用的是ISO日期字符串格式,根据此页面,该格式会导致使用UTC时区构建日期:
Note: parsing of date strings with the Date constructor (and
Date.parse, they are equivalent) is strongly discouraged due to
browser differences and inconsistencies. Support for RFC 2822 format
strings is by convention only. Support for ISO 8601 formats differs in
that date-only strings (e.g."1970-01-01") are treated as UTC, not
local.
如果您以不同方式格式化文本,例如
您的日志输出GMT,因此您要指定您的时区:
1 | var doo = new Date("2011-09-24 EST"); |
以下对我有用 -
1 | var doo = new Date("2011-09-24").format("m/d/yyyy"); |
没关系,没注意到GMT -0400,导致日期是昨天
您可以尝试将默认"时间"设置为12:00:00