如果时间没有归零,为什么javascript减去整个月而不是一天?

8zzbczxx  于 2023-02-02  发布在  Java
关注(0)|答案(2)|浏览(121)

不是寻找解决方案,只是想知道为什么我会得到这些结果,并更好地理解javascript。

我正在计算从今天到3天前的日期和日期字符串。如果我将今天的时间清零,则一切正常。如果我不这样做(也可能接近UTC午夜),昨天是一个月前,则其他前一天的计算按预期工作。
截图:

代码在东部时间大约5:30p(UTC时间11:30p)在控制台中运行
下面是代码,您可以自己运行它。
归零时间和昨天是昨天:

let today = new Date();
today.setUTCHours(0,0,0); // remove time, otherwise yesterday if based off of today could be a month ago.
let todays_date_string = today.toISOString().slice(0, 10);

let yesterday = new Date(todays_date_string);
yesterday.setDate(today.getDate() - 1);
let yesterdays_date_string = yesterday.toISOString().slice(0, 10);

let two_days_ago = new Date(yesterdays_date_string);
two_days_ago.setDate(two_days_ago.getDate() - 1);
let two_days_ago_date_string = two_days_ago.toISOString().slice(0, 10);

let three_days_ago = new Date(two_days_ago_date_string);
three_days_ago.setDate(three_days_ago.getDate() - 1);
let three_days_ago_date_string = three_days_ago.toISOString().slice(0, 10);
console.log({today, today_s: today.toISOString(), todays_date_string, yesterdays_date_string, two_days_ago_date_string, three_days_ago_date_string});

不要把时间归零,昨天是一个月前:

let today = new Date();
//today.setUTCHours(0,0,0); // remove time, otherwise yesterday if based off of today could be a month ago.
let todays_date_string = today.toISOString().slice(0, 10);

let yesterday = new Date(todays_date_string);
yesterday.setDate(today.getDate() - 1);
let yesterdays_date_string = yesterday.toISOString().slice(0, 10);

let two_days_ago = new Date(yesterdays_date_string);
two_days_ago.setDate(two_days_ago.getDate() - 1);
let two_days_ago_date_string = two_days_ago.toISOString().slice(0, 10);

let three_days_ago = new Date(two_days_ago_date_string);
three_days_ago.setDate(three_days_ago.getDate() - 1);
let three_days_ago_date_string = three_days_ago.toISOString().slice(0, 10);
console.log({today, today_s: today.toISOString(), todays_date_string, yesterdays_date_string, two_days_ago_date_string, three_days_ago_date_string});

还要注意,我使用今天来计算昨天的日期,而不是基于今天的日期字符串新创建的昨天,这可能是一个影响因素,但我不认为这会影响昨天的计算,当然也不会影响到那个程度。
对此有何解释?

9vw9lbht

9vw9lbht1#

关键在于:setDate()方法用于更改给定Date示例的月份日期,基于本地时间
让我们来看看一些代码。

const date = new Date('2023-02-01T22:34:47.458Z');
const todayDateString = date.toISOString().slice(0, 10); // 2023-02-01
const todayDateDate = new Date(todayDateString);

todayDateDate.toISOString()的值为2023-02-01T00:00:00.000Z
date.getDate()的值为1
todayDateDate.toString()的值为Tue Jan 31 2023 19:00:00 GMT-0500 (Eastern Standard Time)(这将因您所在的时区而异)。
当地时间是1月31日!
如果您使用setDate(0),它会根据当地时间给出上个月的最后一天,因为当地时间是1月,这意味着当地时间是12月31日,也就是1月1日UTC。
具体结果取决于您所在的时区。

46scxncf

46scxncf2#

当您构建没有显式指定时区的新日期时,例如new Date('2023-02-01'),该日期将以您的本地时区进行解释。
但是当您通过toISOString()字符串化它时,您得到的是UTC时区的日期,这可能是不同的一天(午夜的另一边)。
考虑:

// February 1 in UTC+05:00
const d1 = new Date('2023-02-01T01:00:00+05:00')

// is still January 31 in UTC
console.log(d1.toISOString()); // 2023-01-31T20:00:00.000Z

所以如果
1.您的时区偏移意味着UTC时间仍然是昨天,并且
1.昨天还是1月31日而不是2月1日

  1. setDate(1)表示1月1日:一个月前。

相关问题