ember.js Javascript中区分时区的日期比较

wlp8pajw  于 2022-11-23  发布在  Java
关注(0)|答案(1)|浏览(114)

我正在Ember应用程序中用Javascript来计算两个日历日期之间的差异。
现在,大多数提供了所需的结果,唯一的问题是,我需要处理计算两个日期之间的差异,这是敏感的时区(而不是本地时区的浏览器)。
据我所知,JS的日期是以UTC来追踪的,日期对象本身没有存储时区。我在JS中所做的任何时区本地化都是输出字符串。有没有一个好的库或方法来实现differenceInCalendarDays,同时考虑时区?

const daysAgo = this.intl.formatRelative(-differenceInCalendarDays(new Date(), someOtherDay), {
    unit: 'day', 
    numeric: 'auto', 
    timeZone: 'this.intl.timeZone
});

这是我正在做的一个小示例,显然differenceInCalendarDays将解析为一个不考虑任何时区的数字。differenceInDays的文档对浏览器的本地时间是时区敏感的(这在这里没有帮助),但是differenceInCalendarDays没有这样的说明。任何帮助都将非常感谢!

dpiehjr4

dpiehjr41#

从逻辑上讲,两个日历日期(如2020-01-012020-01-02)之间的差异不区分时区,也根本不涉及时间。它正好是一天。在此上下文中,一天不是24小时,而是一年的逻辑划分。可以将其视为纸质日历上的一个正方形。
然而,在任何给定的时刻,两个不同的时区可能在同一个日历日期,或者它们可能在两个不同的日历日期。因此,当确定日期是“现在”(或“今天”、“昨天”、“明天”等)时,时区很重要。
为了说明这两点并希望回答您的问题,可以使用以下代码来获取给定时区中自“today”以来经过的天数:

function daysSince(year, month, day, timeZone) {

  // Create a DateTimeFormat object for the given time zone.
  // Force 'en' for English to prevent issues with languages that don't use Arabic numerals.
  const formatter = new Intl.DateTimeFormat('en', { timeZone });
  
  // Format "now" to a parts array, then pull out each part.
  const todayParts = formatter.formatToParts();  // now is the default when no Date object is passed.
  const todayYear = todayParts.find(x=> x.type === 'year').value;
  const todayMonth = todayParts.find(x=> x.type === 'month').value;
  const todayDay = todayParts.find(x=> x.type === 'day').value;
  
  // Make a pseudo-timestamp from those parts, abusing Date.UTC.
  // Note we are intentionally lying - this is not actually UTC or a Unix/Epoch timestamp.
  const todayTimestamp = Date.UTC(+todayYear, todayMonth-1, +todayDay);

  // Make another timestamp from the function input values using the same approach.
  const otherTimestamp = Date.UTC(+year, month-1, +day);

  // Since the context is the same, we can subtract and divide to get number of days.
  return (todayTimestamp - otherTimestamp) / 864e5;
}

// example usage:
console.log("US Pacific: " + daysSince(2020, 1, 1, 'America/Los_Angeles'));
console.log("Japan: " + daysSince(2020, 1, 1, 'Asia/Tokyo'));

此方法仅在UTC没有转换(如DST或标准时间偏移量的更改)时有效。
还要注意,这里我没有使用Date对象,因为我们必须非常小心地考虑这些对象是如何构造的。如果您只有一个来自日期选择器UI的Date对象,则该对象很可能是采用本地时间创建的--而不是特定时区的时间。因此,您需要提取year、month和天,然后再继续。例如:

daysSince(dt.getFullYear(), dt.getMonth() + 1, dt.getDate(), 'America/New_York');

请密切注意+1和-1。Date对象使用从0开始的月份,但我更喜欢从1开始的月份。

相关问题