时区解析地狱

时间:2013-07-09 16:01:16

标签: javascript momentjs

我有这个ISO日期:

var v = '2013-07-09T13:27:29.000Z';

如果我这样做:

var g = moment(v).format();

控制台将g值作为正确的当地时间 2013-07-08T17:25:08-03:00

但如果我这样做是为了得到时间:

console.log(moment(g).startOf('day').fromNow());

Moments使用原始v ISO而不是格式化的g来计算前一段时间。

为什么?

编辑:我已经测试了另一个时间插件(jquery.timeago),并且在传递原始v值时会发生解析为本地时间的相同错误。

我在这里做错了什么?此代码正在客户端执行,因此所有插件都应为用户返回正确的本地时间。

编辑2 :有关我正在尝试做的更多相关信息:

var v = notifs.ntime; //2013-07-09T13:27:29.000Z
var m = moment(v).zone(v).format(); // 2013-07-09T13:27:29+00:00 (wrong local)
var m2 = moment(v).format();  // 2013-07-09 10:27:29 (correct local)
var r = moment(v).zone(v).startOf('day').fromNow() // 21 hours ago (wrong)
var r2 = moment(v).startOf('day').fromNow() // 18 hours ago (wrong)
console.log(v);
console.log(m);
console.log(m2);
console.log(r);
console.log(r2);
console.log('-------------------');
/*
    2013-07-09T13:27:29.000Z                            
    2013-07-09T13:27:29+00:00                           
    2013-07-09T10:27:29-03:00                           
    21 hours ago                        
    18 hours ago                            
    -------------------

    I expected "8 hours ago" as now is 18:10 and (v) was set on 10:27 (m2)
*/

1 个答案:

答案 0 :(得分:3)

我不太确定我是否按照您的要求进行操作。

通过使用g变量,您基本上就是这样做的:

moment(moment(v).format()).startOf('day').fromNow()

这有点多余。与此完全相同:

moment(v).startOf('day').fromNow()

这将告诉您从v落入的本地日开始到现在已经过了多长时间。

如果您正在寻找从v落入的 UTC 日开始之间经过的时间,请改用:

moment.utc(v).startOf('day').fromNow()

或者使用稍微不同的语法,但效果相同:

moment(v).utc().startOf('day').fromNow()

如果您正在寻找其他内容,请澄清。

操作实例

让我们来看看在计算机上运行原始代码时会发生什么。我在美国亚利桑那州,这是UTC-7,没有夏令时。

// we'll start with the string you provided
var v = '2013-07-09T13:27:29.000Z';

// and the redundant moment, but we'll take a look at the formatting
var g = moment(v).format();

console.log(g);                 // 2013-07-09T06:27:29-07:00
console.log(moment(g).format()) // 2013-07-09T06:27:29-07:00  (it didn't change)

// start of the local day is midnight in the local time zone
console.log(moment(g).startOf('day').format())  // 2013-07-09T00:00:00-07:00

// here's my time right now
console.log(moment().format())  // 2013-07-09T13:56:54-07:00

// and your final bit of code
console.log(moment(g).startOf('day').fromNow());  // 14 hours ago

正如您所看到的那样,在确定一天的开始时使用本地时区正确执行。当然,当你在不同的时区运行它时,它会返回不同的结果。那是因为每个时区都有自己每天的概念。如果您想要一致的输出,那么您将删除startOf('day')来电。

建议

在您上次更新后说明您预计会有8个小时,那么您似乎根本不想要startOf('day')的时间。就这样做:

moment(v).fromNow()

也无需涉及.zone()