Moment.js转换为日期对象


696

使用Moment.js,我无法将正确的矩对象转换为具有时区的日期对象。我找不到正确的日期。

例:

var oldDate = new Date(),
    momentObj = moment(oldDate).tz("MST7MDT"),
    newDate = momentObj.toDate();
console.log("start date " + oldDate)
console.log("Format from moment with offset " + momentObj.format())
console.log("Format from moment without offset " + momentObj.utc().format())
console.log("(Date object) Time with offset " + newDate)
console.log("(Date object) Time without offset "+ moment.utc(newDate).toDate())

1
您期望什么输出,您会得到什么输出?
菲利克斯·克林

4
第4行让我这样输出:<code>(日期对象),偏移时间Thu Aug 01 2013 15:23:49 GMT + 0300(Финляндия(лето))</ code>但时区必须为MST7MDT
vadim.zhiltsov

Wednesday 24th 2019, 12:47:48 am这可能转换成2019-04-23T19:17:48.000Z 吗?@ vadim.zhiltsov
Anupam Maurya

日期对象没有时区,只是从1970-01-01T00:00:00Z的偏移量。因此,当您调用toDate时,返回的对象会丢失您使用附加到此刻对象的时区信息.tz("MST7MDT")。这就是为什么存在诸如moment.tz之类的库的原因,以补充仅了解UTC和主机时区的内置Date对象的基本功能。
RobG

Answers:


1232

使用它可以将矩对象转换为日期对象:

http://momentjs.com/docs/#/displaying/as-javascript-date/

moment().toDate();

产量:

Tue Nov 04 2014 14:04:01 GMT-0600 (CST)

11
@Spencer-是的,它会回答标题,并且toDate确实是如何从中获取Date对象的方法moment。但是问题正文中的代码询问有关时区转换的问题- Date不能这样做。除非山区时间确实是用户的时区,否则我不确定这将如何回答问题。
马特·约翰逊·品脱

1
@Matt取决于您正在查看的问题的哪一部分。大多数人在google中搜索Google,发现该标题与他们的问题保持一致,并赞成回答标题的答案,而不是问题的正文。这也许可以解释为什么即使在技术上对OP并没有帮助,但为什么投票最多。
斯宾塞

14
这实际上是正确的答案吗?问题是如何使用TIMEZONE将moment对象转换为javascript日期。当更改为javascript日期对象时,它仍会还原为本地时区。
无法说

1
大家看一下这个链接momentjs.com/guides/#/warnings/js-date。不建议这样做,并将在即将发布的主要版本中将其删除。
gtzinos

3
@gtzinos您要链接和引用的是一个单独的问题和场景,例如,将字符串传递到构造函数的那一刻moment("12/12/2011"),您将在其中获得该消息。它与从现在到现在都没有关系objmoment().toDate()
btbJosh

51

只要您使用所需区域的数据初始化了moment-timezone,您的代码就会按预期工作。

您正在正确地将矩转换为时区,这反映在来自输出的第二行中 momentObj.format()

切换到UTC不仅会减少偏移量,还会改回到UTC时区。如果要执行此操作,则根本不需要原始.tz()呼叫。你可以做moment.utc()

也许您只是想更改输出格式字符串?如果是这样,只需为format方法指定所需的参数:

momentObj.format("YYYY-MM-DD HH:mm:ss")

关于代码的最后一行-当您Date使用时返回一个对象时toDate(),您将放弃moment.js的行为,而回到JavaScript的行为。JavaScriptDate对象将始终在运行它的计算机的本地时区中打印。瞬间没有任何办法。js对此无能为力。

其他一些小事情:

  • 虽然构造函数可以使用Date,但通常最好不要使用。对于“ now”,请不要使用moment(new Date())。而是使用moment()。两者都可以,但是不必要地多余。如果您要从字符串中进行解析,请将该字符串直接传递给moment。不要试图先解析它Date。您会发现瞬间的解析器更加可靠。

  • 像这样的时区MST7MDT是出于向后兼容的原因。它们源自POSIX样式的时区,并且只有少数几个在TZDB数据中。除非绝对必要,否则应使用诸如的键America/Denver


谢谢马特!您的回答很有用。正如您提到的使用America / Denver而不是MST7MDT一样,这些映射是否有可用的地图?我正在使用很多这样的时区,例如CET,EET,EST5EDT,CST6CDT,PST8PDT。
monish001 2014年

是否可以将例如:“ 10:20 AM”(从moment()。format('hh:mm A')获得的字符串时间)转换为Date对象?
ram

