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

Displaying timezone-formatted date as UTC time

本文关键字:UTC 时间 显示 日期 时区 格式      更新时间:2024-06-23

在我的UI上,我尝试根据特定时区显示日期。在本例中,我将使用美洲/纽约作为时区。我就是这么做的。

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

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

例如,如果时间是纽约的中午12:00,那么在将时间发送到后端之前,该时间将被序列化为UTC时间的下午4:00。这是我的尝试:

    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日期,我不知道为什么。如有任何帮助,我们将不胜感激。谢谢

编辑:

尝试遵循以下方法,以下是我所做的:

    $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

几件事:

  • 希望这是一个拼写错误,但要指出的是,区域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函数将产生不同的输出。

为了实现这一点,您需要使用.utcOffset()。这是力矩2.9.0的首选方法。此函数使用UTC的实际偏移量,而不是反向偏移量(例如,夏令时期间纽约为-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()作为setter被弃用。它接受了一个包含时区标识符的字符串(例如,-4小时的"-0400"或"-04:00")或表示UTC后分钟的数字(例如,夏令时期间纽约为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')

要使用命名时区而不是数字偏移,请包括时刻时区并使用.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')