Javascript 日期对象总是休息一天吗?

发布于 2024-12-06 19:53:36 字数 318 浏览 0 评论 0 原文

在我的 Javascript 应用程序中,我以如下格式存储日期:

2011-09-24

现在,当我尝试使用上面的值创建一个新的 Date 对象(这样我可以以不同的格式检索日期)时,日期总是会在某一天返回。见下文:

var date = new Date("2011-09-24");
console.log(date);

日志:

Fri Sep 23 2011 20:00:00 GMT-0400 (Eastern Daylight Time)

In my Javascript app I have the date stored in a format like so:

2011-09-24

Now when I try using the above value to create a new Date object (so I can retrieve the date in a different format), the date always comes back one day off. See below:

var date = new Date("2011-09-24");
console.log(date);

logs:

Fri Sep 23 2011 20:00:00 GMT-0400 (Eastern Daylight Time)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

筱武穆 2024-12-13 19:53:37

您正在使用 ISO 日期字符串格式,根据 此页面,导致使用 UTC 时区构建日期:

注意:使用 Date 构造函数解析日期字符串(以及
Date.parse,它们是等价的)强烈建议不要这样做,因为
浏览器差异和不一致。支持 RFC 2822 格式
字符串只是按照惯例。对 ISO 8601 格式的支持不同
仅日期字符串(例如“1970-01-01”)被视为 UTC,而不是
本地。

如果您以不同的方式设置文本格式,例如 "Jan 01 1970",那么(至少在我的计算机上)它会使用您的本地时区。

You are using the ISO date string format which, according to this page, causes the date to be constructed using the UTC timezone:

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.

If you format the text differently, such as "Jan 01 1970", then (at least on my machine) it uses your local timezone.

猫烠⑼条掵仅有一顆心 2024-12-13 19:53:37

以 MySql 日期格式存储 yyyy-mm-dd 您必须执行以下操作:

const newDate = new Date( yourDate.getTime() + Math.abs(yourDate.getTimezoneOffset()*60000) );
console.log(newDate.toJSON().slice(0, 10)); // yyyy-mm-dd

Storing yyyy-mm-dd in MySql Date format you must do the following:

const newDate = new Date( yourDate.getTime() + Math.abs(yourDate.getTimezoneOffset()*60000) );
console.log(newDate.toJSON().slice(0, 10)); // yyyy-mm-dd
双马尾 2024-12-13 19:53:37

使用 moment 您可以在转换为 ISOString 时保留 Offset

let date = moment("2022-03-15").toISOString();
// WRONG OUTPUT 2022-03-14T18:30:00.000Z

let date = moment("2022-03-15").toISOString(true);
// CORRECT OUTPUT 2022-03-15T00:00:00.000+05:30

Using moment you can keep Offset while converting toISOString

let date = moment("2022-03-15").toISOString();
// WRONG OUTPUT 2022-03-14T18:30:00.000Z

let date = moment("2022-03-15").toISOString(true);
// CORRECT OUTPUT 2022-03-15T00:00:00.000+05:30
东北女汉子 2024-12-13 19:53:37

以下代码对我有用。首先,我将日期和时间字符串转换为 localeDateString,然后对返回的字符串应用 split 函数。

const dateString = "Thu Dec 29 2022 00:00:00 GMT+0500 (Pakistan Standard Time)";
const date = new Date(dateString).toLocaleDateString().split("/");
const year = new Date(dateString).getFullYear();
const month = new Date(dateString).getMonth();

console.log(new Date(`${date[2]}-${date[0]}-${date[1]}`));
// 2022-12-29T00:00:00.000Z


// Due to timezone issue, the date is one day off.
console.log(new Date("2011-09-24"));
// => 2011-09-24T00:00:00.000Z-CORRECT DATE.

console.log(new Date("2011/09/24"));
// => 2011-09-23T19:00:00.000Z -ONE DAY OFF AS BEFORE.

Following Code worked for me. First I converted to date and time string to localeDateString then apply the split function on the returned string.

const dateString = "Thu Dec 29 2022 00:00:00 GMT+0500 (Pakistan Standard Time)";
const date = new Date(dateString).toLocaleDateString().split("/");
const year = new Date(dateString).getFullYear();
const month = new Date(dateString).getMonth();

