C#:确保DateTime.Now返回GMT + 1次

时间:2009-07-10 09:38:54

标签: c# datetime timezone

我正在使用DateTime.Now根据今天的日期显示某些内容,并且在本地工作(马耳他,欧洲)时,时间显示正确(显然是因为时区)但当我将其上传到我的托管服务器时(美国),DateTime.Now不代表正确的时区。

因此,在我的代码中,如何转换DateTime.Now以正确返回GMT + 1时区的时间

3 个答案:

答案 0 :(得分:16)

使用System.Core中的TimeZoneInfo类;

您必须将DateTimeKind设置为DateTimeKind.Utc。

DateTime MyTime = new DateTime(1990, 12, 02, 19, 31, 30, DateTimeKind.Utc);

DateTime MyTimeInWesternEurope = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(MyTime, "W. Europe Standard Time");

只有当你使用.Net 3.5时才会这样做!

答案 1 :(得分:15)

这取决于“GMT + 1时区”的含义。您是指永久UTC + 1,还是指UTC + 1或UTC + 2,具体取决于夏令时?

如果您使用的是.NET 3.5,请使用TimeZoneInfo获取适当的时区,然后使用:

// Store this statically somewhere
TimeZoneInfo maltaTimeZone = TimeZoneInfo.FindSystemTimeZoneById("...");
DateTime utc = DateTime.UtcNow;
DateTime malta = TimeZoneInfo.ConvertTimeFromUtc(utc, maltaTimeZone );

您需要计算出马耳他时区的系统ID,但您可以通过在本地运行此代码轻松完成此操作:

Console.WriteLine(TimeZoneInfo.Local.Id);

根据你的评论判断,这一点将无关紧要,但仅限其他人......

如果你使用.NET 3.5,你需要自己计算夏令时。说实话,最简单的方法是一个简单的查找表。计算出未来几年的DST变化,然后编写一个简单的方法,在特定的UTC时间返回偏移量,并对该列表进行硬编码。您可能只想要一个已知已更改的已排序List<DateTime>,并且在您的日期是最后一次更改之后的1到2小时之间交替:

// Be very careful when building this list, and make sure they're UTC times!
private static readonly IEnumerable<DateTime> DstChanges = ...;

static DateTime ConvertToLocalTime(DateTime utc)
{
    int hours = 1; // Or 2, depending on the first entry in your list
    foreach (DateTime dstChange in DstChanges)
    {
        if (utc < dstChange)
        {
            return DateTime.SpecifyKind(utc.AddHours(hours), DateTimeKind.Local);
        }
        hours = 3 - hours; // Alternate between 1 and 2
    }
    throw new ArgumentOutOfRangeException("I don't have enough DST data!");
}

答案 2 :(得分:5)

我认为您不能在代码中设置一个属性,使DateTime.Now返回除代码执行的计算机当前时间以外的任何内容。如果你想要总是得到另一个时间,你可能需要包装另一个函数。您可以在UTC上进行往返并添加所需的偏移量:

private static DateTime GetMyTime()
{
    return DateTime.UtcNow.AddHours(1);
}

(在Luke对DateTime.Now的内部工作方式发表评论后更新了代码示例)