【问题标题】:UTC date.ToLocalTime() still produces date in UTC timeUTC date.ToLocalTime() 仍以 UTC 时间生成日期
【发布时间】:2017-08-24 16:24:36
【问题描述】:

我正在使用 ASP.Net 后端。我将所有日期从客户端保存到 UTC 时间的数据库中。

我在后端有一个导出一些记录的函数,我想在显示它们之前将提取的日期从 UTC 时间转换为用户的本地时间。

我已经尝试过 StackOverflow 上提出的大量解决方案,但它们似乎都没有将日期转换为本地时间,即使这在客户端上显示其中一些日期时有效。我怀疑服务器已经认为日期是在当地时间,但我不知道如何解决它。

以下是我尝试过的不同解决方案:

//1.

var alertTime = record.TimeRecorded.GetValueOrDefault().ToLocalTime().ToString("hh:mm tt");


// 2.
var alertTime = record.TimeRecorded;

 if (alertTime.HasValue)
    {
      var timeInUtc = TimeZoneInfo.ConvertTimeToUtc(alertTime.Value);
     string alertTimeToLocalTime = timeInUtc.ToLocalTime().ToString("hh:mm tt");

    }

 //alertTimeToLocalTime is still in UTC time here

// 3.

if (alertTime.HasValue)
    {
        var localTime = TimeZoneInfo.ConvertTimeFromUtc(timeInUtc, TimeZoneInfo.Local);
       string alertTimeToLocalTime = localTime.ToString("hh:mm tt");

    }

这些都无法将alertTime 转换为当地时间。

我错过了什么吗?

编辑

//4. Another approach I had already tried which didn't work as well

var alertTime = DateTime.SpecifyKind(record.TimeRecorded.GetValueOrDefault(), DateTimeKind.Utc);
alertTimeToLocalTime = alertTime.ToLocalTime().ToString("hh:mm tt");

【问题讨论】:

  • @Hubbs 不幸的是,我已经尝试过了,但如果是当地时间,我仍然会得到 UTC 时间的最终日期。我添加了第 4 种方法的编辑,显示了此实现。

标签: c# asp.net date datetime xamarin.ios


【解决方案1】:

你说:

...从UTC时间到用户本地时间...

ASP.Net 中的任何内容都不会告诉您用户的本地时区。调用ToLocalTime 将从UTC 转换为服务器的 时区(除非.Kind 已经是DateTimeKind.Local)。

在许多情况下,将服务器的时区设置为 UTC 的最佳做法意味着您不会看到 ToLocalTimeToUniversalTime 的变化,除了那种。而且由于服务器的时区在大多数情况下是无关紧要的,所以这不是正确的方法。

相反,您需要通过其他一些机制(例如他们在您的应用程序中选择它)知道用户的时区,以便您可以使用TimeZoneInfo.ConvertTime(或Noda Time)在服务器端进行转换,或者您需要将 UTC 时间向下发送到客户端并在 JavaScript 中执行 utc-to-local(因为浏览器在用户的时区中运行)。

一般来说,应避免在服务器应用程序(例如 ASP.NET)中使用“本地时间”。这包括ToLocalTimeToUniversalTimeDateTimeKind.LocalTimeZoneInfo.LocalDateTime.Now 以及其他一些杂项。

【讨论】:

  • 你是绝对正确的,马特这个“......在许多情况下,将服务器的时区设置为 UTC 的最佳实践将意味着您将看到 ToLocalTime 或 ToUniversalTime 没有任何变化,除了那种“......所以我决定从我的应用程序中获取UTC的偏移量,然后将它传递给后端,然后我使用'AddHours'将它添加到'alertTime'对象。
  • 小心点。偏移量必须特定于该特定时间戳。否则,它不会考虑时区内的偏移变化,例如夏令时。
  • 更好的办法是获取实际的客户端时区 ID,而不仅仅是偏移量。
【解决方案2】:

这是因为您的DateTimeKind 要么是Local 要么是Unspecified。见documentation for ToLocalTime()

从 .NET Framework 2.0 版开始,ToLocalTime 方法返回的值由当前 DateTime 对象的 Kind 属性决定。下表描述了可能的结果。

  • Utc - 此 DateTime 实例转换为本地时间。

  • 本地 - 不执行转换。

  • 未指定 - 此 DateTime 实例假定为 UTC 时间,并且转换的执行方式如同 Kind 是 Utc。

您可以在进行转换之前使用SpecifyKind method 设置种类。

【讨论】:

  • 不幸的是,我也已经尝试过了,但也没有用。我已将其作为方法 4 添加到我上面的问题中,以向您展示我是如何做到的。
  • 嗯!好奇的。那我就不知道了:(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-09
  • 2012-05-18
  • 2021-12-31
  • 2021-05-14
  • 2011-07-11
  • 2023-03-20
  • 2023-03-21
相关资源
最近更新 更多