console.log(new Date(`${date[2]}-${date[0]}-${date[1]}`));
// 2022-12-29T00:00:00.000Z


// Due to timezone issue, the date is one day off.
console.log(new Date("2011-09-24"));
// => 2011-09-24T00:00:00.000Z-CORRECT DATE.

console.log(new Date("2011/09/24"));
// => 2011-09-23T19:00:00.000Z -ONE DAY OFF AS BEFORE.
oО清风挽发oО 2024-12-13 19:53:37

您还可以使用 getUTCDate() 来获取正确的日期。

 const date = new Date('Apr 04 2023') // Any Format
 // Tue Apr 04 2023 00:00:00 GMT-0700 (Pacific Daylight Time)
 date.getUTCDate() // 5

You can also use getUTCDate() to get the correct date.

 const date = new Date('Apr 04 2023') // Any Format
 // Tue Apr 04 2023 00:00:00 GMT-0700 (Pacific Daylight Time)
 date.getUTCDate() // 5
不再让梦枯萎 2024-12-13 19:53:37

尝试了多种解决方案。我的建议是将现有日期转换为字符串

date.toDateString()

接受来自后端的字符串,然后从后端 Convert.ToDateTime(date)

这样,它在所有情况下都适合我,
请尝试这个。

如果你想从 ui 端本身转换

date = this.datepipe.transform(date,"yyyy-MM-ddT00:00:00")

Tried multiple solutions. My suggestion would be convert the existing date to string

date.toDateString()

accept string from backend and then Convert.ToDateTime(date) from backend

In this way it worked well for me in all scenarios,
Please try this.

if your want to convert from ui side itself

date = this.datepipe.transform(date,"yyyy-MM-ddT00:00:00")
歌枕肩 2024-12-13 19:53:36

转换字符串的 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 构造函数提供单独的参数,您可以获得其他有用的输出,如下所述

注意:参数可以是数字或字符串类型。我将展示具有混合值的示例。

获取给定年份的第一个月和第一天

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)

数字、字符串参数的示例。请注意,月份是三月,因为又是从零开始的月份。

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)

There are several crazy things that happen with a JS DATE object that convert strings, for example consider the following date you provided

Note: The following examples may or may not be ONE DAY OFF depending on YOUR timezone and current time.

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...

new Date("09-24-2011");
// => Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE.

Another strange one

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

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"

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?

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.

new Date("2011-09-24T00:00:00".replace(/-/g, '\/').replace(/T.+/, ''));
// => Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE.

UPDATE

If you provide separate arguments to the Date constructor you can get other useful outputs as described below

Note: arguments can be of type Number or String. I'll show examples with mixed values.

Get the first month and day of a given year

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

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.

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.

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

new Date(2011, "02", -1);
// => Sun Feb 27 2011 00:00:00 GMT-0700 (MST)
演出会有结束 2024-12-13 19:53:36

请注意,东部夏令时间为 -4 小时,而您返回日期的小时数为 20

20h + 4h = 24h

这是 2011 年 9 月 24 日午夜。日期是在 UTC (GMT) 中解析,因为您提供了仅日期字符串,没有任何时区指示器。如果您提供了一个不带指示符的日期/时间字符串 (new Date("2011-09-24T00:00:00")),则它将在您的本地时区中进行解析。 (从历史上看,那里一直存在不一致的情况,尤其是因为规范多次更改,但现代浏览器应该没问题;或者您始终可以包含时区指示器。)

您得到了正确的日期,只是从未指定正确的时间区。

如果您需要访问日期值,可以使用 getUTCDate()任何其他 getUTC*() 函数

var d,
  days;
d = new Date('2011-09-24');
days = ['Sun', 'Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat'];
console.log(days[d.getUTCDay()]);

Notice that Eastern Daylight Time is -4 hours and that the hours on the date you're getting back are 20.

20h + 4h = 24h

which is midnight of 2011-09-24. The date was parsed in UTC (GMT) because you provided a date-only string without any time zone indicator. If you had given a date/time string w/o an indicator instead (new Date("2011-09-24T00:00:00")), it would have been parsed in your local timezone. (Historically there have been inconsistencies there, not least because the spec changed more than once, but modern browsers should be okay; or you can always include a timezone indicator.)

