gpt4 book ai didi

javascript - 如何使用偏移量转换时间跨度

转载 作者:太空宇宙 更新时间:2023-11-03 23:15:39 28 4
gpt4 key购买 nike

我有MVC Web应用程序。我将UTC时间存储在数据库中。 (不是日期时间,而是一个时间)。在c#中,当我从数据库中检索到该时间时,我得到了timepan对象。我也有可用的胶版印刷胶版。例如。

double offset = 600;


如何使用此偏移量将时间跨度转换为本地日期时间。

注意我不想使用DateTime.ToLocalTime()方法,因为它将使用服务器的时区。

UPDTAE1
我正在使用javascript new Date().getTimezoneOffset()方法获取客户端的偏移量,并且我将偏移值存储在服务器上。然后,我还有一个下拉列表,显示时间为12:00 AM,12.30 AM,1:00 AM等。dropdownlist绑定到类型为 SelectedDateTime的模型属性 DateTime。想法是根据偏移量将用户选择的时间转换为UTC,然后将UTC转换为本地时间。所以可以说我的偏移量 300 minitues将是 300/60 = 5 hours

double offset = 5.00; // this is available on the server


当用户在下拉列表中选择时间时,我在服务器上获取了datetime对象,而忽略了我要将UTC时间存储到数据库中的日期部分。这就是我如何转换为UTC时间。

TimeSpan utcTime = SelectedDateTime.AddHours(offset).TimeOfday;


我将此utcTime存储到数据库中。现在我想将UTC时间跨度转换为客户的日期时间。
我假设我现在有减法抵消

var newLocalTimeSpan = utcTime.Subtract(TimeSpan.FromHours(offset));
var newLocalDateTime = new DateTime(newLocalTimeSpan.Ticks, DateTimeKind.Local);


但是这会引发错误


  刻度必须在DateTime.MinValue.Ticks和
  DateTime.MaxValue.Ticks。\ r \ n参数名称:ticks


例如,在最长时间 5小时,如果用户选择 8:00 PM,则它将转换为UTC,并将作为 01:00:00.0000000存储在数据库中。当我从数据库中检索UTC值时,它是'1:00:00 AM'。然后我从这个TimeSpan中减去5小时,现在等于'-4',如果我将Ticks传递给DateTime ..

注意:如果您很好奇为什么模型属性是DateTime而不是TimeSpan,那是因为我使用的Kendo TimePicker需要DateTime类型。

更新2
非常感谢您的帮助。我遍历了@Matt Johnson发表的所有文章,看来我不应该使用偏移量来计算UTC时间。主要是因为白天节省时间。但是我应该使用时区。因此,我在这里有3个选项来查找客户的时区:

1>使用JavaScript检测时区
在JavaScript中,我可以执行 new Date().toString()并将日期时间返回为 Sun May 22 2016 02:12:36 GMT-0500 (Central Daylight Time),然后我可以解析该字符串以获取“中央夏令时”并将其发布到服务器。但是,在服务器上,对于.net,“中央夏令时”不是有效的Windows时区ID。

这是正确的方法吗? JavaScript是否返回IANA区域ID?它会始终返回IANA区域ID吗?

如果JavaScript返回 IANA ID,那么我可以使用Matt的文章 here获取Windows时区ID

2>使用 http://momentjs.com/检测客户的时区

momentjs是否返回 IANA区域ID?
如果momentjs返回 IANA区域ID,那么我可以使用上面Matt的文章来获取Windows区域ID。我不喜欢这种方法的原因之一是因为我必须使用2个第三方库 momentjsNoda Time

3>使用TimeZoneInfo.GetSystemTimeZones()为用户提供一个下拉列表,并让用户选择时区。
用户将选择一个时间和时区,然后在服务器上,我将使用所选时区将其转换为UTC并将其保存为数据库。但是我必须在其他页面上显示该时间,因此我再次需要时区。这意味着我必须将下拉列表放在UI上始终可用的位置。像顶级菜单。

(我当然可以将时区和时间一起保存到数据库中,但是,如果用户前往其他地方,他仍然会看到最初选择的时区中的时间。我不希望这样)

这些方法正确吗?我想念什么吗?


假设我使用上述方法之一实现时区选择,并且我在服务器的某些变量中具有Windows时区ID正确的客户端时区。
现在,假设用户选择 6:00 PM(中央夏令时,UTC -5),它将转换为UTC的23:00:00。只要我们处于中部夏令时,从UTC到本地的转换将显示6:00 PM。当我们进入UCC -6的 Central Standard Time时,转换是否仍显示6:00 PM或5:00 PM?
我打算使用 TimeZoneInfo.ConvertFromUtc(datetimevalue, timezone)方法将UTC转换为Local

最佳答案

通常,只有两种可行的方法:


