VB.Net将时间从UTC转换为本地

时间:2018-09-28 18:35:42

标签: vb.net datetime timezone utc timezone-offset

我正在新闻网站上工作,并将所有日期保存在UTC中的数据库中。然后,根据浏览器/机器的位置,我想相应地显示日期/时间(从UTC转换为机器/浏览器的本地时间)。

首先,我想知道是否以这种方式进行操作(数据库中的UTC日期)。

第二,我想知道为什么在VB.NET中这样做不是那么简单吗?以下是我尝试过的方法,但没有按需使用的方法:

方法1:

TimeZoneInfo.ConvertTimeFromUtC

这总是返回服务器时间而不是客户端/机器时间。

方法2:

Dim TimeZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Middle East Standard Time")
Dim Dated As DateTime = TimeZoneInfo.ConvertTimeFromUtC(TempDate, TimeZone)

这有效,但未达到预期目的。这样会将数据库中的UTC日期/时间转换为中东时区,但是世界上任何其他地方的任何用户都只能看到中东时区 em>,而不是他所在的实际时区。另外,我不确定转换是否考虑 DayLightSaving

方法3:

我尝试使用JavaScript解决此问题。我创建了一个 cookie ,它保存了UTC的 offset ,并尝试处理VB.NET中的 offset 并进行转换。

<script>
    function setCookie(cname, cvalue, exdays) {
        var d = new Date();
        d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
        var expires = "expires=" + d.toUTCString();
        document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
    }

    function getTimeOffset() {
        var offset = new Date().getTimezoneOffset();
        setCookie("_tz", offset);
    }
</script>  

JavaScripts返回正确的偏移量,我将此偏移量保存在 cookie 中。由于JavaScriptPage_Load之后启动,因此我在JavaScript上调用getTimeOffset()函数Page_Init

ScriptManager.RegisterStartupScript(Me, Page.GetType, "Script", "getTimeOffset();", True)

cookie 是在呈现页面之前创建的,并且存储在 cookie 中的偏移量是正确的(这是我真正想要的!)。这里的问题是第一次加载。 VB.NET在第一次加载时将 cookie 值读取为空字符串。从第二Page_Load开始,VB.NET读取cookie值并正确进行转换。

方法4

尝试使用此fiddle中的所有示例来获取偏移量,但偏移量始终为0,这是错误的。

摘要

我想知道在VB.NET中是否缺少任何功能来避免所有麻烦。将日期/时间从UTC转换为本地不是一件容易的事吗?

请告诉我我做错了什么还是有更好的选择。

1 个答案:

答案 0 :(得分:1)

您的后端代码对浏览器的时区一无所知。不管使用哪种语言,只有浏览器才能知道有关用户所在时区的任何信息。

当.Net代码(无论VB或C#)指的是“本地”时,表示该代码运行所在的本地时区 。换句话说,在ASP.Net Web应用程序中,这是您的服务器而不是用户的本地时区。一般来说,服务器的本地时区通常是无关紧要的。

要实现目标,请将问题分为两部分。

  1. 在浏览器中获取用户的时区,并将其发送到服务器。
  2. 使用传入的时区在服务器上转换时间。

对于步骤1,请阅读我发布到另一个问题的this answer。请注意,输出将是IANA时区标识符。不要传递数字偏移量,因为它没有足够的信息来正确转换不同的时间点(考虑夏时制和其他时区异常)。

对于步骤2,您需要在以下方法之一中进行选择:

  • 如果您在非Windows操作系统上运行.NET Core,或者在任何平台上与Noda Time库一起使用,则可以将IANA时区标识符与TimeZoneInfo一起使用。< / p>

  • 您可以使用我的TimeZoneConverter库将IANA时区标识符转换为Windows时区标识符,然后可以在Windows上的TimeZoneInfo类中使用结果。

一件小事情:您使用过TimeZoneInfo.ConvertTimeToUtc,我想您的意思是TimeZoneInfo.ConvertTimeFromUtc。注意转换的方向性。

我还将指出,还有一种替代方法,就是将UTC时间戳一直传递到浏览器,然后在JavaScript中将UTC转换为本地时间。然后,您根本不需要执行任何时区检测。