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 属性设置不正确。我已经用谷歌搜索并检查了示例,但我并不真正理解错误消息。

任何建议表示赞赏。

问候。

编辑 - 确切的错误信息是:

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

编辑:outageEndDate.Kind = Utc

4

2 回答 2

8

感谢您澄清您的问题。

如果 DateTime 实例KindLocal,那么TimeZoneInfo.ConvertTime将期望第二个参数是您计算机的本地时区。

如果 DateTime 实例KindUtc,那么TimeZoneInfo.ConvertTime将期望第二个参数是 Utc 时区。

您需要先将 outageEndDate 转换为正确的时区,以防 localProvice 时区与您计算机上的时区不匹配。

outageEndDate = TimeZoneInfo.ConvertTime(outageEndDate, localTime);
于 2012-08-08T21:13:58.210 回答
1

这是您可以尝试的示例

这取决于您所说的“GMT + 1 时区”是什么意思。您是指永久 UTC+1,还是根据 DST 表示 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!");
}
于 2012-08-08T20:59:07.183 回答