Windows 7的TimeZone问题

时间:2017-06-23 15:17:27

标签: vb.net timezone

当我们的UTC服务器数据库返回日期时,Windows非常有用地将日期更改为日期时间(例如2017年6月23日至2017-06-23 00:00),然后对当前时区进行调整(到,说2017-06-22 16:00)...多年来我们一直使用下面的代码将其转换回来......

大约四个月前,运行Windows 7(Windows 10似乎没有受到影响)的用户没有选中“自动调整夏令时的时钟”,或者生活在像亚利桑那州这样的选项不可用的状态下,注意到报告从前一天返回日期 - 我们的数据库返回正确的日期,但转换不再正常工作..

有什么建议吗?

由于

Public Function LocalDateFormat(ByVal InputDate As Date) As String
    Dim vDate As String = InputDate.ToString("d", System.Globalization.CultureInfo.InvariantCulture)
    Dim LocalZone As TimeZone = TimeZone.CurrentTimeZone
    Dim CurrentOffset As TimeSpan = LocalZone.GetUtcOffset(InputDate)
    Dim DayLightSaving As Boolean = LocalZone.IsDaylightSavingTime(InputDate)
    Dim CalculatedOffset As New DateTime(InputDate.Ticks, DateTimeKind.Local)
    If CurrentOffset.CompareTo(TimeSpan.Zero) < 0 Then
        CalculatedOffset -= LocalZone.GetUtcOffset(InputDate)
        If DayLightSaving = True Then
            CalculatedOffset = CalculatedOffset.AddHours(1)
        End If
    Else
        CalculatedOffset += LocalZone.GetUtcOffset(InputDate)
        If DayLightSaving = True Then
            CalculatedOffset = CalculatedOffset.AddHours(-1)
        End If
    End If

    InputDate = CalculatedOffset

    Dim vCulture As String = System.Globalization.CultureInfo.CurrentCulture.ToString
    Dim vReturnDate As String = ""
    Select Case vCulture
        Case "en-US"
            vReturnDate = Format(InputDate, "MM/dd/yyyy")
        Case "en-GB"
            vReturnDate = Format(InputDate, "dd/MM/yyyy")
        Case Else
            vReturnDate = Format(InputDate, "dd/MM/yyyy")
    End Select
    Return vReturnDate

End Function

1 个答案:

答案 0 :(得分:1)

您的整个功能可以重写为:

Public Function LocalDateFormat(ByVal InputDate As Date) As String
    Return InputDate.ToLocalTime().ToShortDateString()
End Function

如果代码太小,您可能想重新考虑一下在功能中是否有任何好处。

至于为什么你现有的功能没有正常工作:

  • TimeZone.GetUtcOffset已经考虑了DST是否生效,尽管它在MSDN文档中描述了一些问题。
  • 您根本不应该再使用TimeZone。如果您需要使用时区,请使用TimeZoneInfoNoda Time。在这种情况下,您不需要其中任何一个,因为您只是从UTC转换为当地时间,这是DateTime.ToLocalTime所做的。
  • 如果偏移为正,此代码有一些逻辑似乎认为应该减去一小时的DST。对不起,但是夏令时并没有这样做 - 你总是加一小时(除非你在澳大利亚的豪勋爵岛,你加30分钟)。
  • 它似乎也认为你应该从UTC添加偏移量,如果它是正数则减去它,如果它是负数则减去它。这本质上是一个绝对值函数,也是不正确的。
  • 通过在当前文化中进行格式化来处理所有文化内容。没有必要手工完成。

你说它在Windows 10上工作正常,但我很抱歉 - 这是一个错误的代码,无论它在哪里运行都会出错。只需使用框架提供的内置API即可。不要重新发明轮子。 :)