将DateTime.Now转换为不同的时区

4

这段代码长期以来一直在运行,但现在当我尝试将 DateTime.Now 作为 outageEndDate 参数传递时却出错了:

public Outage(DateTime outageStartDate, DateTime outageEndDate, Dictionary<string, string> weeklyHours, string province, string localProvince)
    {
        this.outageStartDate = outageStartDate;
        this.outageEndDate = outageEndDate;
        this.weeklyHours = weeklyHours;
        this.province = province;
        localTime = TimeZoneInfo.FindSystemTimeZoneById(timeZones[localProvince]);

        if (outageStartDate < outageEndDate)
        {
            TimeZoneInfo remoteTime = TimeZoneInfo.FindSystemTimeZoneById(timeZones[province]);
            outageStartDate = TimeZoneInfo.ConvertTime(outageStartDate, localTime, remoteTime);
            outageEndDate = TimeZoneInfo.ConvertTime(outageEndDate, localTime, remoteTime);

我在最后一行收到的错误信息是DateTime参数(outageEndDate)上的Kind属性未正确设置。我已经通过Google和SO查找了示例,但我并不真正理解错误消息。
任何建议都将不胜感激。
问候。
编辑-确切的错误消息是:
The conversion could not be completed because the supplied DateTime did not have the Kind
property set correctly.  For example, when the Kind property is DateTimeKind.Local, the source
time zone must be TimeZoneInfo.Local.  Parameter name: sourceTimeZone

EDIT: outageEndDate.Kind = Utc


请发布具体错误。谢谢。 - MethodMan
outageEndDate 的 DateTimeKind 是什么? Debug.WriteLine(string.Format("{0}", outageEndDate.Kind)); - Monroe Thomas
@DJKRAZE:请查看对原帖的编辑。 - Kevin
@MonroeThomas:请查看对原帖的编辑。 - Kevin
2个回答

8
感谢您澄清问题。
如果DateTime实例的Kind是Local,则TimeZoneInfo.ConvertTime将期望第二个参数为计算机的本地时区。
如果DateTime实例的Kind是Utc,则TimeZoneInfo.ConvertTime将期望第二个参数为Utc时区。
您需要首先将outageEndDate转换为正确的时区,以防本地省份时区与计算机上的时区不匹配。
outageEndDate = TimeZoneInfo.ConvertTime(outageEndDate, localTime);

1

这是一个你可以尝试的例子。

这取决于你所说的“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,您需要自己计算夏令时。说实话,最简单的方法是创建一个简单的查找表。计算未来几年的夏令时变化,然后编写一个简单的方法,在该列表中硬编码返回特定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!");
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接