You're getting the right date, you just never specified the correct time zone.

If you need to access the date values, you can use getUTCDate() or 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()]);

¢蛋碎的人ぎ生 2024-12-13 19:53:36

标准化日期并消除不需要的偏移(此处测试: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 )  );

To normalize the date and eliminate the unwanted offset (tested here : 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)

This also accomplishes the same and credit to @tpartee (tested here : https://jsfiddle.net/7xp1xL5m/1/ ):

var doo = new Date("2011-09-24");
console.log( new Date( doo.getTime() - doo.getTimezoneOffset() * -60000 )  );
指尖上得阳光 2024-12-13 19:53:36

我认为这与时区调整有关。您创建的日期采用 GMT,默认时间是午夜,但您的时区是 EDT,因此会减去 4 小时。尝试这样做来验证:

var doo = new Date("2011-09-25 EDT");

I believe that it has to do with time-zone adjustment. The date you've created is in GMT and the default time is midnight, but your timezone is EDT, so it subtracts 4 hours. Try this to verify:

var doo = new Date("2011-09-25 EDT");
红玫瑰 2024-12-13 19:53:36

只是想补充一点,显然在字符串末尾添加空格将使用 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)

编辑:这不是推荐的解决方案,只是一个替代答案。请不要使用这种方法,因为目前还不清楚发生了什么。有人可以通过多种方式重构此过程,从而意外地导致错误。

Just want to add that apparently adding a space at the end of the string will use UTC for creation.

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)

Edit: This is not a recommended solution, just an alternative answer. Please do not use this approach since it is very unclear what is happening. There are a number of ways someone could refactor this accidentally causing a bug.

疯了 2024-12-13 19:53:36

如果您想要获取本地时区某个日期的 0 小时,请将各个日期部分传递给 Date 构造函数。

new Date(2011,08,24); // month value is 0 based, others are 1 based.

If you want to get hour 0 of some date in the local time zone, pass the individual date parts to the Date constructor.

new Date(2011,08,24); // month value is 0 based, others are 1 based.
断爱 2024-12-13 19:53:36

如果您需要一个简单的解决方案,请参阅:

new Date('1993-01-20'.split('-')); 

在此处输入图像描述

if you need a simple solution for this see:

new Date('1993-01-20'.split('-')); 

enter image description here

み格子的夏天 2024-12-13 19:53:36

您可以将此日期转换为 UTC 日期,

new Date(Date.UTC(Year, Month, Day, Hour, Minute, Second))

并且始终建议使用 UTC(通用时区)日期而不是使用本地时间的日期,因为默认情况下日期以 UTC 存储在数据库中。因此,在整个项目中使用和解释 UTC 格式的日期是一个很好的做法。
例如,

Date.getUTCYear(), getUTCMonth(), getUTCDay(), getUTCHours()

因此,使用 UTC 日期可以解决与时区问题相关的所有问题。

You can convert this date to UTC date by

new Date(Date.UTC(Year, Month, Day, Hour, Minute, Second))

And it is always recommended to use UTC (universal time zone) date instead of Date with local time, as by default dates are stored in Database with UTC. So, it is good practice to use and interpret dates in UTC format throughout entire project.
For example,

Date.getUTCYear(), getUTCMonth(), getUTCDay(), getUTCHours()

So, using UTC dates solves all the problem related to timezone issues.

神也荒唐 2024-12-13 19:53:36

您的问题具体与时区有关。请注意 GMT-0400 部分 - 即您比 GMT 晚 4 小时。如果您在显示的日期/时间上加上 4 小时,您将得到 2011 年 9 月 24 日午夜。使用 toUTCString() 方法来获取 GMT 字符串:

var doo = new Date("2011-09-24");
console.log(doo.toUTCString());

Your issue is specifically with time zone. Note part GMT-0400 - that is you're 4 hours behind GMT. If you add 4 hours to the displayed date/time, you'll get exactly midnight 2011/09/24. Use toUTCString() method instead to get GMT string:

var doo = new Date("2011-09-24");
console.log(doo.toUTCString());
死开点丶别碍眼 2024-12-13 19:53:36

