是否在Xamarin上打破了ToLocalTime?

时间:2013-10-01 20:55:57

标签: c# ios xamarin.ios mono xamarin

我在GMT时区的Xamarin Studio(v4.0.12 - Mono 3.2.3)中运行以下代码......

var utcDateTime = new DateTime(1970, 07, 15, 15, 00, 00, DateTimeKind.Utc);
string utcTimeString = utcDateTime.ToLongTimeString();
string localTimeString = utcDateTime.ToLocalTime().ToLongTimeString();

...但两个变量都返回值“3:00:00 PM”。

如果我在.NET 4.0下运行相同的代码,那么第二个变量是“4:00:00 PM”。这就是我所期望的。

我不确定我错过了什么,如果两者都不一致吗?

从'ToLocalTime()'返回的DateTime看起来与原作相同,只是'Kind'现在是'Local'。

更新

这与上例中的年份无关。如果输入当前年份,则时间不同(且正确),如果输入1970年之前的任何内容,则忽略时区。

以下是基于http://msdn.microsoft.com/en-us/library/system.timezone.currenttimezone.aspx

中代码的时区信息的副本
Standard time name:           GMT
Daylight saving time name:    BST

Current date and time:        2013-10-02 09:27
Daylight saving time?         True
Coordinated Universal Time:   2013-10-02 08:27
UTC offset:                   01:00:00

Daylight saving time for year 1970:
0001-01-01 00:00 to 0001-01-01 00:00, delta: 00:00:00

1970
7/15/1970 3:00:00 PM
7/15/1970 3:00:00 PM

2005
7/15/2005 3:00:00 PM
7/15/2005 4:00:00 PM

Now
10/2/2013 8:27:09 AM
10/2/2013 9:27:09 AM

4 个答案:

答案 0 :(得分:2)

通过查看Mono的DateTime源代码,我们可以看到ToLocalTime来电使用TimeZone.CurrentTimeZone来执行转换,

https://github.com/mono/mono/blob/master/mcs/class/corlib/System/DateTime.cs

因此,要解决您遇到的这个问题,您可以在两种情况下(iOS和Windows)打印TimeZone.CurrentTimeZone以查看是否存在任何显着差异。

Windows案例是正确的,因为.NET 4访问底层Windows系统以找到适当的时区(具有完整的DST支持)。

Xamarin.iOS案件很难,因为我们不确定iOS是否公开了正确的时区信息以及Xamarin.iOS是否正确使用它。

答案 1 :(得分:0)

看起来你在夏天的时候已经离开了。

GMT与UTC几乎相同(GMT是基于太阳能的,而UTC是基于原子钟的),但由于夏季时间都没有,所以它们应该是相同的。

问题可能是您没有在Windows机器上使用GMT,而是使用其他一些夏令时感知时区。

答案 2 :(得分:0)

虽然正在针对此错误修复此问题,但您可以将此解决方法用于DateTime.ToLocalTime():

Datetime localdate = TimeZoneInfo.ConvertTime(utcdate,TimeZoneInfo.Utc, TimeZoneInfo.Local);

答案 3 :(得分:0)

尝试使用此解决方法扩展方法

public static class DateTimeExtensions
{
    public static DateTime ToLocalTimeX(this DateTime dateTime)
    {
        var info = TimeZoneInfo.Local;
        return dateTime.Add(info.BaseUtcOffset.Add(TimeSpan.FromHours(info.IsDaylightSavingTime(DateTime.Now) ? 1 : 0)));
    }
}