将时区格式的日期显示为UTC时间

时间:2016-04-14 17:57:30

标签: javascript date datetime timezone momentjs

在我的用户界面上,我尝试根据特定时区显示日期。在此示例中,我将使用Americas / New_York作为时区。这就是我做到的。

    $scope.getStartTime = function(){
        var date = new Date();
        return moment(date).tz("Americas/New_York").format('YYYY-MM-DD HH:mm:ss');
    };

之后,我想发送这些数据并将其发送到我的服务器。但是,在我的服务器中,我希望它始终序列化为UTC时间而不是纽约时区(EST)。

例如,如果时间是凌晨12点。在纽约,时间将被序列化到下午4点。在发送到后端之前的UTC时间。这是我的尝试:

    var date = getStartTime();
    ....
    // Display the date in the UI
    ....
    $scope.revertStartTime(date);

    $scope.revertStartTime = function(startTime) {
        console.log("Start time: ", startTime);
        console.log("Moment: ", moment(startTime).format());
        console.log("Converted to utc time: ", moment().utc(startTime).format());
        return moment.utc(startTime).format("YYYY-MM-DD'T'HH:mm:ss.SSSZ");
    }

我尝试使用moment().utc()函数恢复开始时间,并希望日期会更改为基于UTC的日期,但不幸的是,它会将我的日期设置为本地化日期而不是UTC日期和我&#39 ;我不知道为什么。任何帮助,将不胜感激。谢谢!

编辑:

试图遵循以下方法,这就是我所做的:

    $scope.getStartTime = function(){
        var date = new Date();
        var startTime = new moment(date).tz($rootScope.userinfo.timeZone).format('YYYY-MM-DD HH:mm:ss');
        $rootScope.offset = moment().utcOffset(startTime);    
        console.log("offset: ", $rootScope.offset);
        return startTime;
    };

    $scope.revertStartTime = function(startTime) {
        console.log("User Selected Time: ", moment().utcOffset(startTime).format('YYYY-MM-DD HH:mm:ss'));
        return moment().utcOffset(startTime).format('YYYY-MM-DD HH:mm:ss');
    }

但我得到的一个错误是revertStartTime返回Invalid Date

2 个答案:

答案 0 :(得分:2)

一些事情:

  • 希望它是一个错字,但只是要指出,区域ID是America/New_York,而不是Americas/New_York

  • 您可以将值传递为moment.utc(foo)moment(foo).utc(),但不能传递moment().utc(foo)。不同之处在于,将输入解释为UTC并保持UTC模式,而其他只是切换到UTC模式。您也可以将其视为"转换为UTC",但实际上基础时间戳值不会发生变化。

  • 是的,您可以切换到UTC模式和通话格式,但无论您使用何种模式,您都可以拨打.toISOString()。这已经是ISO格式你正在寻找。

  • 请注意,如果您从一个独特的时间点开始,并以转换为UTC结束,则中间没有任何切换时区或偏移量会改变结果。换句话说,这些都是等价的:

    moment().toISOString()
    moment.utc().toISOString()
    moment(new Date()).toISOString()
    moment.utc(new Date()).toISOString()
    moment(new Date()).utc().toISOString()
    moment().tz('America/New_York').toISOString()
    moment.tz('America/New_York').toISOString()
    moment().utcOffset(1234).toISOString()
    moment.utc().format('YYYY-MM-DD[T]HH:mm:ss.SSS[Z]')
    moment().utc().format('YYYY-MM-DD[T]HH:mm:ss.SSS[Z]')
    

    只有最后两个甚至需要处于UTC模式,因为format函数在本地模式或特定时区内会产生不同的输出。

答案 1 :(得分:0)

为了实现这一目标,您需要使用.utcOffset()。这是Moment 2.9.0的首选方法。此函数使用UTC的实际偏移量,而不是反向偏移量(例如,DST期间纽约的-240)。像“+0400”这样的偏移字符串与以前一样工作:

// always "2013-05-23 00:55"
moment(1369266934311).utcOffset(60).format('YYYY-MM-DD HH:mm')
moment(1369266934311).utcOffset('+0100').format('YYYY-MM-DD HH:mm')

Moment.js 2.9.0中较旧的.zone() as a setter 已弃用。它接受包含时区标识符的字符串(例如,“-0400”或“-04:00”-4小时)或代表背后 UTC的数字的数字(例如,在DST期间为纽约的240) )。

// always "2013-05-23 00:55"
moment(1369266934311).zone(-60).format('YYYY-MM-DD HH:mm')
moment(1369266934311).zone('+0100').format('YYYY-MM-DD HH:mm')

要使用已命名的时区而不是数字偏移量,请添加Moment Timezone并使用.tz()代替:

// determines the correct offset for America/Phoenix at the given moment
// always "2013-05-22 16:55"
moment(1369266934311).tz('America/Phoenix').format('YYYY-MM-DD HH:mm')