如何在javascript中获取指定时区的一天的开始时间和结束时间?

Posted

技术标签:

【中文标题】如何在javascript中获取指定时区的一天的开始时间和结束时间?【英文标题】:How to get the start time and end time in utc of a day for a specified timezone in javascript? 【发布时间】:2016-07-02 01:40:30 【问题描述】:

正如标题所述,我想获取某个时区一天的开始时间和结束时间,并将它们转换为 UTC 时间。这是我的实现部分:

//convert current local time to specified timezone time
var converted = moment.tz(moment(), timezone).format("YYYY-MM-DD");
var full_format = "YYYY-MM-DD HH:mm:ss";

// get start time and end time in the timezone
var start = converted + " 00:00:00";
var end = converted + " 23:59:59";

// how to convert them in utc time by momentjs or other methods? 
var utc_start_time = ?
var utc_end_time = ?

问题是如何将某个时区的时间转换为UTC时间。或者还有其他不错的解决方案吗?谢谢!

编辑:

我想出了一种自己制作的方法,但不是很体面。

var converted = moment.tz(moment(), timezone).format("YYYY-MM-DD");         
var full_format = "YYYY-MM-DD HH:mm:ss";
var start = converted + " 00:00:00";
var end = converted + " 23:59:59";
var utc_start_time = moment(start).add(utc_offset * -1, 'hours').format(full_format);
var utc_end_time = moment(end).add(utc_offset * -1, 'hours').format(full_format); 

欢迎提出任何改进建议。谢谢

【问题讨论】:

How do you convert a javascript date to UTC?的可能重复 您是否要计算它们之间的差距? 问题与 [如何将 JavaScript 日期转换为 UTC? ](***.com/questions/948532/…)。处理时间不包含任何时区信息。 @Zamboney 不,只是想获取转换时间的 UTC 时间。 this 有帮助吗? 【参考方案1】:

取决于你到底想做什么:

// for the current day
var start = moment.tz(timezone).startOf('day').utc();
var end = moment.tz(timezone).endOf('day').utc();

// for a specific moment (m)
var start = m.clone().tz(timezone).startOf('day').utc();
var end = m.clone().tz(timezone).endOf('day').utc();

// for a specific calendar date
var m = moment.tz(date, format, timezone);
var start = m.clone().startOf('day').utc();
var end = m.clone().endOf('day').utc();

然后,您可以使用format 函数随意格式化startend

还请记住,并非每个时区的每一天都从午夜开始,也不是所有当地日子都有 24 小时。

【讨论】:

再次感谢您的回复。它确实回答了我的问题。我应该在询问之前阅读文档。但是你能给我一个例子,说明一天不是从凌晨 12 点开始或没有 24 小时的情况。 任何有时区转换的日子,尤其是那些与daylight saving time 相关的日子,按当地时钟计算可能多于或少于 24 小时。在午夜有向前移动的时区将跳过午夜。巴西就是一个很好的例子。考虑一下October 16, 2016, the day will start at 1:00 in São Paulo, Brazil【参考方案2】:

这是一个使用Intl.DateTimeFormat 处理时区的原生解决方案。

它可以找到指定时区的一天的开始/结束。

要将Date 实例转换为UTC 时间,请使用Date.prototype.toISOString。

const beginingOfDay = (options = ) => 
  const  date = new Date(), timeZone  = options;
  const parts = Intl.DateTimeFormat("en-US", 
    timeZone,
    hourCycle: "h23",
    hour: "numeric",
    minute: "numeric",
    second: "numeric",
  ).formatToParts(date);
  const hour = parseInt(parts.find((i) => i.type === "hour").value);
  const minute = parseInt(parts.find((i) => i.type === "minute").value);
  const second = parseInt(parts.find((i) => i.type === "second").value);
  return new Date(
    1000 *
      Math.floor(
        (date - hour * 3600000 - minute * 60000 - second * 1000) / 1000
      )
  );
;

const endOfDay = (...args) =>
  new Date(beginingOfDay(...args).getTime() + 86399999);

const beginingOfYear = () => ;

console.log(beginingOfDay( timeZone: "GMT" ));
console.log(endOfDay( timeZone: "GMT" ));
console.log(beginingOfDay( timeZone: "Asia/Tokyo" ));
console.log(endOfDay( timeZone: "Asia/Tokyo" ));

【讨论】:

在实行夏令时的地方,这个答案在夏令时转换日之后的任何时间都是错误的,因为它应用了错误的偏移量。更改前一天的开始时间与更改后一天的其余时间有不同的偏移量。【参考方案3】:

我也遇到了这个问题。不幸的是,moment.js 似乎在告诉人们使用其他选项。 (从他们的网站来看,我猜他们更关注美国政治,呃)。此外,现在已弃用已接受答案中的许多 moemt 函数。 Luxon 是当时建议作为替代方案的第一个库。

let DateTime = luxon.DateTime;

var dt = DateTime.local() // get the current time in local timezone
  .startOf('day')         // set the time to the start of the current day
  .setZone('GMT');        // change time zone back to GMT (zero offset)
console.log('Start: ' + dt.toISO());  // UTC equivalent for local start of day

var dt = DateTime.local() // get the current time in local timezone
  .endOf('day')           // set the time to the end of the current day
  .setZone('GMT');        // change time zone back to GMT (zero offset)
console.log('End  : ' + dt.toISO());  // UTC equivalent for local end of day (1 ms before midnight)
<script src="https://cdn.jsdelivr.net/npm/luxon@1.22.2/build/global/luxon.min.js"></script>

【讨论】:

Matt's answer 中的所有方法目前都没有被弃用。但是,根据project status page,Moment.js 作为一个库已经“完成”并且处于维护模式。鉴于Temporal proposal 将补充(实际上几乎全部替换)内置日期,我怀疑日期在很长一段时间内都不会改变(在过去 25 年中没有显着变化)所以那一刻.js 将在类似的时间内继续工作。 :-)

以上是关于如何在javascript中获取指定时区的一天的开始时间和结束时间?的主要内容,如果未能解决你的问题,请参考以下文章

Rails:在时区获取#beginning_of_day

SQL语句 如何取得指定月份的最后一天的日期

如何在跨越多天的时间安排中获取一天的结束时间

如何按日期分组,考虑时区和 DST?

在JavaAndroid中获取开始和结束的一天的纪元第二。

java如何获取某一天的日期?