使用 Moment.js 就像 PHP 的日期和 strtotime

Using Moment.js like PHP's date and strtotime

我是一名典型的服务器端开发人员,感觉有点像离开水的鱼,试图在前端显示时间值。我怎样才能从 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 问题,但我不知道它是对库本身的更新还是稍微不同的上下文,我还没有找到一个适用的现有解决方案我。

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

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

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

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

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

仍然 return 时区校正值(在我的例子中,这是不正确的几个小时,因为所讨论的格式化时间与客户端计算机无关)无论 .utc() 函数是否是否包括在内。

你应该意识到的几件事:

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

  2. 虽然传统上 "Unix Timestamp" 以 表示,但许多环境使用 毫秒 来代替。 PHP的date时间戳是基于秒的,而moment和JavaScript的Date对象都默认使用毫秒。使用 moment.unix 函数会让你秒过去,等同于将时间戳乘以 1000。

  3. Moment 有两种内置模式,本地UTC。默认模式是 local。无论您提供什么输入,如果您不指定 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(),那么时刻将保留在 local 模式,因此任何输出都将显示为当地时间。

  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:03h:m:s 对应 1:2:3

  7. Moment 的 X 格式化程序不关心 moment 处于哪种模式。它将始终以 UTC 格式发出秒数。同样,UTC 中的 x 格式化程序 returns 毫秒,moment.valueOf().

  8. 也是如此

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

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

Returns "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

对于任何进来并且仍在寻找 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) 将 return 本地时间值,而不是你的 输入。
  • Moment.js 不喜欢在格式中使用 'i' 分钟, 不像 php.