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);

最後の行に表示されるエラーメッセージは、KindプロパティがDateTimeパラメーター(outageEndDate)に正しく設定されていないことです。私はグーグルで例を探して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

編集:outageEndDate.Kind = Utc

4

2 に答える 2

8

質問を明確にしていただきありがとうございます。

DateTimeインスタンスKindがのLocal場合TimeZoneInfo.ConvertTime、2番目のパラメータはコンピュータのローカルタイムゾーンであると想定されます。

DateTimeインスタンスKindUtcの場合TimeZoneInfo.ConvertTime、2番目のパラメータはUTCタイムゾーンであると想定されます。

localProviceのタイムゾーンがコンピューターのタイムゾーンと一致しない場合に備えて、最初にoutageEndDateを適切なタイムゾーンに変換する必要があります。

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 に答える