在我的Java Script应用程序中,我将日期存储为如下格式:
2011-09-24
现在,当我尝试使用上面的值来创建一个新的Date对象(所以我可以用不同的格式检索日期)时,日期总会在一天之后回来。见下文:
var doo = new Date("2011-09-24");
console.log(doo);
日志:
Fri Sep 23 2011 20:00:00 GMT-0400 (Eastern Daylight Time)
答案 0 :(得分:189)
对于转换字符串的JS DATE 对象,会发生几个疯狂的事情,例如考虑您提供的以下日期
注意:以下示例可能会或可能不会一天关闭,具体取决于您的时区和当前时间。
new Date("2011-09-24"); // Year-Month-Day
// => Fri Sep 23 2011 17:00:00 GMT-0700 (MST) - ONE DAY OFF.
但是,如果我们将字符串格式重新排列为月 - 日 - 年 ......
new Date("09-24-2011");
=> // Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE.
另一个奇怪的人
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.
我们可以在制作新日期时轻松更改日期“2011-09-24”中的连字符
new Date("2011-09-24".replace(/-/g, '\/')); // => "2011/09/24".
=> // Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE.
如果我们的日期字符串如“2011-09-24T00:00:00”
怎么办?
new Date("2011-09-24T00:00:00");
// => Fri Sep 23 2011 17:00:00 GMT-0700 (MST) - ONE DAY OFF.
现在像以前一样将连字符更改为正斜杠;会发生什么?
new Date("2011/09/24T00:00:00");
// => Invalid Date
我通常必须管理日期格式 2011-09-24T00:00:00 所以这就是我的工作。
new Date("2011-09-24T00:00:00".replace(/-/g, '\/').replace(/T.+/, ''));
// => Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE.
<强>更新强>
如果为Date构造函数提供单独的参数,则可以获得其他有用的输出,如下所述
注意:参数可以是Number或String类型。我将展示具有混合值的示例。
获取特定年份的第一个月和第一天
new Date(2011, 0); // Normal behavior as months in this case are zero based.
=> // Sat Jan 01 2011 00:00:00 GMT-0700 (MST)
获取一年中的最后一个月和一天
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)
Number,String参数的示例。请注意,月份是3月份,因为再次为零个月。
new Date(2011, "02");
=> // Tue Mar 01 2011 00:00:00 GMT-0700 (MST)
如果我们做同样的事情但是一天零,我们会得到不同的东西。
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)
在任何年份和月份参数中添加零日将获得上个月的最后一天。如果您继续使用负数,则可以继续回滚另一天
new Date(2011, "02", -1);
=> // Sun Feb 27 2011 00:00:00 GMT-0700 (MST)
答案 1 :(得分:84)
请注意,东部夏令时为-4 hours
,而您返回日期的时间为20
。
20h + 4h = 24h
是2011-09-24的午夜。
你得到了正确的约会,你从未指定过正确的时区。
如果您需要访问日期值,可以使用getUTCDate()
或any of the other getUTC*()
functions:
var d,
days;
d = new Date('2011-09-24');
days = ['Sun', 'Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat'];
console.log(days[d.getUTCDay()]);
答案 2 :(得分:64)
标准化日期并消除不需要的偏移(在此测试:https://jsfiddle.net/7xp1xL5m/):
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/):
var doo = new Date("2011-09-24");
console.log( new Date( doo.getTime() - doo.getTimezoneOffset() * -60000 ) );
答案 3 :(得分:25)
如果您想在当地时区获得某个日期的0小时,请将各个日期部分传递给Date
构造函数。
new Date(2011,08,24); // month value is 0 based, others are 1 based.
答案 4 :(得分:23)
只是想补充一点,显然在字符串末尾添加一个空格将使用UTC进行创建。
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)
编辑:这不是推荐的解决方案,只是一个替代答案。请不要使用这种方法,因为很不清楚发生了什么。有很多方法可以让人意外地重构这个错误。
答案 5 :(得分:16)
我认为这与时区调整有关。您创建的日期是GMT,默认时间是午夜,但您的时区是EDT,因此减去4小时。试试这个来验证:
var doo = new Date("2011-09-25 EDT");
答案 6 :(得分:11)
您的问题专门针对时区。注意部分GMT-0400
- 即你比GMT落后4小时。如果您将4小时添加到显示的日期/时间,您将获得2011/09/24的午夜时间。使用toUTCString()
方法来获取GMT字符串:
var doo = new Date("2011-09-24");
console.log(doo.toUTCString());
答案 7 :(得分:5)
这是通过我循环,在zzzBov的回答+1。以下是使用UTC方法为我工作的日期的完整转换:
//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!
答案 8 :(得分:4)
这意味着2011-09-24 00:00:00 GMT
,因为您位于GMT -4
,前一天将是20:00
。
就个人而言,我得到2011-09-24 02:00:00
,因为我住在GMT +2
。
答案 9 :(得分:4)
这可能不是一个好的答案,但我只想分享我对这个问题的经验。
我的应用程序全局使用格式为'YYYY-MM-DD'的utc日期,而我使用的datepicker插件只接受js日期,我很难同时考虑utc和js。因此,当我想将'YYYY-MM-DD'格式的日期传递给我的datepicker时,我首先使用moment.js或任何你喜欢的方式将其转换为'MM / DD / YYYY'格式,并且datepicker上的日期现在显示正确。对于你的例子
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是我想要的。希望这对某些人有用。
答案 10 :(得分:4)
您可以将此日期转换为UTC日期
new Date(Date.UTC(Year, Month, Day, Hour, Minute, Second))
并且始终建议使用UTC(通用时区)日期而不是带有本地时间的Date,因为默认情况下,日期存储在带有UTC的数据库中。因此,优良作法是在整个项目中使用和解释UTC格式的日期。 例如,
Date.getUTCYear(), getUTCMonth(), getUTCDay(), getUTCHours()
因此,使用UTC日期可以解决所有与时区问题相关的问题。
答案 11 :(得分:4)
答案 12 :(得分:2)
虽然在OP的情况下时区是EDT,但不能保证执行脚本的用户将在EDT时区内,因此对偏移量进行硬编码不一定有效。我找到的解决方案拆分日期字符串并使用Date构造函数中的单独值。
var dateString = "2011-09-24";
var dateParts = dateString.split("-");
var date = new Date(dateParts[0], dateParts[1] - 1, dateParts[2]);
请注意,您必须考虑JS的另一个奇怪之处:月份是从零开始的。
答案 13 :(得分:1)
在不使用更多转换方法的情况下处理此问题的最佳方法,
<rewrite>
<rules>
<rule name="apple_json_file">
<match url="^apple-app-site-association" />
<action type="Rewrite" url="apple-app-site-association.json" />
</rule>
</rules>
</rewrite>
现在只需在您的日期添加GMT,或者您可以追加它。
var mydate='2016,3,3';
var utcDate = Date.parse(mydate);
console.log(" You're getting back are 20. 20h + 4h = 24h :: "+utcDate);
答案 14 :(得分:1)
尝试将我的2美分添加到该线程中(详细说明@ paul-wintz答案)。
在我看来,当Date构造函数接收到与ISO 8601格式的第一部分(日期部分)匹配的字符串时,它将在UTC时区中以0时间进行精确的日期转换。该日期转换为当地时间后,日期可能会发生变化 如果午夜UTC是本地时区的较早日期。
new Date('2020-05-07')
Wed May 06 2020 20:00:00 GMT-0400 (Eastern Daylight Time)
如果日期字符串采用任何其他“更宽松”的格式(使用“ /”或日期/月份未填充零),则会在本地时区创建日期,因此不会出现日期转换问题。
new Date('2020/05/07')
Thu May 07 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2020-5-07')
Thu May 07 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2020-5-7')
Thu May 07 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2020-05-7')
Thu May 07 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
因此,如上所述,一种快速的解决方法是将ISO格式的“仅日期”字符串中的“-”替换为“ /”。
new Date('2020-05-07'.replace('-','/'))
Thu May 07 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
答案 15 :(得分:1)
如果您只是要确保日期的各个部分保持一致以进行显示,*即使我更改了时区,这似乎也可行:
var doo = new Date("2011-09-24 00:00:00")
只需在其中添加零即可。
在我的代码中,我这样做:
let dateForDisplayToUser =
new Date( `${YYYYMMDDdateStringSeparatedByHyphensFromAPI} 00:00:00` )
.toLocaleDateString(
'en-GB',
{ day: 'numeric', month: 'short', year: 'numeric' }
)
然后我在计算机上切换时区,并且日期与从API获取的yyyy-mm-dd日期字符串相同。
但是我错过了什么吗/这是个坏主意吗?
*至少在chrome中。这在Safari中不起作用!在撰写本文时
答案 16 :(得分:1)
我遇到了这样的问题。但是我的问题是从数据库获取日期时出现偏移。
它存储在数据库中,并且采用UTC格式。
2019-03-29 19:00:00.0000000 +00:00
因此,当我从数据库中获取日期并检查日期时,它会添加偏移量并发送回javascript。
正在添加+05:00,因为这是我的服务器时区。我的客户所在的时区是+07:00。
2019-03-28T19:00:00 + 05:00 //这就是我在javascript中得到的东西。
这是我的解决方案,我将如何处理此问题。
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);
因此,当日期来自服务器且具有服务器偏移量时,我将拆分日期并删除服务器偏移量,然后转换为日期。它解决了我的问题。
答案 17 :(得分:0)
我的客户在大西洋标准时间遇到了这个确切的问题。客户端检索的日期值为“ 2018-11-23” ,当代码将其传递到new Date("2018-11-23")
时,客户端的输出为前一天。我创建了一个效用函数,如片段中所示,该函数对日期进行了归一化,从而为客户提供了预期的日期。
date.setMinutes(date.getMinutes() + date.getTimezoneOffset());
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);
<h2>Calling new Date("2018-11-23")</h2>
<div>
<label><b>Default</b> : </label>
<span id="default"></span>
</div>
<hr>
<div>
<label><b>Normalized</b> : </label>
<span id="normalized"></span>
</div>
答案 18 :(得分:0)
您使用的是ISO日期字符串格式,根据this page,该格式导致使用UTC时区构造日期:
注意:使用Date构造函数解析日期字符串(和 强烈建议不要使用Date.parse,它们等效) 浏览器的差异和不一致之处。支持RFC 2822格式 字符串仅按照惯例。对ISO 8601格式的支持在以下方面有所不同 仅日期的字符串(例如“ 1970-01-01”)被视为UTC,而不是 本地的。
如果您以不同的格式设置文本,例如"Jan 01 1970"
,则(至少在我的机器上)它将使用您的本地时区。
答案 19 :(得分:0)
以MySql Date格式存储yyyy-mm-dd
时,您必须执行以下操作:
const newDate = new Date( yourDate.getTime() + Math.abs(yourDate.getTimezoneOffset()*60000) );
console.log(newDate.toJSON().slice(0, 10)); // yyyy-mm-dd
答案 20 :(得分:0)
由于大多数答案都是 hacky,请允许我提出对我有用的非常简单的 hack:将脚本的时区设置为 UTC
process.env.TZ = 'UTC' // this has to be run before any use of dates
通过此更改,任何时区修改都将无效,因此只要您不需要跑步者的实际时区,这可能是最简单的解决方法。
答案 21 :(得分:0)
您可以使用矩库来格式化日期。 https://momentjs.com/
let format1 = "YYYY-MM-DD"
let date = new Date();
console.log(moment(date).format(format1))
答案 22 :(得分:0)
这解决了我的问题(感谢@Sebastiao 的回答)
var date = new Date();
//"Thu Jun 10 2021 18:46:00 GMT+0200 (Eastern European Standard Time)"
date.toString().split(/\+|-/)[0] ; // .split(/\+|-/) is a regex for matching + or -
//"Thu Jun 10 2021 18:46:00 GMT"
var date_string_as_Y_M_D = (new Date(date)).toISOString().split('T')[0];
//2021-06-10
答案 23 :(得分:-1)
您的日志输出GMT,因此您想指定时区:
page
答案 24 :(得分:-3)
没关系,没注意到GMT -0400,导致日期是昨天
您可以尝试将默认“时间”设置为12:00:00