仅将UTC日期和时间传递给客户端,并使用JavaScript在浏览器中将所有时间转换为本地时间。


当您不在乎时区实际是什么时,而只希望它与浏览器的本地时间匹配,请使用此方法。
Date对象可以做到这一点,但是您可能会发现使用moment.js之类的库会更容易,它可以让您更好地控制输出格式。

在服务器端对UTC日期和时间应用时区(而不仅仅是偏移量),以产生正确的本地时间值。


当时区影响整个应用程序并且需要在服务器端业务逻辑中知道时,请使用此方法。
您可以尝试使用jsTimeZoneDetect中的moment-timezonemoment.tz.guess()猜测用户的时区。但是,这只是一个猜测,它始终是IANA时区ID(例如America/Los_Angeles)。
从列表中询问用户他们的时区是一个好主意。通常,将其放置在用户设置或个人资料页面上。您可以使用之前做出的猜测从列表中选择一个默认值。
如果要在客户端上使用IANA时区,则确实需要在服务器上使用Noda Time
某些应用程序选择列出Windows时区,这是一种更为简单的方法,因为您可以从TimeZoneInfo类获取所有内容。但是,请注意此方法存在局限性,包括:


本地化问题,因为除了与操作系统默认语言匹配的名称字符串之外,您无法轻易获得显示名称字符串,而不是.NET的全球化和本地化功能。
可维护性问题,因为您将控制权交给操作系统以保持时区数据更新。这似乎更方便,但是您可能会发现,跟上short-notice time zone changes时,双手会被绑住。当您无法控制如何或何时将更新应用到操作系统(例如使用Microsoft Azure App Service)时,这尤其成问题。
兼容性问题,因为Windows时区通常无法在Windows之外识别。如果您曾在API中公开用户的时区设置,则其他平台的调用者可能会遇到翻译问题。




现在,转到您的特定要点:


  我正在使用javascript new Date()。getTimezoneOffset()方法来获取客户端的偏移量...


这将为您提供客户端的当前偏移量。您不能保证这是适用于任意日期和时间的正确时区。

如果要对C#中的UTC DateTime应用固定的偏移量,最好的方法是使用DateTimeOffset

DateTime utc = new DateTime(2016, 12, 31, 0, 0, 0, DateTimeKind.Utc);
DateTimeOffset dto = new DateTimeOffset(utc); // DateTimeKind matters here
TimeSpan offset = TimeSpan.FromMinutes(-300); // The offset is inverse of JavaScript's
DateTimeOffset result = dto.ToOffset(offset);


但是请注意,这仅适用于固定的时区偏移量。对于真实的时区,如果使用的是Windows时区,则可以使用 TimeZoneInfo类;对于IANA时区,则可以使用NodaTime的 DateTimeZone类。


  在JavaScript中,我可以执行new Date()。toString(),将日期时间返回为Sun May 22 2016 02:12:36 GMT-0500(Central Daylight Time),然后我可以解析字符串以获取“ Central Daylight Time”并发布它到服务器。


不,不建议采用这种方法,原因有以下几个:


不能保证您会从JavaScript的 toString函数获得任何特定格式的输出。结果是特定于实现的,并且会因浏览器和平台而异。
它们通常用于显示目的。夏令时生效时,它们将显示一个白天名称,而标准时间生效时,它们将显示一个标准名称。
它们通常针对用户的语言,英语,法语,中文等进行本地化。


唯一可以返回用户时区的本地API是:

Intl.DateTimeFormat().resolvedOptions().timeZone


这是 ECMAScript Internationalization API的一部分。不幸的是,它目前仅在少数浏览器中有效。如果可用,则jsTimeZoneDetect和 moment.tz.guess()都将使用此API,否则将使用其自己的猜测逻辑。


  假设我使用上述方法之一实现时区选择,并且我在服务器的某些变量中具有Windows时区ID正确的客户端时区。现在,假设用户选择了6:00 PM(中央夏令时,UTC -5),它将转换为UTC的23:00:00。只要我们处于中部夏令时,从UTC到本地的转换将显示6:00 PM。进入中部标准时间(UTC -6)后,转换是否仍显示6:00 PM或5:00 PM?
  我打算使用 TimeZoneInfo.ConvertFromUtc(datetimevalue, timezone)方法将UTC转换为Local


如前所述, "Central Daylight Time"不是有效的Windows时区标识符。您的用户不会选择。您将显示从 TimeZoneInfo.GetSystemTimeZones()生成的列表,向用户显示 DisplayName,并使用 Id作为值。 Id将是 "Central Standard Time",它确实是美国中部时间的正确标识符,包括CST和CDT-尽管字符串中有单词“ Standard”。

关于javascript - 如何使用偏移量转换时间跨度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37331524/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com