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

VB.Net将UTC时间转换为本地时间,vb.net,datetime,timezone,utc,timezone-offset,Vb.net,Datetime,Timezone,Utc,Timezone Offset,我正在一个新闻网站上工作,我正在用UTC保存数据库中的所有日期。然后,根据浏览器/机器位置,我想相应地显示日期/时间(从UTC转换为机器/浏览器的本地时间) 首先,我想知道我是否应该这样做(数据库中的UTC日期) 其次,我想知道为什么在VB.NET中这样做不那么简单?以下是我尝试过的方法,但没有一种能按需要发挥作用: 方法1: TimeZoneInfo.ConvertTimeFromUtC Dim TimeZone As TimeZoneInfo = TimeZoneInfo.FindSyst

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

首先,我想知道我是否应该这样做(数据库中的UTC日期)

其次,我想知道为什么在
VB.NET
中这样做不那么简单?以下是我尝试过的方法,但没有一种能按需要发挥作用:

方法1:

TimeZoneInfo.ConvertTimeFromUtC
Dim TimeZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Middle East Standard Time")
Dim Dated As DateTime = TimeZoneInfo.ConvertTimeFromUtC(TempDate, TimeZone)
这会不断返回服务器时间,而不是客户端/计算机时间

方法2:

TimeZoneInfo.ConvertTimeFromUtC
Dim TimeZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Middle East Standard Time")
Dim Dated As DateTime = TimeZoneInfo.ConvertTimeFromUtC(TempDate, TimeZone)
这起了作用,但没有达到预期效果。这会将数据库中的UTC日期/时间转换为中东时区,但世界上任何其他地方的任何用户都只能看到中东时区中的日期/时间,而不会看到其所在地的实际时区中的日期/时间。此外,我不确定转换是否考虑日光节约

方法3:

TimeZoneInfo.ConvertTimeFromUtC
Dim TimeZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Middle East Standard Time")
Dim Dated As DateTime = TimeZoneInfo.ConvertTimeFromUtC(TempDate, TimeZone)
我尝试使用
JavaScript
修复此问题。我创建了一个cookie来保存UTC的偏移量,并尝试在
VB.NET
中处理偏移量并进行转换

<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>  
cookie是在呈现页面之前创建的,并且cookie中存储的偏移量是正确的(这就是我真正想要的!)。这里的问题是在第一个负载上
VB.NET
在第一次加载时将cookie值作为空字符串读取。在第二个
页面\u Load
之后,
VB.NET
读取cookie值并正确进行转换

方法4

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

摘要

我想知道我在
VB.NET
中是否遗漏了任何函数来避免所有这些麻烦。将日期/时间从UTC转换为本地时间不是一件容易的事情吗


如果我做错了什么,或者有更好的选择,请告诉我。

您的后端代码不知道浏览器的时区。不管你使用什么语言,只有浏览器知道用户的时区

当.Net代码(不管是VB还是C#)指的是“本地”时,它指的是运行该代码的本地时区。换句话说,在ASP.NETWeb应用程序中,这是服务器的本地时区,而不是用户的本地时区。一般来说,服务器的本地时区通常是不相关的

为了达到你的目标,把问题分成两部分

  • 在浏览器中获取用户的时区,并将其发送到服务器
  • 使用传入的时区转换服务器上的时间
  • 对于第1步,请阅读我发布的另一个问题。请注意,输出将是IANA时区标识符。不要传递数字偏移,因为它没有足够的信息来正确转换不同的时间点(考虑夏令时和其他时区异常)

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

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

    • 您可以使用my library将IANA时区标识符转换为Windows时区标识符,然后将结果与Windows上的
      TimeZoneInfo
      类一起使用

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


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

    您可能会发现这很有用。我发现这是谷歌搜索词的第一次成功,你的方法是正确的,但只需使用DateTime.SpecifyKind。看看这个例子:你可以在浏览器中完成。将日期时间呈现为
    ,将
    数据时间设置为UTC日期时间,然后使用jQuery将转换后的日期时间呈现为$(document).ready事件中跨度的内部HTML。或者类似的东西。@JeffZeitlin在
    GetUtcOffset
    中返回0,我比UTC早2小时。检查此示例:@David我检查了示例,它返回UTC时间。我尝试放置
    DateTimeKind.Local
    而不是
    DateTimeKind.Utc
    ,但仍然得到Utc时间。有什么建议吗@AndrewMorton我想这是我在方法3中尝试过的,但在第二次重新加载时有效,而不是第一次。我希望避免在第一次点击时重新加载页面。有没有明确的例子?谢谢你提供的信息和建议。步骤1:链接无效。您建议从浏览器获取时区并将其发送到服务器。当使用注册/登录功能时,这可能是一个很好的场景。但是,如果登录页面显示时间,JS将不会在页面加载之前运行。这意味着该方法将从第二个页面加载开始工作(如果我们使用会话/cookie)。第二步:我将进行一次测试,如果答案有效,我会将其标记为“已解决”。谢谢你!不知道为什么,但显然那个长期存在的问题被删除了。基本上,您需要调用
    Intl.DateTimeFormat().resolvedOptions().timeZone