Comment afficher DateTime avec un fuseau horaire abrégé?

je suis conscient de l' Système.Fuseau horaire classe ainsi que les nombreuses utilisations de l' DateTime.ToString () méthode. Ce que je n'ai pas pu trouver est un moyen de convertir une DateTime en une chaîne qui, en plus des informations sur l'heure et la date, contient l'abréviation du fuseau horaire à trois lettres (en fait, de la même manière que les infobulles de StackOverflow pour l'affichage du temps relatif fonctionne).

pour rendre un exemple facile à suivre pour tout le monde ainsi que de consommer, continuons avec L'exemple StackOverflow. Si vous regardez l'infobulle qui s'affiche sur les heures relatives, il affiche la date complète, l'heure, y compris les secondes en format de douze heures, une désignation AM/PM, puis l'abréviation de trois lettres fuseau horaire (dans leur cas, Temps universel coordonné). Je me rends compte que je pourrais facilement obtenir GMT ou UTC en utilisant les méthodes intégrées, mais ce que je veux vraiment est le temps comme il est localement-dans ce cas, sur un serveur web.

Si notre serveur est en cours d'exécution Windows Server 2k3 et a défini son fuseau horaire à CST (ou, jusqu'à heure interrupteurs de retour, CDT est-il?), J'aimerais ASP.NET application web pour afficher les DateTimes relatives à ce fuseau horaire ainsi que formaté pour afficher un "CST" à la fin. Je sais que je pourrais facilement le coder en dur, mais dans l'intérêt de la robustesse, je préférerais vraiment une solution basée sur le serveur qui exécute les paramètres D'environnement OS du code.

pour l'instant, j'ai tout sauf le fuseau horaire abréviation utilisant le code suivant:

myDateTime.ToString("MM/dd/yyyy hh:mm:ss tt")

Qui s'affiche:

10/07/2008 03:40: 31 PM

