【问题标题】:How to parse local time without a date with moment?如何在没有日期的情况下解析当地时间?
【发布时间】:2020-05-13 01:13:56
【问题描述】:

输入 8:30 PM,本地日期为 2020 年 5 月 12 日,而 UTC 日期已为 2020 年 5 月 13 日

期望的输出2020-05-12 20:30:00

实际输出2020-05-13 20:30:00


尝试了 3 件事:

result = moment('8:30 PM', 'h:mm A').format('YYYY-MM-DD HH:mm:ss');

result = moment.tz('8:30 PM', 'h:mm A', 'America/New_York').format('YYYY-MM-DD HH:mm:ss');

moment.tz.setDefault('America/New_York');
result = moment.tz('8:30 PM', 'h:mm A', 'America/New_York').format('YYYY-MM-DD HH:mm:ss');

【问题讨论】:

  • 我没有得到相同的结果,'8:30 PM' 被解析为本地而不是 UTC。
  • @RobG - 我的错,你是对的......但是 - 如果我改变我的时区,我如何设置时刻仍然在“America/New_York”?
  • 检查后我相当确定现在时区插件确实存在问题。它总是使用转发日期。 moment.tz('10:30 PM', 'h:mm A', moment.tz.guess()).format('YYYY-MM-DD') 任何时候总是给出转发日期,而 moment() 没有。虽然是 OP,但你真的不应该这样做,因为如果你以这种形式将它传递给另一台计算机,它会变得模棱两可,没有日期。即:即使此处的 .tz 存在问题,也没有有效的用例以这种方式使用它
  • 似乎当您设置时区并解析时间时,moment.tz 使用当前 UTC 日期作为日期部分,而 moment.js 使用当前本地日期。我猜你宁愿那个 moment.tz 在设定的时区使用当前日期。如果你愿意,可以提交一个错误,但据我所知,moment.js 团队已将注意力转向 Luxon,而 moment.js 处于维护模式,所以如果不是“按设计工作”,那么很可能“不会修复”。 :-/

标签: javascript datetime momentjs moment-timezone


【解决方案1】:

正如 user120242 所说,moment.tz 在从某个时间创建日期时似乎使用当前的 UTC 日期。如果您想使用目标时区中的当前日期,则需要为日期创建一个字符串,添加您的时间字符串然后解析它,例如

moment.tz.setDefault('America/New_York');

let timeString    = '8:30 PM';
let inputFormat   = 'YYYY-MM-DD HH:mm A'
let dateFormat    = 'YYYY-MM-DD';
let displayFormat = 'YYYY-MM-DD HH:mm:ss ZZ';

// Current date in New York
let now = moment();
// Create a timestamp for required time
let nyString = now.format(dateFormat) + ' ' + timeString;
// Create a date for 8:30 in New York
let then = moment(nyString, inputFormat);

console.log('Now in New York    : ' + now.format(displayFormat));
console.log(timeString + ' in New York: ' + then.format(displayFormat));
console.log('Sans kludge in NY  : ' + moment(timeString, 'HH:mm A').format(displayFormat));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.25.3/moment-with-locales.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.28/moment-timezone-with-data.js"></script>

要使其正常工作,您需要将时钟设置为纽约与 UTC 不同的日期。

【讨论】:

    【解决方案2】:

    在那里尝试运行第二段代码时,控制台包含错误。

    Moment Timezone 没有 America/New_York 的数据。见http://momentjs.com/timezone/docs/#/data-loading/

    如果您尚未将一组时区加载到时刻,则它不会有用于解析的数据。在尝试运行任何与时区相关的功能之前,请检查您是否已将时区数据加载到时刻。如果您不确定如何将数据加载到 moment,请查看错误消息中列出的文档部分,here

    【讨论】:

      【解决方案3】:

      请说明您实际解决的是什么问题;
      OP,无论如何你都不应该这样做,因为如果将它发送到另一台计算机,时间就会变得不明确。如果当前时间是上午 12 点或晚上 11 点 59 分,并且人们处于不同的时区,那么您发送的时间就会变得不明确。
      如果您仍然必须这样做,则必须在结果上设置日期,或在计算“所需”日期后手动设置小时和分钟,以始终将其计算为过去 24 小时内的时间。

      是的,时区插件存在问题。实际上,当它是之前的时间时,moment() 也会行为不端。但是我想不出一个有效的用例来以您尝试使用它的方式使用它,并且它的行为方式不再根据您的使用方式来定义。

      问题证明:

      moment.tz.setDefault('America/New_York');
      result = moment.tz('8:30 PM', 'h:mm A', 'America/New_York').format('YYYY-MM-DD HH:mm:ss');
      
      // set your clock to a time when UTC date will be tomorrow (or yesterday) to see the problem
      console.log([result,
      moment('12:01AM', 'h:mm A').format('YYYY-MM-DD HH:mm:ss'),
      moment.tz('12:01 AM', 'h:mm A', moment.tz.guess()).format('YYYY-MM-DD HH:mm:ss'),
      moment('11:59PM', 'h:mm A').format('YYYY-MM-DD HH:mm:ss'),
      moment.tz('11:59 PM', 'h:mm A', moment.tz.guess()).format('YYYY-MM-DD HH:mm:ss')].join('\n')
      )
      <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.25.3/moment-with-locales.min.js" integrity="sha256-8d6kI5cQEwofkZmaPTRbKgyD70GN5mDpTYNP9YWhTlI=" crossorigin="anonymous"></script>
      
      <script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.28/moment-timezone-with-data.js" integrity="sha256-O1PdKrSbpAYWSBteb7yX/CMmHhu3US31mtCbsryGwaY=" crossorigin="anonymous"></script>

      【讨论】:

      • 我认为这是一个有效的做法。通过首先设置时区,它并不模棱两可。例如。在纽约为 08:00 创建日期应使用纽约的当前日期而不是 UTC 或本地日期创建该时间的日期。无论主机设置如何,这都会使结果保持一致(当然,前提是时钟设置正确)。
      猜你喜欢
      • 2023-03-25
      • 1970-01-01
      • 2011-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多