Share via


Comment : créer des fuseaux horaires avec des règles d'ajustement

Mise à jour : novembre 2007

Les informations de fuseau horaire précises requises par une application peuvent être absentes d'un système particulier pour plusieurs raisons :

  • Le fuseau horaire n'a jamais été défini dans le Registre du système local.

  • Les données relatives au fuseau horaire ont été modifiées ou supprimées du Registre.

  • Le fuseau horaire ne dispose pas d'informations exactes sur les ajustements des fuseaux horaires pour une période donnée.

Dans ces cas précis, vous pouvez appeler la méthode CreateCustomTimeZone pour définir le fuseau horaire requis par votre application. Vous pouvez utiliser les surcharges de cette méthode pour créer un fuseau horaire avec ou sans règles d'ajustement. Si le fuseau horaire prend en charge l'heure d'été, vous pouvez définir des ajustements avec des règles d'ajustement de date fixe ou flottante. (Pour obtenir les définitions de ces termes, consultez la section « Terminologie de fuseau horaire » dans Vue d'ensemble des fuseaux horaires.)

Remarque importante :

Les fuseaux horaires personnalisés créés en appelant la méthode CreateCustomTimeZone ne sont pas ajoutés au Registre. Seule la référence d'objet retournée par l'appel de méthode CreateCustomTimeZone permet d'y accéder.

Cette rubrique indique comment créer un fuseau horaire avec des règles d'ajustement. Pour créer un fuseau horaire qui ne prend pas en charge les règles d'ajustement de l'heure d'été, consultez Comment : créer des fuseaux horaires sans règles d'ajustement.

Pour créer un fuseau horaire avec des règles d'ajustement de date flottante

  1. Pour chaque ajustement (autrement dit, pour chaque passage à/de l'heure d'hiver sur une période donnée), procédez comme suit :

    1. Définissez l'heure de début de la période de transition pour l'ajustement de fuseau horaire.

      Vous devez appeler la méthode TimeZoneInfo.TransitionTime.CreateFloatingDateRule et lui passer une valeur DateTime qui définit l'heure de la transition, deux entiers qui définissent la transition et la semaine durant laquelle la transition se produit et une valeur DayOfWeek qui définit le jour de la semaine auquel survient la transition. Cet appel de méthode instancie un objet TimeZoneInfo.TransitionTime.

    2. Définissez l'heure de fin de la période de transition pour l'ajustement de fuseau horaire. La méthode TimeZoneInfo.TransitionTime.CreateFloatingDateRule est de nouveau appelée. Cet appel de méthode instancie un deuxième objet TimeZoneInfo.TransitionTime.

    3. Appelez la méthode CreateAdjustmentRule et passez-lui les dates de début et de fin de l'ajustement, un objet TimeSpan qui définit la durée de la transition et les deux objets TimeZoneInfo.TransitionTime qui définissent quand a lieu le passage à/de l'heure d'été. Cet appel de méthode instancie un objet TimeZoneInfo.AdjustmentRule.

    4. Assignez l'objet TimeZoneInfo.AdjustmentRule à un tableau d'objets TimeZoneInfo.AdjustmentRule.

  2. Définissez le nom complet du fuseau horaire. Le nom complet respecte un format relativement standard dans lequel l'offset du fuseau horaire par rapport au temps universel coordonné (UTC, Coordinated Universal Time) est mis entre parenthèses et suivi d'une chaîne qui identifie le fuseau horaire, ainsi qu'une ou plusieurs villes ou un ou plusieurs pays ou régions du fuseau horaire.

  3. Définissez le nom de l'heure d'hiver du fuseau horaire. En général, cette chaîne est également utilisée comme identificateur de fuseau horaire.

  4. Définissez le nom de l'heure d'été du fuseau horaire.

  5. Si vous souhaitez utiliser un identificateur différent du nom standard du fuseau horaire, définissez l'identificateur de fuseau horaire.

  6. Instanciez un objet TimeSpan qui définit l'offset du fuseau horaire par rapport à l'heure UTC. Les fuseaux horaires dont les heures sont ultérieures à l'heure UTC présentent un offset positif. Inversement, les fuseaux horaires dont les heures sont antérieures à l'heure UTC présentent un offset négatif.

  7. Appelez la méthode TimeZoneInfo.CreateCustomTimeZone(String, TimeSpan, String, String, String, array<TimeZoneInfo.AdjustmentRule[]) pour instancier le nouveau fuseau horaire.

Exemple

L'exemple suivant définit un fuseau horaire du Centre des États-Unis qui inclut des règles d'ajustement pour diverses périodes à partir de 1918.

Dim cst As TimeZoneInfo
' Declare necessary TimeZoneInfo.AdjustmentRule objects for time zone
Dim delta As New TimeSpan(1, 0, 0)
Dim adjustment As TimeZoneInfo.AdjustmentRule
Dim adjustmentList As New List(Of TimeZoneInfo.AdjustmentRule)
' Declare transition time variables to hold transition time information
Dim transitionRuleStart, transitionRuleEnd As TimeZoneInfo.TransitionTime

' Define new Central Standard Time zone 6 hours earlier than UTC
' Define rule 1 (for 1918-1919)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#02:00:00AM#, 03, 05, DayOfWeek.Sunday)
transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#02:00:00AM#, 10, 05, DayOfWeek.Sunday) 
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#01/01/1918#, #12/31/1919#, delta, transitionRuleStart, transitionRuleEnd)
adjustmentList.Add(adjustment) 
' Define rule 2 (for 1942)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFixedDateRule(#2:00:00AM#, 02, 09)
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#01/01/1942#, #12/31/1942#, delta, transitionRuleStart, transitionRuleEnd)
adjustmentList.Add(adjustment)
' Define rule 3 (for 1945)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFixedDateRule(#11:00:00PM#, 08, 14)
transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFixedDateRule(#2:00:00AM#, 09, 30)
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#01/01/1945#, #12/31/1945#, delta, transitionRuleStart, transitionRuleEnd)
adjustmentList.Add(adjustment)
' Define end rule (for 1967-2006)
transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#02:00:00AM#, 10, 5, DayOfWeek.Sunday)
' Define rule 4 (for 1967-73)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#2:00:00AM#, 04, 05, DayOfWeek.Sunday)
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#01/01/1967#, #12/31/1973#, delta, transitionRuleStart, transitionRuleEnd)
adjustmentList.Add(adjustment)
' Define rule 5 (for 1974 only)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFixedDateRule(#2:00:00AM#, 01, 06)
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#01/01/1974#, #12/31/1974#, delta, transitionRuleStart, transitionRuleEnd)
adjustmentList.Add(adjustment)
' Define rule 6 (for 1975 only)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFixedDateRule(#2:00:00AM#, 02, 23)
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#01/01/1975#, #12/31/1975#, delta, transitionRuleStart, transitionRuleEnd)
adjustmentList.Add(adjustment)
' Define rule 7 (1976-1986)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#2:00:00AM#, 04, 05, DayOfWeek.Sunday)
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#01/01/1976#, #12/31/1986#, delta, transitionRuleStart, transitionRuleEnd)
adjustmentList.Add(adjustment)
' Define rule 8 (1987-2006)  
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#2:00:00AM#, 04, 01, DayOfWeek.Sunday)
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#01/01/1987#, #12/31/2006#, delta, transitionRuleStart, transitionRuleEnd)
adjustmentList.Add(adjustment)
' Define rule 9 (2007- )  
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#2:00:00AM#, 03, 02, DayOfWeek.Sunday)
transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#2:00:00AM#, 11, 01, DayOfWeek.Sunday)
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#01/01/2007#, Date.MaxValue.Date, delta, transitionRuleStart, transitionRuleEnd)
adjustmentList.Add(adjustment)

' Convert list of adjustment rules to an array
Dim adjustments(adjustmentList.Count - 1) As TimeZoneInfo.AdjustmentRule
adjustmentList.CopyTo(adjustments)

cst = TimeZoneInfo.CreateCustomTimeZone("Central Standard Time", New TimeSpan(-6, 0, 0), _
      "(GMT-06:00) Central Time (US Only)", "Central Standard Time", _
      "Central Daylight Time", adjustments)
TimeZoneInfo cst;
// Declare necessary TimeZoneInfo.AdjustmentRule objects for time zone
TimeSpan delta = new TimeSpan(1, 0, 0);
TimeZoneInfo.AdjustmentRule adjustment;
List<TimeZoneInfo.AdjustmentRule> adjustmentList = new List<TimeZoneInfo.AdjustmentRule>();
// Declare transition time variables to hold transition time information
TimeZoneInfo.TransitionTime transitionRuleStart, transitionRuleEnd;

// Define new Central Standard Time zone 6 hours earlier than UTC
// Define rule 1 (for 1918-1919)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 03, 05, DayOfWeek.Sunday);
transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 10, 05, DayOfWeek.Sunday); 
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1918, 1, 1), new DateTime(1919, 12, 31), delta, 
                                                           transitionRuleStart, transitionRuleEnd);
