63

TimeZoneInfoは、特定のタイムゾーンの略語または短い名前を提供しません。それを行う唯一の良い方法は、略語をTimezone.idStandardNameまたはDaylightNameプロパティにマップする辞書を用意することです。ただし、略語のリストを検索したすべてのソースは、タイムゾーン名が異なります。つまり、Windows とは異なります。

フルネーム、ID、または.NETの他の名前ではないユーザーをどのように表示しますか? UtcOffsetは必要ありませんが、タイムゾーンの略語-太平洋のPST、ユニバーサルのUTC、東部標準のEST-などです。可能なすべてのタイムゾーンとその略語を含むC#互換のリストまたはデータベースはありTimeZoneInfo.GetSystemTimeZones()ますか? ?

4

7 に答える 7

80

更新された回答

私の元の応答は以下のとおりであり、まだ有効です。ただし、TimeZoneNamesライブラリを使用するより簡単な方法があります。Nugetからインストールした後、次の操作を実行できます。

string tzid = theTimeZoneInfo.Id;                // example: "Eastern Standard time"
string lang = CultureInfo.CurrentCulture.Name;   // example: "en-US"
var abbreviations = TZNames.GetAbbreviationsForTimeZone(tzid, lang);

結果のオブジェクトは、次のようなプロパティを持ちます。

abbreviations.Generic == "ET"
abbreviations.Standard == "EST"
abbreviations.Daylight == "EDT"

この同じライブラリを使用して、タイムゾーンの完全にローカライズされた名前を取得することもできます。ライブラリは、CLDRデータの埋め込み自己完結型コピーを使用します。

元の回答

他の人が述べたように、タイムゾーンの略語はあいまいです。ただし、本当に表示用に1つが必要な場合は、IANA/Olsonタイムゾーンデータベースが必要です。

WindowsのタイムゾーンからIANA/Olsonのタイムゾーンに、またはその逆に移動することもできます。ただし、特定のWindowsゾーンには複数のIANA/Olsonゾーンが存在する可能性があることに注意してください。これらのマッピングは、ここのCLDRで維持されます。

NodaTimeにはデータベースとマッピングの両方があります。.NetDateTimeまたはDateTimeOffsetを使用してTimeZoneInfo、NodaTimeInstantおよびに移動できDateTimeZoneます。そこから、略語名を取得できます。

// starting with a .Net TimeZoneInfo
var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");

// You need to resolve to a specific instant in time - a noda Instant
// For illustrative purposes, I'll start from a regular .Net UTC DateTime
var dateTime = DateTime.UtcNow;
var instant = Instant.FromDateTimeUtc(dateTime);

// note that if we really wanted to just get the current instant,
// it's better and easier to use the following:
// var instant = SystemClock.Instance.Now;


// Now let's map the Windows time zone to an IANA/Olson time zone,
// using the CLDR mappings embedded in NodaTime.  This will use
// the *primary* mapping from the CLDR - that is, the ones marked
// as "territory 001".

// we need the NodaTime tzdb source.  In NodaTime 1.1.0+:
var tzdbSource = TzdbDateTimeZoneSource.Default;

// in previous NodaTime releases:
// var tzdbSource = new TzdbDateTimeZoneSource("NodaTime.TimeZones.Tzdb");

// map to the appropriate IANA/Olson tzid
var tzid = tzdbSource.MapTimeZoneId(timeZoneInfo);
        
// get a DateTimeZone from that id
var dateTimeZone = DateTimeZoneProviders.Tzdb[tzid];


// Finally, let's figure out what the abbreviation is
// for the instant and zone we have.

// now get a ZoneInterval for the zone and the instant
var zoneInterval = dateTimeZone.GetZoneInterval(instant);

// finally, you can get the correct time zone abbreviation
var abbreviation = zoneInterval.Name;

// abbreviation will be either PST or PDT depending
// on what instant was provided
Debug.WriteLine(abbreviation);
于 2013-03-08T22:25:40.140 に答える
15

これは難しい要件です。選択したリストを取得し、指定された TimeZoneInfo の省略形を取得する拡張機能/ヘルパー メソッドを作成するのが最善の方法です。

開始する場所はhttp://www.timeanddate.com/library/abbreviations/timezones/で、私が知っているゾーンをカバーするバージョンのリストがあります。

問題は、特定のタイムゾーンに複数の略語が存在する場合に適切な略語を選択することです。たとえば、UTCはUTCまたはWET (西ヨーロッパ時間)またはWEZ (Westeuropäische Zeit)またはWT (西サハラ標準時)として表すことができます。

