使用 moment.js 时区获取另一个时区的极值(但答案为 UTC)

Using moment.js timezone to get day extremes in another timezone (but the answer in UTC)

我想计算出某一天的极值(午夜到午夜),那一天是相对于现在的整数天数(即相对于 Date.now())...但是对于与 UTC 不同的时区。但我想要以 UTC 时间返回的答案(午夜时间)(以毫秒为单位,类似于你使用 Date.now() 得到的结果),这样我就可以将它们提供给需要 UTC 时间的 API,以获得准确的数据时间范围。我试过使用 moment.js timezone but am getting horribly stuck... I found 但它在不同的时区不起作用。

Moment 可以让您相当轻松地做到这一点:

function getUTCMidnightMillis(timezone, days_ago) {
  return moment()               // Current time.
    .tz(timezone)               // Convert to desired timezone.
    .subtract(days_ago, 'days') // Go back x days.
    .startOf('day')             // Get start of day, aka Midnight!
    .utc()                      // Convert value into UTC.
    .valueOf()                  // Return milliseconds since unix epoch.
}

console.log("Midnight in Denver:", getUTCMidnightMillis("America/Denver", 0))
console.log("Midnight in New York:", getUTCMidnightMillis("America/New_York", 0))

产生输出:

Midnight in Denver: 1594274400000
Midnight in New York: 1594267200000

确实,您可以验证这是正确的:

new Date(1594274400000).toISOString()
// Produces: "2020-07-09T06:00:00.000Z"

2020 年 7 月 9 日,我们观察到丹佛的夏令时,使我们的 UTC 偏移 -6 小时。所以上面的时间戳(世界标准时间上午 6:00)与丹佛午夜的时间相同。

我建议您考虑使用 Luxon,它实际上是 moment.js 的替代品。

算法是在需要的代表位置创建一个现在的日期,减去需要的天数,然后设置为一天的开始,然后得到时间值,例如

let DateTime = luxon.DateTime;

// Create date for 00:00:00 3 days ago in Denver
let d = DateTime.local()                   // Create a date
                .setZone('America/Denver') // Set to Denver
                .minus({days:3})           // Subtract 3 days
                .startOf('day');           // Set to start of day
// Create date for end of day
let e = d.endOf('day');

// Denver 3 days ago at start and end of day
console.log('Start of day: ' + d.toISO() + '\nTime value  : ' + d.ts);
console.log('End   of day: ' + e.toISO() + '\ntime value  : ' + e.ts);
<script src="https://cdn.jsdelivr.net/npm/luxon@1.24.1/build/global/luxon.min.js"></script>

请注意,由于偏移差异,丹佛的 3 天前可能与主机系统中的 3 天前不同。例如,在澳大利亚悉尼,7 月 20 日上午 9 点在丹佛是 7 月 19 日下午 5 点,因此在悉尼减去 3 天是 7 月 17 日,但在丹佛是 7 月 16 日。