adjustmentList.Add(adjustment); 
// Define rule 2 (for 1942)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, 2, 0, 0), 02, 09);
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1942, 1, 1), new DateTime(1942, 12, 31), 
                                                           delta, transitionRuleStart, transitionRuleEnd);
adjustmentList.Add(adjustment);
// Define rule 3 (for 1945)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, 23, 0, 0), 08, 14);
transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, 2, 0, 0), 09, 30);
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1945, 1, 1), new DateTime(1945, 12, 31), 
                                                           delta, transitionRuleStart, transitionRuleEnd);
adjustmentList.Add(adjustment);
// Define end rule (for 1967-2006)
transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 10, 5, DayOfWeek.Sunday);
// Define rule 4 (for 1967-73)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 04, 05, DayOfWeek.Sunday);
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1967, 1, 1), new DateTime(1973, 12, 31), 
                                                           delta, transitionRuleStart, transitionRuleEnd);
adjustmentList.Add(adjustment);
// Define rule 5 (for 1974 only)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, 2, 0, 0), 01, 06);
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1974, 1, 1), new DateTime(1974, 12, 31), 
                                                           delta, transitionRuleStart, transitionRuleEnd);
adjustmentList.Add(adjustment);
// Define rule 6 (for 1975 only)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, 2, 0, 0), 02, 23);
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1975, 1, 1), new DateTime(1975, 12, 31), 
                                                           delta, transitionRuleStart, transitionRuleEnd);
