web-dev-qa-db-fra.com

Obtenir DateTime pour un autre fuseau horaire indépendamment du fuseau horaire local

Indépendamment de ce que le fuseau horaire local de l'utilisateur est défini, en utilisant C # (.NET 2.0), je dois déterminer l'heure (objet DateTime) dans le fuseau horaire de l'Est.

Je connais ces méthodes, mais il ne semble pas y avoir de moyen évident d'obtenir un objet DateTime pour un fuseau horaire différent de celui dans lequel se trouve l'utilisateur.

 DateTime.Now
 DateTime.UtcNow
 TimeZone.CurrentTimeZone

Bien entendu, la solution doit prendre en compte l'heure avancée.

40
Dave

Comme tout le monde l'a mentionné, .NET 2 ne contient aucune information de fuseau horaire . Les informations sont stockées dans le registre, et il est assez simple d'écrire une classe wrapper autour de celle-ci:

SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones

contient des sous-clés pour tous les fuseaux horaires. La valeur du champ TZI contient toutes les propriétés de transition et de polarisation pour un fuseau horaire, mais toutes les informations sont contenues dans un tableau binaire. Les bits les plus importants (biais et lumière du jour), sont les int32 stockés aux positions 0 et 8 respectivement:

int bias = BitConverter.ToInt32((byte[])tzKey.GetValue("TZI"), 0);
int daylightBias = BitConverter.ToInt32((byte[])tzKey.GetValue("TZI"), 8);

Voici une archive de Comment obtenir des informations de fuseau horaire à partir du registre?

8
Andy

Dans .NET 3.5, il existe TimeZoneInfo , qui fournit de nombreuses fonctionnalités dans ce domaine; 2.0SP1 a DateTimeOffset , mais cela est beaucoup plus limité.

Obtenir UtcNow et ajouter un décalage fixe fait partie du travail, mais n'est pas compatible avec DST.

Donc, dans 3.5 je pense que vous pouvez faire quelque chose comme:

DateTime eastern = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(
    DateTime.UtcNow, "Eastern Standard Time");

Mais cela n’existe tout simplement pas dans la version 2.0; Pardon.

82
Marc Gravell

De - http://msdn.Microsoft.com/en-us/library/system.timezoneinfo.converttimefromutc.aspx

Cela permet de trouver un fuseau horaire par son nom, au cas où les États-Unis flotteraient à 15 degrés à l'ouest ou à l'est du méridien de Londres.

DateTime timeUtc = DateTime.UtcNow;
try
{
   TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
   DateTime cstTime = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, cstZone);
   Console.WriteLine("The date and time are {0} {1}.", 
                     cstTime, 
                     cstZone.IsDaylightSavingTime(cstTime) ?
                             cstZone.DaylightName : cstZone.StandardName);
}
catch (TimeZoneNotFoundException)
{
   Console.WriteLine("The registry does not define the Central Standard Time zone.");
}                           
catch (InvalidTimeZoneException)
{
   Console.WriteLine("Registry data on the Central STandard Time zone has been corrupted.");
}
6
Christopher Edwards

Je vous ferai gagner du temps et vous dirai qu'il n'existe aucun moyen dans la version 2.0 de .net proprement dite d'obtenir un objet DateTime pour un fuseau horaire différent de celui sur lequel le logiciel est exécuté (à l'exception de l'UTC).

Cependant, cela ne signifie pas qu'il n'y a pas de moyen de le faire en dehors de .net. Jetez un coup d'oeil ici à la classe TimeZoneInformation. Cette classe encapsule certains éléments p/invoke dans le système d’exploitation Windows pour obtenir les informations de fuseau horaire auprès du système d’exploitation. Je l'ai utilisé avec succès lorsque la version 2.0 était nouvelle et cela fonctionnait très bien. Le site sur lequel je travaillais devait pouvoir afficher chaque date/heure en local et être compatible avec l'heure d'été, et cette classe a rempli la facture pour nous.

2
Robert C. Barth

Que diriez-vous

 DateTime lclTime = DateTime.Now;
 DateTime ept = lclTime.ToUniversalTime().AddHours(
                   IsEasternDaylightSavingTime(
                       lclTime.ToUniversalTime())? -5: -4)

ou si vous avez déjà UTC local, juste

 DateTime lclUtc = DateTime.UtcNow;
 DateTime ept = lclUtc.AddHours(
                  IsEasternDaylightSavingTime(lclUtc)? -5: -4)

Utilisez le dictionnaire statique des valeurs codées en dur pour les dates de printemps et de repli pour l’heure de l’Est au cours des 50 prochaines années. C’est environ 300 octets ... et indexez-le ensuite pour déterminer s’il s’agit de l’heure d’été sur la côte est. .. Comme indiqué, vous ne vous souciez pas de savoir si c’est ou non dans la zone locale ... 

 private static bool IsEasternDaylightSavingTime(DateTime utcDateTime)
   {
        // hard coded method to determine 
        // whether utc datetime is Eastern Standard time
        // or Eastern Daylight Time
   }
1
Charles Bretana

Une comparaison de date est une comparaison de date. DateTime encapsule simplement une structure de mémoire définie par des ticks et crée des méthodes pour accéder aux parties de la mémoire couramment utilisées, par ex. jour ou année ou heure ou heure du jour etc.

De plus, la conversion n’est possible que si vous connaissez à la fois les décalages source et destination et le calcul est toujours tel que donné est donné par -1 * (sourceOffset - destOffset)

Où la partie entre parenthèses représente la différence de fuseau horaire.

S'il vous plaît voir aussi

Obtenir l'heure orientale en C # sans convertir l'heure locale

0
Jay