我正在尝试从一个时区转换为另一个时区(手动)以获取Date对象,并通过此函数返回另一个时区:
getDateInMomentFormatToSave: function (date) {
function padNums(num) {
return num.toString().length == 1 ? "0" + num : num;
}
var month = padNums(date.getMonth() + 1);
var day = padNums(date.getDate());
var hour = padNums(date.getHours());
var minutes = padNums(date.getMinutes());
var result = moment(date.getFullYear() + "-" + month + "-" + day + " " + hour + ":" + minutes, "YYYY-MM-DD HH:mm");
var sourceMoment = moment.tz(result, "America/Mexico_City"); //UTC neutro de la BD moment.tz.guess()
var localMoment = sourceMoment.clone().tz("Europe/Lisbon").format('YYYY-MM-DD[T]HH:mm:ss');
return new Date(localMoment.substring(0, 19));
}
一个例子是:
为什么墨西哥->里斯本仅提前1小时?据我所知,localmoment应该是“ 2018-08-17T20:36:00”。
我在做什么错?这似乎适用于欧洲/里斯本到欧洲/马德里,但我不知道为什么。
谢谢。
解决方案:
var result = moment.tz(date.getFullYear() + "-" + month + "-" + day + " " + hour + ":" + minutes, "America/Mexico_City");
var localMoment = result.clone().tz("Europe/Lisbon").format('YYYY-MM-DD[T]HH:mm:ss');
答案 0 :(得分:1)
Date
对象不能永远表示任意时区中的时间。自1970年1月1日00:00:00 UTC以来,它内部跟踪毫秒。显示非UTC时间的功能始终在UTC和执行代码的计算机的 local 时区之间进行转换。无论您是利用瞬间来操纵事物还是其他技术,任何尝试返回位于其他时区的Date
对象的尝试最终都会失败,因为您无法绕开本地时区的行为
此外,在使用Moment时,您不应该对输入和输出进行过多的手动操作,例如您要从日期部分手动创建然后再次解析的字符串。时刻可以为您处理这些事情。
在构造Date
对象时,可以使用moment
对象作为输入,但这将用于从Date
对象保持的UTC瞬间进行转换。您可以从本地时间或UTC时间构造Date
对象,但不能从任意时区构造对象。因此,如果源是America/Mexico_City
对象,则不能断言Date
作为输入时区。取而代之的是,您可以传递字符串,数组,带有单个部分的整数,或者传递创建文档中描述的moment
对象的任何其他方法。
同样,如果您希望Date
对象反映任意时区,则永远不能输出。尽管力矩确实具有.toDate()
函数,但是它将基于力矩的UTC时间构造(由于Date
对象的限制)。换句话说,moment(someDateObject).tz(someTimeZone).toDate()
之类的代码只会导致您以someDateObject
开始使用相同的代码-不管经过的时区如何。
使用字符串从一个时区转换为另一个时区的代码如下:
moment.tz("2018-08-17 14:36:25", "YYYY-MM-DD HH:mm:ss", "America/Mexico_City")
.tz("Europe/Lisbon").format("YYYY-MM-DD HH:mm:ss")
//=> "2018-08-17 20:36:25"
使用数组的相同代码如下:
moment.tz([2018, 7, 17, 14, 36, 25, 0], "America/Mexico_City")
.tz("Europe/Lisbon").toArray()
//=> [2018, 7, 17, 20, 36, 25, 0] (note months are 0-11)
但是现在看看我们是否使用Date
对象,那怎么行呢:
moment.tz(new Date(2018, 7, 17, 14, 36, 25, 0), "America/Mexico_City")
.tz("Europe/Lisbon").toDate()
//=> Fri Aug 17 2018 14:36:25 GMT-0700 (Pacific Daylight Time)
因为我的计算机处于太平洋时间,所以输入日期被视为太平洋时间(不是墨西哥城),输出日期被显示为太平洋时间(不是里斯本)。即使我试图调整时间以匹配其他时区,它仍然会显示GMT-0700
和Pacific Daylight Time
。更重要的是,无论是否在其他时区都适用,它仍将使用太平洋标准时间和太平洋夏令时间之间的DST转换。
这说明了Date
对象的时区限制。 moment
对象没有这样的限制。
最后,如果要编写仅针对现代浏览器或Node.js的新应用程序,Moment团队建议改为使用Luxon。它的时区支持由环境而不是数据文件提供,因此它要小得多。