adjustmentList.Add(adjustment);
// Define rule 7 (1976-1986)
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 04, 05, DayOfWeek.Sunday);
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1976, 1, 1), new DateTime(1986, 12, 31), 
                                                           delta, transitionRuleStart, transitionRuleEnd);
adjustmentList.Add(adjustment);
// Define rule 8 (1987-2006)  
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 04, 01, DayOfWeek.Sunday);
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1987, 1, 1), new DateTime(2006, 12, 31), 
                                                           delta, transitionRuleStart, transitionRuleEnd);
adjustmentList.Add(adjustment);
// Define rule 9 (2007- )  
transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 03, 02, DayOfWeek.Sunday);
transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 11, 01, DayOfWeek.Sunday);
adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(2007, 1, 1), DateTime.MaxValue.Date, 
                                                           delta, transitionRuleStart, transitionRuleEnd);
adjustmentList.Add(adjustment);

// Convert list of adjustment rules to an array
TimeZoneInfo.AdjustmentRule[] adjustments = new TimeZoneInfo.AdjustmentRule[adjustmentList.Count];
adjustmentList.CopyTo(adjustments);

cst = TimeZoneInfo.CreateCustomTimeZone("Central Standard Time", new TimeSpan(-6, 0, 0), 
      "(GMT-06:00) Central Time (US Only)", "Central Standard Time", 
      "Central Daylight Time", adjustments);

Le fuseau horaire créé dans cet exemple comporte plusieurs règles d'ajustement. Veillez à ce que les dates de début et de fin de toute règle d'ajustement ne chevauchent pas les dates d'une autre règle d'ajustement. En cas de chevauchement, une exception InvalidTimeZoneException est levée.

Pour les règles d'ajustement de date flottante, la valeur 5 est passée au paramètre week de la méthode CreateFloatingDateRule pour indiquer que la transition se produit la dernière semaine d'un mois donné.

