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



我正在一个新闻网站上工作,我正在以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 日期/时间转换为中东时区,但来自世界任何其他地方的任何用户都只能看到中东时区的日期/时间,而看不到其所在位置的实际时区。另外,我不确定转换是否考虑夏令时

方法3:

我试图使用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>  

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

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

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

方法4

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

总结

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

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

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

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

为了实现您的目标,请将问题分为两部分。

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

对于第 1 步,请阅读我发布到另一个问题的答案。 请注意,输出将是 IANA 时区标识符。 不要传递数字偏移量,因为它携带的信息不足以正确转换不同的时间点(考虑夏令时和其他时区异常(。

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

  • 如果您在非 Windows 操作系统上运行 .NET Core,则可以将 IANA 时区标识符原生地用于TimeZoneInfo,或者与任何平台上的 Noda 时间库一起使用。

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

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

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

最新更新