这可能不是一个好的答案,但我只是想分享我对此问题的经验。

我的应用程序全局使用 utc 日期,格式为“YYYY-MM-DD”,而我使用的 datepicker 插件只接受 js 日期,我很难同时考虑 utc 和 js。因此,当我想将“YYYY-MM-DD”格式的日期传递给我的日期选择器时,我首先使用 moment.js 或您喜欢的任何内容将其转换为“MM/DD/YYYY”格式,并且日期选择器上显示的日期现在是正确的。对于你的例子

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 是我想要的。希望这对某些人有帮助。

This probably is not a good answer, but i just want to share my experience with this issue.

My app is globally use utc date with the format 'YYYY-MM-DD', while the datepicker plugin i use only accept js date, it's hard for me to consider both utc and js. So when i want to pass a 'YYYY-MM-DD' formatted date to my datepicker, i first convert it to 'MM/DD/YYYY' format using moment.js or whatever you like, and the date shows on datepicker is now correct. For your example

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

Apparently d1 is what i want. Hope this would be helpful for some people.

小苏打饼 2024-12-13 19:53:36

这通过我循环了一遍,对 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!

This through me for a loop, +1 on zzzBov's answer. Here is a full conversion of a date that worked for me using the UTC methods:

//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!
只涨不跌 2024-12-13 19:53:36

当我的客户使用大西洋标准时间时,我遇到了这个确切的问题。客户端检索到的日期值是“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>

I encountered this exact problem where my client was on Atlantic Standard Time. The date value the client retrieved was "2018-11-23" and when the code passed it into new Date("2018-11-23") the output for the client was for the previous day. I created a utility function as shown in the snippet that normalized the date, giving the client the expected date.

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>

掩饰不了的爱 2024-12-13 19:53:36

尽管在OP的情况下,时区是EDT,但不能保证执行脚本的用户将在EDT时区,因此对偏移量进行硬编码不一定有效。我找到的解决方案分割日期字符串并在日期构造函数中使用单独的值。

var dateString = "2011-09-24";
var dateParts = dateString.split("-");
var date = new Date(dateParts[0], dateParts[1] - 1, dateParts[2]);

请注意,您必须考虑 JS 的另一个怪异之处:月份是从零开始的。

Though in the OP's case the timezone is EDT, there's not guarantee the user executing your script will be int he EDT timezone, so hardcoding the offset won't necessarily work. The solution I found splits the date string and uses the separate values in the Date constructor.

var dateString = "2011-09-24";
var dateParts = dateString.split("-");
var date = new Date(dateParts[0], dateParts[1] - 1, dateParts[2]);

Note that you have to account for another piece of JS weirdness: the month is zero-based.

羁拥 2024-12-13 19:53:36

我解析 ISO 日期而不被时区困扰的解决方案是在解析之前在末尾添加一个“T12:00:00”,因为当格林威治中午时,整个世界都在同一天:

function toDate(isoDateString) {
  // isoDateString is a string like "yyyy-MM-dd"
  return new Date(`${isoDateString}T12:00:00`);
}

之前:

> new Date("2020-10-06")
> Date Mon Oct 05 2020 14:00:00 GMT-1000 (heure normale d’Hawaii - Aléoutiennes)

后:

> toDate("2020-10-06")
> Date Tue Oct 06 2020 12:00:00 GMT-1000 (heure normale d’Hawaii - Aléoutiennes)

My solution to parse an ISO date without beeing annoyed by the timezone is to add a "T12:00:00" at the end before parsing it, because when it's noon at Greenwich, well the whole world is on the same day :

function toDate(isoDateString) {
  // isoDateString is a string like "yyyy-MM-dd"
  return new Date(`${isoDateString}T12:00:00`);
}

Before:

> new Date("2020-10-06")
> Date Mon Oct 05 2020 14:00:00 GMT-1000 (heure normale d’Hawaii - Aléoutiennes)

After:

> toDate("2020-10-06")
> Date Tue Oct 06 2020 12:00:00 GMT-1000 (heure normale d’Hawaii - Aléoutiennes)
小女人ら 2024-12-13 19:53:36

它表示 2011-09-24 00:00:00 GMT,由于您现在处于 GMT -4,因此将为 20:00 > 前一天。

