.NET日期,Moment.js,UTC和时区转换

时间:2018-01-29 13:15:18

标签: javascript date datetime momentjs

我通过Ajax通话获得了 UTC 日期,例如"/Date(1517216466000+0100)/"
打印到控制台时:Mon Jan 29 2018 10:01:06 GMT+0100 (W. Europe Standard Time)

我需要做的是让用户更改时区:我可以轻松地使用例如moment(myDate).tz("Japan")

然后我需要以它的UTC格式保存日期,这是我无法做到的 我一直在试验moment.utc(),但对于上面的输入,它会返回 1小时

如何应对这种情况?总结:
 1.从网络服务获取UTC时间
 2.让用户更改时区
3.以UTC格式保存修改日期(不带时区)
工作演示:https://stackblitz.com/edit/angular-kqrct7?file=app%2Fapp.component.html
编辑澄清:
我们来看看时间。我从WCF得到的日期是10点钟。浏览器将其解释为GMT + 1中的10 o&时钟BUT,因此当我将其转换为UTC时,它变为9 o'时钟。
我希望它为10 o'时钟为UTC 。然后,如果我修改时区,例如这个日期的分钟,我希望能够得到这个日期的UTC值。

编辑2:让我的问题更简单,以澄清

  1. 我有一个UTC日期,我可以通过以下网络服务获得:" /日期(1517216466000 + 0100)/"这是:2018年1月29日星期一10:01:06 GMT + 0100(欧洲标准时间)打印到控制台时。

  2. 我用时刻(this.inputDate).tz("欧洲/柏林")。格式()添加一个时区,但它保持在10:01:06,我猜是因为我的浏览器GMT + 1。

  3. 我希望ORIGINAL字符串用作UTC日期,它应该保持在10:01:06,而不是09:01:06,如上所示(第二时刻示例),所以使用时区& #34;欧/柏林"将是11:01:6

3 个答案:

答案 0 :(得分:3)

.NET JSON formatted date" /日期(1517216466000 + 0100)/"时区偏移量可以忽略。它代表" 2018-01-29T09:01:06.000Z",其中源系统的时区偏移量为+0100。因此,如果您不关心源时区,请忽略它。

这也是2018年1月29日星期一10:01:06 GMT + 0100(欧洲标准时间)的相同时刻,只是有不同的偏差。

UTC不是格式,它是时间标准。如果您想使用ISO 8601格式:

  1. 提取第一个数值
  2. 转换为数字
  3. 传递给Date构造函数
  4. 在生成的日期
  5. 上调用 toISOString 方法

    
    
    var s = '/Date(-1517216466000+0100)/';
    console.log(new Date(+s.replace(/^[^\d-]+(-?\d+).*$/,'$1')).toISOString());
    
    
    

    您还可以使用moment.js对其进行解析和格式化,根据the documentation,它可以处理.NET JSON格式而无需指定格式。所以你可以这样做或者提取时间值并用" x"解析它。格式标记:

    
    
    var s = '/Date(1517216466000+0100)/';
    
    // Let moment.js guess the format
    console.log(moment(s).utc());
    
    // Extract time value and supply format
    console.log(moment(s.replace(/^[^\d-]+(-?\d+).*$/,'$1'), 'x').utc());
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
    &#13;
    &#13;
    &#13;

答案 1 :(得分:1)

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { let userlocation: CLLocation = locations[0] as CLLocation self.userLoc = userlocation manager.stopUpdatingLocation() DispatchQueue.main.asyncAfter(deadline: .now() + 30) { self.requestLocation() } } 是序列化日期/时间的非标准方式。看一下ISO8601,它定义了几种表示日期和时间的标准方法。

话虽如此,让我们来看看这被评估为......

"/Date(1517216466000+0100)/"

给我moment("/Date(1517216466000+0100)/").toDate() (在英国)

仅获取时间戳值Mon Jan 29 2018 09:01:06 GMT+0000 (GMT Standard Time)

1517216466000

也提供new Date(1517216466000)

这意味着Mon Jan 29 2018 09:01:06 GMT+0000 (GMT Standard Time)被忽略。

你实际上并没有修改时间,所以为什么你会期望它除了+0100

以外的其他任何东西

<强>更新

但是“原始”字符串表示Mon Jan 29 2018 09:01:06 Mon Jan 29 2018 09:01:06 UTC被忽略,而您对UTC的偏移也是+0100的巧合。关闭。

偏移和时区是两个不同的东西。时区包含与UTC的偏移以及何时/如果夏令时生效。仅仅因为它说+0100并不一定意味着(W。欧洲标准时间),因为它可以很容易地(西非时间)也是UTC + 0100但是根本没有观察到夏令时。

+0100的时间没有传达足够的信息来说明它是哪个时区,而JS /时刻只使用时间戳"/Date(1517216466000+0100)/",因此使用UTC。当您1517216466000时,浏览器会将其作为本地时间console.log()写入屏幕,但这只是基础日期时间的表示。

通过讲述使用特定时区的时刻,它只会改变日期/时间的显示方式,并且实际上不会改变它所代表的时间。

如果您使用日期选择器更改日期/时间,那么您必须将值序列化以便以适当的方式发送到后端,使您无法更改的.Net应用程序将理解并传达您的意图。

<强> 实施例

  1. Mon Jan 29 2018 10:01:06 GMT+0100 (W. Europe Standard Time)
  2. 获取服务器的日期
  3. 使用片刻var serverTime = "/Date(1517216466000+0100)/"
  4. 将其转换为JS日期
  5. 让用户指定TimeZone,即日本标准时间(UTC + 9)var time = new moment(serverTime)
  6. time = time.tz("Japan")仍然代表time,但在Mon Jan 29 2018 09:01:06 UTC屏幕上显示时会显示time.format()
  7. 你说“我希望它是UTC的10点”。不幸的是,你的价值是 10点UTC并且永远不会是10点UTC,因为它不是。 UTC时间是9点

    您可以自己解析从服务器获得的值,但是服务器的时间 IS 上午9点UTC。如果你把它改为UTC早上10点那么你会看到"2018-01-29T18:01:06+09:00" - 当地时间11点。

答案 2 :(得分:1)

感谢大家的详细解答,他们帮助我理解了我的问题!但是,正确的解决方案如下:

10 o&#39;时钟是数据库中的UTC时间,它在Moment.js中被解释为9 o&#UTC时间因为C#将其处理为本地时间。因此,在将日期发送给客户之前,我必须指出它是UTC:

var utcToClient = DateTime.SpecifyKind(downtime.DownTimeStartUTC, DateTimeKind.Utc)

然后,在Moment中,我可以创建一个UTC:

var jsUtc = moment.utc(downtime.DownTimeStartUTC)

通过以下方式轻松更改时区:

jsUtc.tz(userSelectedTimezone)

在数据库中保存日期,我在C#中使用了这个:

var utcFromClient = Record.DownTimeStartUTC.ToUniversalTime()