2
@ram-1)如果有时间,请使用.toDate()。2)不要使用评论来提出新问题。这就是大的“询问问题”按钮的用途。
Matt Johnson-Pint 2014年

22

.toDate 并没有真正为我工作,所以,这就是我所做的:

futureStartAtDate = new Date(moment().locale("en").add(1, 'd').format("MMM DD, YYYY HH:MM"))

希望这可以帮助


2
这个答案没有回答问题。该代码是漫长的写作方式moment().add(1, 'd').toDate()
RobG

12

由于momentjs无法控制javascript日期对象,因此我找到了解决方法。

const currentTime = new Date();    
const convertTime = moment(currentTime).tz(timezone).format("YYYY-MM-DD HH:mm:ss");
const convertTimeObject = new Date(convertTime);

这将为您提供一个带有转换时间的javascript date对象


2
这是直接回答问题的唯一正确答案。
阿尼斯·萨那

1
这正是我想要的。我期望本地日期能正确表示时区,但可悲的是我错了。
mklbtz

1
Safari不支持格式“ YYYY-MM-DD HH:mm:ss”,因此结果为null。格式应为“ YYYY-MM-DDTHH:mm:ss”(使用ECMAScript支持的格式,日期和时间部分之间应使用“ T”)。
RobG

4

我需要在日期字符串中包含时区信息。我原本使用的是,moment.tz(dateStr, 'America/New_York').toString();但后来开始收到有关将该字符串反馈回瞬间的错误。

我尝试了,moment.tz(dateStr, 'America/New_York').toDate();但随后却丢失了所需的时区信息。

返回带有时区的可用日期字符串的唯一解决方案是moment.tz(dateStr, 'America/New_York').format();



3

要转换任何日期,例如utc:

moment( moment().utc().format( "YYYY-MM-DD HH:mm:ss" )).toDate()

2
这真的挽救了我的一天!
HV Sharma

这个答案是错误的。它应用两次时区偏移:moment().utc()返回UTC的值,然后.format( "YYYY-MM-DD HH:mm:ss" )返回已设置为UTC且没有时区偏移的字符串,因此将其解析为本地。它与默认的时间格式不匹配,因此由内置的解析器进行解析。它也不匹配任何ECMAScript支持的格式,因此解析取决于实现。无论如何,它将被解析为本地,因此在创建日期的时间值时会再次应用时区偏移。
RobG

3

这个问题有点晦涩。我会尽力解释这一点。首先,您应该了解如何使用moment-timezone。根据这里的答案, TypeError:moment()。tz不是一个函数,您必须从moment-timezone而不是默认矩中导入moment(当然,您必须首先npm安装moment-timezone!)。为清楚起见,

const moment=require('moment-timezone')//import from moment-timezone

现在,为了使用时区功能,请使用moment.tz(“ date_string / moment()”,“ time_zone”)(有关更多详细信息,请访问https://momentjs.com/timezone/)。此函数将返回具有特定时区的矩对象。为清楚起见,

var newYork= moment.tz("2014-06-01 12:00", "America/New_York");/*this code will consider NewYork as the timezone.*/

现在,当您尝试将带有矩的toDate()(ISO 8601格式转换)的newYork(矩对象)转换为英国格林威治时间时。有关更多详细信息,请浏览有关UTC的这篇文章https://www.nhc.noaa.gov/aboututc.shtml。但是,如果您只想以这种格式(根据本示例,为纽约时间)来安排当地时间,则只需将带有arg true的.utc(true)方法添加到moment对象。为清楚起见,

newYork.toDate()//will give you the Greenwich ,UK, time.

newYork.utc(true).toDate()//will give you the local time. according to the moment.tz method arg we specified above, it is 12:00.you can ofcourse change this by using moment()

简而言之,moment.tz会考虑您指定的时区,并将本地时间与格林威治时间进行比较,以得出结果。我希望这是有用的。


2

此刻已更新了截至2018年6月6日的js库。

var newYork    = moment.tz("2014-06-01 12:00", "America/New_York");
var losAngeles = newYork.clone().tz("America/Los_Angeles");
var london     = newYork.clone().tz("Europe/London");

newYork.format();    // 2014-06-01T12:00:00-04:00
losAngeles.format(); // 2014-06-01T09:00:00-07:00
london.format();     // 2014-06-01T17:00:00+01:00

如果您可以自由使用Angular5 +,则最好使用此处的datePipe功能,而不要使用此处的时区功能。我必须使用moment.js,因为我的项目仅限于Angular2。


1

尝试(无format步骤)

new Date(moment())


new Date(moment())等同于new Date()。时区仅设置为d
RobG
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.