与えられた選択に従う命名規則について、利害関係者に同意することをお勧めします。

于 2013-03-08T21:22:09.873 に答える
13

あなたの質問は、アプリケーションが動作しなければならないタイムゾーンを示していませんが、私の特定の例では、米国のタイムゾーンと UTC だけを気にする必要があります。

米国のタイム ゾーンの省略形は、常にタイム ゾーン名の各単語の最初の文字です。たとえば、「Mountain Standard Time」の略語は「MST」で、「Eastern Daylight Time」の略語は「EDT」です。

同様の要件がある場合は、次のように、ローカル タイム ゾーンの名前からローカル タイム ゾーンのタイム ゾーンの省略形を簡単に導出できます (注: ここでは、現在の日付と時刻に基づいて適切な名前を決定しています)。

string timeZoneName = TimeZone.CurrentTimeZone.IsDaylightSavingTime(DateTime.Now)
                          ? TimeZone.CurrentTimeZone.DaylightName 
                          : TimeZone.CurrentTimeZone.StandardName;

string timeZoneAbbrev = GetTzAbbreviation(timeZoneName);

関数のコードGetTzInitials()は非常に簡単です。言及する価値のあることの 1 つは、一部のタイム ゾーンがメキシコまたはカナダに設定される可能性があることです。これらのタイム ゾーン名は、"太平洋標準時 (メキシコ)" のように、括弧内に国名が表示されます。これに対処するために、括弧で囲まれたデータは直接返されます。上記に対して返される略語は「PST(Mexico)」であり、これでうまくいきます。

string GetTzAbbreviation(string timeZoneName) {
    string output = string.Empty;

    string[] timeZoneWords = timeZoneName.Split(' ');
    foreach (string timeZoneWord in timeZoneWords) {
        if (timeZoneWord[0] != '(') {
            output += timeZoneWord[0];
        } else {
            output += timeZoneWord;
        }
    }
    return output;
}
于 2014-03-29T16:02:01.117 に答える
4

すべての日付を UTC で保存し、現地時間で表示する必要があることが多いため、拡張メソッドを作成しましたToAbbreviation()

    public static string ToAbbreviation(this TimeZone theTimeZone)
    {

        string timeZoneString = theTimeZone.StandardName;
        string result = string.Concat(System.Text.RegularExpressions.Regex
           .Matches(timeZoneString, "[A-Z]")
           .OfType<System.Text.RegularExpressions.Match>()
           .Select(match => match.Value));

        return result;
    }

使用例:

string tz = TimeZone.CurrentTimeZone.ToAbbreviation();
string formattedDate = String.Format("{0:yyyy/MM/dd hh:mm:ss} {1}", myDate, tz);

または、DateTime オブジェクトから書式設定された日付文字列を取得するだけの場合:

public static string ToLocalTimeWithTimeZoneAbbreviation(this DateTime dt)
{
    DateTime localtime = dt.ToLocalTime();
    string tz = TimeZone.CurrentTimeZone.ToAbbreviation();

    string formattedDate = String.Format("{0:yyyy/MM/dd hh:mm:ss} {1}", localtime, tz);
    return formattedDate;
}

次のように使用します。

string formattedDate = myDateTimeObject.ToLocalTimeWithTimeZoneAbbreviation()

出力:2019-06-24 02:26:31 EST

于 2019-07-09T14:41:24.033 に答える
2

ドキュメントによると、「表示名は、Windows オペレーティング システムと共にインストールされたカルチャに基づいてローカライズされます。」これを中央タイム ゾーンで使用すると、DateTime「2016-09-01 12:00:00 GMT」に対して、この関数は「CDT」を返します。これは、まさにこの質問に出くわしたときに必要なものです。

public static string GetTimeZoneAbbreviation(DateTime time)
{
    string timeZoneAbbr;
    if(time.IsDaylightSavingTime() == true)
    {
        timeZoneAbbr = TimeZoneInfo.Local.DaylightName;
    }
    else
    {
        timeZoneAbbr = TimeZoneInfo.Local.StandardName;
    }

    return timeZoneAbbr;
}
于 2016-07-14T14:40:52.830 に答える
1

同様の問題がありましたが、サードパーティのライブラリを使用したくありませんでした (これらの回答のほとんどが示唆しているように)。.Net のタイムゾーン名のみをサポートし、ルックアップ テーブルを使用することにした場合は、こちらの回答をご覧ください。これは、PHP に依存して略語のリストを生成するのに役立ちます。そこのスニペットとテーブルをニーズに合わせて調整できます。

于 2016-03-22T18:42:29.350 に答える