就我个人而言,我得到的是 2011-09-24 02:00:00,因为我住在 GMT +2

It means 2011-09-24 00:00:00 GMT, and since you're at GMT -4, it will be 20:00 the previous day.

Personally, I get 2011-09-24 02:00:00, because I'm living at GMT +2.

浅唱ヾ落雨殇 2024-12-13 19:53:36

您可以使用时刻库​​来格式化日期。
https://momentjs.com/

let format1 = "YYYY-MM-DD"
let date = new Date();

console.log(moment(date).format(format1))

编辑

该时刻现已弃用,您可以使用 date-fns format 用于格式化日期的方法。

import { format } from 'date-fns'
format(new Date(), "yyyy-MM-dd")

You can use moment library to format the date.
https://momentjs.com/

let format1 = "YYYY-MM-DD"
let date = new Date();

console.log(moment(date).format(format1))

EDIT

The moment is now deprecated, you can use date-fns format method for formatting a date.

import { format } from 'date-fns'
format(new Date(), "yyyy-MM-dd")
逆光下的微笑 2024-12-13 19:53:36

由于大多数答案都是 hacky,请允许我提出对我有用的非常简单的 hack:将脚本的时区设置为 UTC

process.env.TZ = 'UTC' // this has to be run before any use of dates

通过此更改,任何时区修改都会被抵消,因此只要您不这样做需要跑步者的实际时区,这可能是最简单的解决方法。

As most answers are hacky, allow me to propose my very simple hack that worked for me: Set the script's timezone to UTC

process.env.TZ = 'UTC' // this has to be run before any use of dates

With this change, any timezone modifications are neutralized, so as long as you don't need the runner's actual timezone, this is probably the easiest fix.

全部不再 2024-12-13 19:53:36

如果您只是想确保日期的各个部分出于显示目的保持不变,*即使我更改时区,这似乎也有效:

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 日期字符串保持不变。

但我错过了什么/这是一个坏主意吗?

*至少在铬合金中。这在 Safari 中不起作用!截至撰写本文时

if you're just looking to make sure the individual parts of the date stay the same for display purposes, *this appears to work, even when I change my timezone:

var doo = new Date("2011-09-24 00:00:00")

just add the zeros in there.

In my code I do this:

let dateForDisplayToUser = 
  new Date( `${YYYYMMDDdateStringSeparatedByHyphensFromAPI} 00:00:00` )
  .toLocaleDateString( 
    'en-GB', 
    { day: 'numeric', month: 'short', year: 'numeric' }
  )

And I switch around my timezone on my computer and the date stays the same as the yyyy-mm-dd date string I get from the API.

But am I missing something/is this a bad idea ?

*at least in chrome. This Doesn't work in Safari ! as of this writing

-黛色若梦 2024-12-13 19:53:36
// When the time zone offset is absent, date-only formats such as '2011-09-24' 
// are interpreted as UTC time, however the date object will display the date 
// relative to your machine's local time zone, thus producing a one-day-off output.
const date = new Date('2011-09-24');
console.log(date); // Fri Sep 23 2011 17:00:00 GMT-0700 (PDT)
console.log(date.toLocaleDateString('en-US')); // "9/23/2011"
            
// To ensure the date object displays consistently with your input, simply set
// the timeZone parameter to 'UTC' in your options argument.  
console.log(date.toLocaleDateString('en-US', { timeZone: 'UTC' })); // "9/24/2011"

// When the time zone offset is absent, date-only formats such as '2011-09-24' 
// are interpreted as UTC time, however the date object will display the date 
// relative to your machine's local time zone, thus producing a one-day-off output.
const date = new Date('2011-09-24');
console.log(date); // Fri Sep 23 2011 17:00:00 GMT-0700 (PDT)
console.log(date.toLocaleDateString('en-US')); // "9/23/2011"
            
// To ensure the date object displays consistently with your input, simply set
// the timeZone parameter to 'UTC' in your options argument.  
console.log(date.toLocaleDateString('en-US', { timeZone: 'UTC' })); // "9/24/2011"

你又不是我 2024-12-13 19:53:36