En créant le tableau d'objets TimeZoneInfo.AdjustmentRule à utiliser dans l'appel de méthode TimeZoneInfo.CreateCustomTimeZone(String, TimeSpan, String, String, String, array<TimeZoneInfo.AdjustmentRule[]), le code pourrait initialiser le tableau à la taille requise par le nombre d'ajustements à créer pour le fuseau horaire. Au lieu de cela, cet exemple de code appelle la méthode Add pour ajouter chaque règle d'ajustement à une collection générique List<T> d'objets TimeZoneInfo.AdjustmentRule. Le code appelle ensuite la méthode CopyTo pour copier les membres de cette collection vers le tableau.

L'exemple utilise également la méthode CreateFixedDateRule pour définir des ajustements de date fixe. Cela revient à appeler la méthode CreateFloatingDateRule, sauf que seuls l'heure, le mois et le jour des paramètres de transition sont requis.

L'exemple peut être testé à l'aide du code suivant :

Dim est As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time")

Dim pastDate1 As Date = #2/11/1942#
Console.WriteLine("Is {0} daylight saving time: {1}", pastDate1, _
                  cst.IsDaylightSavingTime(pastDate1))

Dim pastDate2 As Date = #10/29/1967 1:30AM#
Console.WriteLine("Is {0} ambiguous: {1}", pastDate2, _
                  cst.IsAmbiguousTime(pastDate2))

Dim pastDate3 As Date = #1/7/1974 2:59AM#
Console.WriteLine("{0} {1} is {2} {3}", pastDate3, _
                  IIf(est.IsDaylightSavingTime(pastDate3), _
                      est.DaylightName, est.StandardName), _
                  TimeZoneInfo.ConvertTime(pastDate3, est, cst), _ 
                  IIf(cst.IsDaylightSavingTime(TimeZoneInfo.ConvertTime(pastDate3, est, cst)), _
                      cst.DaylightName, cst.StandardName)) 
'
' This code produces the following output to the console:
' 
'    Is 2/11/1942 12:00:00 AM daylight saving time: True
'    Is 10/29/1967 1:30:00 AM ambiguous: True
'    1/7/1974 2:59:00 AM Eastern Standard Time is 1/7/1974 2:59:00 AM Central Daylight Time                            
TimeZoneInfo est = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");

DateTime pastDate1 = new DateTime(1942, 2, 11);
Console.WriteLine("Is {0} daylight saving time: {1}", pastDate1, 
                  cst.IsDaylightSavingTime(pastDate1));

DateTime pastDate2 = new DateTime(1967, 10, 29, 1, 30, 00);
Console.WriteLine("Is {0} ambiguous: {1}", pastDate2, 
                  cst.IsAmbiguousTime(pastDate2));

DateTime pastDate3 = new DateTime(1974, 1, 7, 2, 59, 00);
Console.WriteLine("{0} {1} is {2} {3}", pastDate3, 
                  est.IsDaylightSavingTime(pastDate3) ? 
                      est.DaylightName : est.StandardName, 
                  TimeZoneInfo.ConvertTime(pastDate3, est, cst),  
                  cst.IsDaylightSavingTime(TimeZoneInfo.ConvertTime(pastDate3, est, cst)) ?
                      cst.DaylightName : cst.StandardName);
//
// This code produces the following output to the console:
// 
//    Is 2/11/1942 12:00:00 AM daylight saving time: True
//    Is 10/29/1967 1:30:00 AM ambiguous: True
//    1/7/1974 2:59:00 AM Eastern Standard Time is 1/7/1974 2:59:00 AM Central Daylight Time                            

Compilation du code

Cet exemple nécessite :

  • qu'une référence à System.Core.dll soit ajoutée au projet ;

  • que les espaces de noms suivants soient importés :

    Imports System.Collections.Generic
    Imports System.Collections.ObjectModel
    
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    

Voir aussi

Tâches

Comment : créer des fuseaux horaires sans règles d'ajustement

Concepts

Vue d'ensemble des fuseaux horaires

Autres ressources

Heures et fuseaux horaires