【问题标题】:Using Moment.js like PHP's date and strtotime使用像 PHP 的 date 和 strtotime 这样的 Moment.js
【发布时间】:2015-11-04 02:27:48
【问题描述】:

我是一个典型的服务器端开发人员,我感觉有点像一条离开水的鱼,试图在前端显示时间值。如何从 moment.js 中获取 PHP 的 date() 和 strtotime() 函数之类的行为?我只想让 unix 时间戳以 H:i:s 格式出现,反之亦然。

到目前为止,我已经从现有示例代码和文档中尝试了以下内容:

moment(timestamp).format(H:i:s);
moment().duration(timestamp).format(H:i:s);
moment.unix(timestamp).format(h:mm:ss);
moment(formatted,'H:i:s');

没有一个可以正常工作。这可能会被标记为重复,因为那里有很多 moment.js 问题,但我不知道它是对库本身的更新还是略有不同的上下文,我还没有找到一个对我有用的现有解决方案。

有人对这两个简单的任务有什么建议吗?

编辑: 我从中提炼出两个不同的问题。一个是文档 say 应该起作用的那一刻的功能给出了奇怪的值:

moment(1437462000).format('h:mm:ss')

例如,应该返回 7:00:00 UTC,返回 10:17:42。在这种情况下,可以通过使用 moment.unix(1437462000).utc().format('h:mm:ss') 来解决此问题,但这会导致第二个问题 - .utc() 函数似乎被忽略了从日期转换回时间戳时:

timestamp = moment(formatted,'DD/MM/YYYY H:m:s').utc().unix();

无论是否包含 .utc() 函数,仍将返回一个时区校正值(在我的情况下,这是不正确的几个小时,因为有问题的格式化时间与客户端计算机无关)。

【问题讨论】:

  • 您是否将函数的结果放在屏幕上?还是您正在生成一个用于其他功能的值?
  • 在尝试将时间戳转换为格式化时间的情况下,它是为了显示。对于另一种方式(格式化为时间戳)的情况,它是解析用户输入以供函数使用。
  • 文档声明它应该是“时刻(时间戳)”或moment.unix(timestamp)。这些价值观有多错误?你有多确定你的时间戳是正确的?
  • moment(timestamp) 为我返回了非常奇怪的值。 moment.unix(timestamp) 返回大致正确的东西,但它已经关闭了 4 小时。似乎是时区问题。我知道时间戳是正确的,因为 PHP 的 date() 在同一页面上格式化了相同的时间戳。

标签: javascript php jquery date momentjs


【解决方案1】:

对于任何进入并仍在寻找 date() 和 strtotime() 的直接 PHP 等效项的人,这里是我最终使用的那些。匹配 php 基本上意味着通过确保一切都在 UTC 中完全忽略任何类型的本地时间信息。但是,timestamp->datedate->timestamp 情况之间的任务略有不同,因此您必须小心。

日期()

将时间戳转换为格式化日期,无需任何客户端时区校正

var formatted = moment.unix(timestamp).utc().format('h:mm:ss');

strtotime()

将 UTC 格式的日期转换回时间戳而不将其更正为本地时间:

var new_timestamp = moment.utc(formatted_utc,'DD/MM/YYYY H:m:s').format('X')
//where 'DD/MM/YYYY H:m:s' is the formatted date's format, and 
//'X' outputs a unix timestamp without milliseconds. 

注意事项:

  • 不要在调用中使用带括号的 moment(): moment().utc(date,format) 将返回本地时间值,而不是您的 输入。
  • Moment.js 不喜欢在格式化中使用“i”表示分钟, 不像 php。

【讨论】:

  • 您应该意识到的一点是.format('X') 返回一个字符串,而.unix() 返回与数字 相同的值。使用对您的方案最方便的方法。
【解决方案2】:

