2017-08-24 80 views
0

我正在使用ASP.Net后端。我以UTC时间将所有日期从客户端保存到数据库。UTC date.ToLocalTime()仍然以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"); 
+0

Check out https://stackoverflow.com/questions/179940/convert-utc-gmt-time-to-local-time回答最佳回答 – Hubbs

+0

@Hubbs不幸的是,我已经尝试过这一点,我仍然得到我在UTC时间的最后日期而不是当地时间。我用第4种方法添加了一个编辑,显示了这个实现。 – naffie

回答

1

你说:

...从UTC时间到用户的本地时间......在ASP.Net

什么都不会告诉你用户的本地时区。调用ToLocalTime将从UTC转换为服务器的时区(除非.Kind已经为DateTimeKind.Local)。

在许多情况下,将服务器的时区设置为UTC的最佳做法意味着您将看到ToLocalTimeToUniversalTime以外的其他类型的更改。而且由于服务器的时区在大多数情况下都不相关,所以这不是正确的方法。您可以通过其他机制(例如在您的应用程序中选择它)来知道用户的时区,以便您可以使用TimeZoneInfo.ConvertTime(或Noda Time)转换服务器端,或者您需要发送UTC时间到达客户端,并在JavaScript中执行utc-to-local(因为浏览器正在用户的时区中运行)。

一般而言,应避免在服务器应用程序(如ASP.NET)中使用“本地时间”。这包括ToLocalTime,ToUniversalTime,DateTimeKind.Local,TimeZoneInfo.Local,DateTime.Now,和其他一些其他的东西。

+0

你是绝对正确的马特与此“...在许多情况下,将服务器的时区设置为UTC的最佳做法将意味着您将看到ToLocalTime或ToUniversalTime没有变化,除类型“...所以我决定从我的应用程序中获取UTC的偏移量,然后将其传递到后端,并使用'AddHours'将它添加到'alertTime'对象中 – naffie

+0

请注意,偏移量必须只针对特定的时间戳,否则不会考虑时区内的偏移量变化,如夏时制 –

+0

更好的办法是获取实际的客户端时区ID,而不仅仅是偏移量。 –

1

这是因为你的DateTimeKind或者是LocalUnspecified。请参阅documentation for ToLocalTime()

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

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

  • 本地 - 未执行任何转换。

  • 未指定 - 此DateTime实例被假定为UTC时间,转换的执行方式类似Kind为Utc。

可以使用SpecifyKind method设置之前做转换的类。

+0

不幸的是,我已经尝试了这一点,它也没有工作。我已经将它作为方法4添加到了上面的问题中,以向您展示我是如何做到的。 – naffie

+0

嗯!好奇。我不知道然后:( – Amy