处理此问题的最佳方法是在不使用更多转换方法的情况下,

 var mydate='2016,3,3';
 var utcDate = Date.parse(mydate);
 console.log(" You're getting back are 20.  20h + 4h = 24h :: "+utcDate);

现在只需在日期中添加 GMT,或者您可以附加它。

 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/

The best way to handle this without using more conversion methods,

 var mydate='2016,3,3';
 var utcDate = Date.parse(mydate);
 console.log(" You're getting back are 20.  20h + 4h = 24h :: "+utcDate);

Now just add GMT in your date or you can append it.

 var  mydateNew='2016,3,3'+ 'GMT';
 var utcDateNew = Date.parse(mydateNew);
 console.log("the right time that you want:"+utcDateNew)

Live: https://jsfiddle.net/gajender/2kop9vrk/1/

于我来说 2024-12-13 19:53:36

我遇到了这样的问题。但我的问题是从数据库获取日期时的偏移。

这是存储在数据库中的,并且采用 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);

因此,当日期来自服务器并具有服务器偏移量时,我会分割日期并删除服务器偏移量,然后转换为日期。它解决了我的问题。

I faced some issue like this. But my issue was the off set while getting date from database.

this is stroed in the database and it is in the UTC format.

2019-03-29 19:00:00.0000000 +00:00

So when i get from database and check date it is adding offset with it and send back to javascript.

enter image description here

It is adding +05:00 because this is my server timezone. My client is on different time zone +07:00.

2019-03-28T19:00:00+05:00 // this is what i get in javascript.

So here is my solution what i do with this issue.

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

So when date come from the server and have server offset so i split date and remove server offset and then convert to date. It resolves my issue.

彡翼 2024-12-13 19:53:36

试图将我的 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)

Trying to add my 2 cents to this thread (elaborating on @paul-wintz answer).

Seems to me that when Date constructor receives a string that matches first part of ISO 8601 format (date part) it does a precise date conversion in UTC time zone with 0 time. When that date is converted to local time a date shift may occur
if midnight UTC is an earlier date in local time zone.

new Date('2020-05-07')
Wed May 06 2020 20:00:00 GMT-0400 (Eastern Daylight Time)

If the date string is in any other "looser" format (uses "/" or date/month is not padded with zero) it creates the date in local time zone, thus no date shifting issue.

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)

So then one quick fix, as mentioned above, is to replace "-" with "/" in your ISO formatted Date only string.

new Date('2020-05-07'.replace('-','/'))
Thu May 07 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
时常饿 2024-12-13 19:53:36

这解决了我的问题(感谢@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

This solved my problem (thanks to @Sebastiao answer)

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
岁月静好 2024-12-13 19:53:36

我只想为此付出 2 美分,因为这篇文章对于解决这个问题非常有帮助。我认为我没有看到提到过这个解决方案,如果我错了,请纠正我。

正如这里已经多次提到的,问题主要来自夏季/冬季。我注意到一月份,GMT 为+1。如果未设置时间,则始终为 00.00.00(午夜),这将导致前一天的 23 小时继续。

如果您有动态日期并且不关心小时,则可以使用 setHours() 方法设置小时,然后再将其与 toISOString() 一起使用。

句法:
应该希望对您有用,因为即使日期提前/落后一小时,

这意味着:

dynamicDate.setHours(12, 0, 0, 0)
dynamicDate.toISOString()

它仍然是同一天,因为我们将时间设置为中午。

有关 setHours() 的更多信息,请访问 MDN

I just wanted to give my 2 cents on this, as this post was very helpful to figure out the issue. I don't think I've seen this solution mentioned, correct me if I'm wrong.

As it has been mentioned numerous times already here, the problem comes mainly from summer/winter time. I noticed that in January, the GMT was +1. If the time is not set, it will always be 00.00.00 (midnight), which results in going on the 23rd hour of the previous day.

If you have a dynamic date and don't care about the hour, you can set the hour using the setHours() method before using it with toISOString().

syntax:
setHours(hoursValue, minutesValue, secondsValue, msValue)

Which means that:

dynamicDate.setHours(12, 0, 0, 0)
dynamicDate.toISOString()

should hopefully work for you as even if the date is one hour ahead/behind it will still be the same day now that we're setting the hour to be noon.

More about setHours() on MDN.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文