你应该意识到的一些事情:

  1. Unix 时间戳应该总是以 UTC 表示。它们永远不会以数字形式针对时区进行调整。如果它们针对时区进行了调整,那是在解释数字时完成的,而不是在其表示中。

  2. 虽然传统上“Unix 时间戳”以 为单位,但许多环境使用 毫秒。 PHP 的 date 时间戳基于秒,而 moment 和 JavaScript 的 Date 对象都默认使用 毫秒。使用moment.unix 函数可以让您通过秒,这与将时间戳乘以 1000 相同。

  3. Moment 有两种内置模式,localUTC。默认模式是本地。无论您提供什么输入,如果您不指定 UTC,则将时刻调整为本地。要指定 UTC,请使用 utc 函数。该函数有两种形式:

    moment.utc(input)   // parsing form
    
    moment(input).utc() // conversion form
    

    两种形式都需要一些输入,并在 UTC 模式下产生片刻。区别在于输入的解释方式。在任何一种情况下,如果输入值是明确的,则结果是相同的。对于字符串,这意味着输入将包含 Z(来自 ISO8601)或基于 UTC 的偏移量。所有其他形式都是模棱两可的。例如,如果我通过"2015-11-08 01:23:45",我将得到不同的结果,具体取决于我将该字符串解释为本地时间还是UTC。

    对于数字,它们总是解释为 UTC 中的毫秒数。但是,如果您使用 moment(number) 而不调用 .utc(),则该时刻将处于 本地 模式,因此任何输出都将显示为本地时间。

  4. 当您调用moment.unix(input) 时,输入的是秒数,但该时刻处于本地 模式。因此,要显示 UTC 时间,您可以使用 moment.unix(input).utc()

  5. 如果您从其他系统中预先记录的时间戳是数字形式,但已从 UTC 进行调整,则它们不正确。您有错误的数据,而 Moment 无法帮助您,除非您明确他们已经偏离并且您编写代码来抵消它。

  6. Moment 的格式化程序区分大小写。 M 是月,m 是分钟。 H 是 24 小时制的小时数,h 是 12 小时制的小时数。如果要包含零填充,请使用两个连续的字母。例如,HH:mm:ss 对应于13:02:03,而h:m:s 对应于1:2:3

  7. Moment 的 X 格式化程序不关心时刻处于哪种模式。它总是会以 UTC 格式发出秒数。同样,x 格式化程序返回 UTC 毫秒数,moment.valueOf() 也是如此。

另外,你的最后一个例子:

moment.unix(1437462000).utc().format()

返回 "2015-07-21T07:00:00+00:00" - 我相信这是您期望的值。

无论您尝试哪种方式,您都会得到相同的原始时间戳:

moment.unix(1437462000).utc().format("X") // "1437462000"
moment.unix(1437462000).format("X")       // "1437462000"
moment.unix(1437462000).utc().unix()      // 1437462000
moment.unix(1437462000).unix()            // 1437462000

【讨论】:

  • 感谢您的详细解答!不幸的是,它仍然缺少我仍在努力解决的一件事:将 格式化 UTC 时间恢复为时间戳。我试过这个:new_timestamp = moment(formatted_utc_datetime,'DD/MM/YYYY H:m:s').utc().unix(),但尽管有 .utc 函数,它仍然返回一个本地更正的时间戳:例如,7:00 变成 11:00。有什么建议吗?
  • 好的,我已经使用了:moment.utc(formatted,'DD/MM/YYYY H:m:s').format('X')。你的回答是最完整的,所以我会接受它。
  • 没错。您希望输入字符串被解释为 UTC,因此您使用解析形式,而不是转换形式。
  • 如果我能再得到你的帮助,你能解释一下为什么 moment().utc(formatted, 'format').format('X') 不起作用吗?带括号的 moment() 是否调用当前时间并覆盖 utc() 函数?
  • moment() 获取当前时间。在现有 moment 对象上调用 .utc() 是一种转换方法。它不接受任何参数,因此如果您传递任何参数,它们将被忽略。只有moment.utc(...)(解析形式)接受参数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-21
  • 1970-01-01
相关资源
最近更新 更多