197

マシンのタイムゾーンが正しく設定されていないために変更された場合に、ケースをテストするための単体テストを作成しようとしています。

テストでは、ローカルタイムゾーン以外でDateTimeオブジェクトを作成して、テストを実行しているユーザーが場所に関係なく正常に作成できるようにする必要があります。

DateTimeコンストラクターからわかることから、TimeZoneをローカルタイムゾーン、UTCタイムゾーン、または指定なしのいずれかに設定できます。

PSTなどの特定のタイムゾーンでDateTimeを作成するにはどうすればよいですか?

4

9 に答える 9

250

Jon's answerはTimeZoneについて語っていますが、代わりにTimeZoneInfoを使用することをお勧めします。

個人的には、可能な限り UTC で保存するのが好きです (少なくとも過去の場合。将来の UTC の保存には潜在的な問題があります)。そのため、次のような構造をお勧めします。

public struct DateTimeWithZone
{
    private readonly DateTime utcDateTime;
    private readonly TimeZoneInfo timeZone;

    public DateTimeWithZone(DateTime dateTime, TimeZoneInfo timeZone)
    {
        var dateTimeUnspec = DateTime.SpecifyKind(dateTime, DateTimeKind.Unspecified);
        utcDateTime = TimeZoneInfo.ConvertTimeToUtc(dateTimeUnspec, timeZone); 
        this.timeZone = timeZone;
    }

    public DateTime UniversalTime { get { return utcDateTime; } }

    public TimeZoneInfo TimeZone { get { return timeZone; } }

    public DateTime LocalTime
    { 
        get 
        { 
            return TimeZoneInfo.ConvertTime(utcDateTime, timeZone); 
        }
    }        
}

わかりやすくするために、「TimeZone」の名前を「TimeZoneInfo」に変更することをお勧めします。私自身は、より短い名前を好みます。

于 2008-10-29T12:00:15.860 に答える
51

ここでの他の回答は役に立ちますが、特にパシフィックにアクセスする方法については説明していません-ここに行きます:

public static DateTime GmtToPacific(DateTime dateTime)
{
    return TimeZoneInfo.ConvertTimeFromUtc(dateTime,
        TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"));
}

奇妙なことに、通常、「太平洋標準時」は「太平洋夏時間」とは別のものを意味しますが、この場合は太平洋時間全般を指します。実際、FindSystemTimeZoneById取得に使用する場合、使用可能なプロパティの 1 つは、そのタイムゾーンが現在夏時間であるかどうかを示す bool です。

ユーザーがどこから要求しているかなどに基づいて、さまざまな TimeZones で必要な DateTimes を処理するためにまとめたライブラリで、これのより一般的な例を見ることができます。

https://github.com/b9chris/TimeZoneInfoLib.Net

時刻のリストは Windows レジストリから取得されるため、これは Windows 以外 (Linux の Mono など) では機能しません。 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\

その下にキー (レジストリ エディターのフォルダー アイコン) があります。これらのキーの名前は、 に渡すものですFindSystemTimeZoneById。Linux では、別の Linux 標準のタイムゾーン定義セットを使用する必要がありますが、これについては十分に調べていません。

于 2012-01-27T00:24:49.180 に答える
7

拡張メソッドを使用して、Jon Skeet の回答を Web 用に少し変更しました。また、魔法のように紺碧でも機能します。

public static class DateTimeWithZone
{

private static readonly TimeZoneInfo timeZone;

static DateTimeWithZone()
{
//I added web.config <add key="CurrentTimeZoneId" value="Central Europe Standard Time" />
//You can add value directly into function.
    timeZone = TimeZoneInfo.FindSystemTimeZoneById(ConfigurationManager.AppSettings["CurrentTimeZoneId"]);
}


public static DateTime LocalTime(this DateTime t)
{
     return TimeZoneInfo.ConvertTime(t, timeZone);   
}
}
于 2014-04-03T06:47:01.260 に答える
2

そのためのカスタム オブジェクトを作成する必要があります。カスタム オブジェクトには 2 つの値が含まれます。

  • DateTime 値
  • TimeZoneオブジェクト_

それを持つ CLR 提供のデータ型が既に存在するかどうかはわかりませんが、少なくとも TimeZone コンポーネントは既に利用可能です。

于 2008-10-29T11:51:21.590 に答える