Tout ce que je veux (et ce n'est pas beaucoup, promis!!!), c'est de dire:

10/07/2008 03:40: 31 PM CDT

je peux utiliser le Système.fuseau.CurrentTimeZone et utilisez-le pour afficher correctement "Central Daylight Time" mais... c'est un peu trop long pour être bref. Est-ce que je suis alors coincé à écrire une routine de manipulation de ficelle pour rayer l'espace blanc et n'importe quel des lettres sans majuscules? Bien que ça puisse marcher, ça me semble incroyablement bidon...

Google et en regardant autour de moi, je n'ai rien trouvé qui puisse s'appliquer à ma question spécifique.

36
demandé sur Sean Hanley 2008-10-08 00:53:42

8 réponses

voici ma méthode de piratage rapide que je viens de mettre au point.

public static String TimeZoneName(DateTime dt)
{
    String sName = TimeZone.CurrentTimeZone.IsDaylightSavingTime(dt) 
        ? TimeZone.CurrentTimeZone.DaylightName 
        : TimeZone.CurrentTimeZone.StandardName;

    String sNewName = "";
    String[] sSplit = sName.Split(new char[]{' '});
    foreach (String s in sSplit)
        if (s.Length >= 1)
            sNewName += s.Substring(0, 1);

    return sNewName;
}
19
répondu craigmoliver 2009-04-27 19:32:56

Il y a un libre accès à la bibliothèque, TZ4NET, dont les abréviations sont disponibles. Avant .NET 3.5, c'était l'une des seules alternatives pour la conversion entre les fuseaux horaires.

si vous ne voulez pas de bibliothèque séparée, Vous pouvez certainement générer une carte des abréviations raisonnables en utilisant les classes TimeZoneInfo, et puis juste les fournir à votre utilisateur.

6
répondu Dave Moore 2008-10-08 03:42:00

je créerais une table de recherche qui convertirait le nom du fuseau horaire en son abréviation. Si la correspondance n'est pas trouvée, vous pouvez retourner le nom complet de la zone.

Voir abréviations des fuseaux horaires.

2
répondu Pavel Chuchuva 2008-10-08 02:20:07

si vous retirez l'abréviation du nom D'un jour/Nom Standard, vous serez plus à même de construire la chaîne à l'aide d'un compilateur de chaînes, car les chaînes sont immuables.

    public static string ToCurrentTimeZoneString(this DateTime date)
    {
        string name = TimeZone.CurrentTimeZone.IsDaylightSavingTime(date) ?
            TimeZone.CurrentTimeZone.DaylightName :
            TimeZone.CurrentTimeZone.StandardName;
        return name;
    }

    public static string ToCurrentTimeZoneShortString(this DateTime date)
    {
        StringBuilder result = new StringBuilder();

        foreach (string value in date.ToCurrentTimeZoneString().Split(' '))
        {
            if (value.IsNotNullOrEmptyWithTrim())
            {
                result.Append(char.ToUpper(value[0]));
            }
        }

        return result.ToString();
    }

bien sûr, un tableau contenant KeyValuePair est probablement le meilleur pour une entreprise multinationale. Si vous voulez réduire de quelques minutes un délai serré, et vous êtes à une entreprise américaine, cela fonctionne.

2
répondu Bob Houghton 2011-09-29 17:14:15

Utiliser nodatime.

La fonction suivante prend un DateTime en temps UTC et le formate avec le fuseau horaire du système local abrégé. Utilisez x dans la chaîne de format pour le fuseau horaire abrégé. Rechercher le formatage personnalisé ici.

    public static string ConvertToFormattedLocalTimeWithTimezone(DateTime dateTimeUtc)
    {
        var tz = DateTimeZoneProviders.Tzdb.GetSystemDefault(); // Get the system's time zone
        var zdt = new ZonedDateTime(Instant.FromDateTimeUtc(dateTimeUtc), tz);
        return zdt.ToString("MM'/'dd'/'yyyy' 'hh':'mm':'ss' 'tt' 'x", CultureInfo.InvariantCulture);
    }
2
répondu kaptan 2014-12-12 21:42:08

Cela dépend du niveau de la robustesse dont vous avez besoin.

Vous aurez probablement besoin d'une sorte de hack. Un moyen facile de diviser la chaîne par des espaces puis concaténer la première lettre de chaque mot. i.e.

string[] words = tzname.Split(" ".ToCharArray());
string tzabbr = "";
foreach (string word in words)
   tzabbr += word[0];

Qui ne fonctionne pas pour tous les fuseaux horaires de la planète, mais il fonctionnera pour la plupart d'entre eux. Si vous avez besoin de plus solide, alors vous aurez probablement besoin de créer une carte qui mappe les noms de fuseau horaire pour leurs abréviations.

1
répondu Gerald 2008-10-07 21:40:34

Ok, ça fait 4 ans (et presque une semaine), il est temps que nous amenions LINQ dans la discussion...

Mettre ensemble Criag et Bob idées...

public static String TimeZoneName2(DateTime dt)
{
    var return ToCurrentTimeZoneShortString(dt)
                 .Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries);
    return sSplit.Aggregate("", (st,w)=> st +=w[0]);
}

sauf si vous pouvez faire confiance à TimeZone pour ne jamais retourner une chaîne avec deux espaces consécutifs:

public static String TimeZoneName3(DateTime dt)
{
    return ToCurrentTimeZoneShortString(dt).Split(' ')
                 .Aggregate("", (st,w)=> st +=w[0]);
}
0
répondu James Curran 2012-10-12 14:03:22

si vous utilisez <= .Net 3.0, téléchargez TZ4Net et utilisez OlsonTimeZone.CurrentTimeZone.StandardAbbreviation pour > .Net 3.0 utilisation NodaTime ou autres. Les noms de timezones ne sont conformes à aucune convention où vous pouvez compter sur une simple manipulation de chaîne de caractères pour construire l'Abréviation à partir d'un acronyme. Mauvais 5% du temps est encore mauvais.

0
répondu ComeIn 2014-10-27 03:06:33