Partager via


Conversion d'heures entre fuseaux horaires

Mise à jour : novembre 2007

Il est de plus en plus important que les applications utilisant des dates et des heures puissent gérer les différences entre fuseaux horaires. Il ne faut plus s'attendre à ce que les heures soient toutes exprimées en heure locale (heure disponible dans la structure DateTime). Par exemple, une page Web qui affiche l'heure actuelle de l'est des États-Unis manquera de crédibilité auprès d'un client d'Asie orientale. Cette rubrique explique comment convertir des heures d'un fuseau horaire à un autre, ainsi que des valeurs DateTimeOffset qui ne prennent pas complètement en charge les fuseaux horaires.

Conversion en temps universel coordonné

Le temps universel coordonné (UTC, Coordinated Universal Time) est une norme de temps atomique extrêmement précise. Les fuseaux horaires du monde sont exprimés sous la forme d'offsets positifs ou négatifs par rapport à l'heure UTC. L'heure UTC indique en quelque sorte une heure provenant d'un fuseau horaire neutre ou d'une zone sans fuseau horaire. Il est recommandé d'utiliser l'heure UTC lorsque la portabilité de la date et de l'heure sur différents ordinateurs est importante. (Pour obtenir des informations et d'autres meilleures pratiques sur l'utilisation des dates et des heures, consultez Meilleures pratiques pour le codage à l'aide de DateTime dans le .NET Framework) (en anglais). La conversion de fuseaux horaires individuels en heure UTC permet de comparer facilement les heures.

Remarque :

Vous pouvez également sérialiser une structure DateTimeOffset pour représenter clairement un point dans le temps. Comme les objets DateTimeOffset stockent une valeur de date et d'heure avec son offset par rapport à l'heure UTC, ils représentent toujours un point particulier dans le temps par rapport à l'heure UTC.

Pour effectuer une conversion en heure UTC, le plus simple est d'appeler la méthode TimeZoneInfo.ConvertTimeToUtc(DateTime)static (Shared dans Visual Basic). La conversion exacte effectuée par la méthode dépend de la valeur de la propriété dateTime du paramètre Kind, comme indiqué dans le tableau ci-dessous.

Propriété DateTime.Kind

Conversion

DateTimeKind.Local

Convertit l'heure locale en heure UTC.

DateTimeKind.Unspecified

Suppose que le paramètre dateTime est exprimé en heure locale et convertit l'heure locale en heure UTC.

DateTimeKind.Utc

Retourne le paramètre dateTime sans le modifier.

Le code suivant convertit l'heure locale actuelle en heure UTC et affiche le résultat sur la console.

Dim dateNow As Date = Date.Now      
Console.WriteLine("The date and time are {0} UTC.", _
                  TimeZoneInfo.ConvertTimeToUtc(dateNow))
DateTime dateNow = DateTime.Now;
Console.WriteLine("The date and time are {0} UTC.", 
                   TimeZoneInfo.ConvertTimeToUtc(dateNow));
Remarque :

La méthode TimeZoneInfo.ConvertTimeToUtc(DateTime) ne produit pas forcément des résultats identiques à ceux des méthodes TimeZone.ToUniversalTime et DateTime.ToUniversalTime. Si le fuseau horaire local du système hôte comprend plusieurs règles d'ajustement, TimeZoneInfo.ConvertTimeToUtc(DateTime) applique la règle appropriée à une date et une heure particulières. Les deux autres méthodes appliquent toujours la règle d'ajustement la plus récente.

Si la valeur de date et d'heure ne représente ni l'heure locale, ni l'heure UTC, la méthode ToUniversalTime retournera vraisemblablement un résultat erroné. Toutefois, vous pouvez utiliser la méthode TimeZoneInfo.ConvertTimeToUtc pour convertir la date et l'heure d'un fuseau horaire spécifié. Pour plus d'informations sur la récupération d'un objet TimeZoneInfo qui représente le fuseau horaire de destination, consultez Recherche des fuseaux horaires définis sur un système local. Le code suivant utilise la méthode TimeZoneInfo.ConvertTimeToUtc pour convertir l'heure de la côte est des États-Unis en heure UTC.

Dim easternTime As New Date(2007, 01, 02, 12, 16, 00)
Dim easternZoneId As String = "Eastern Standard Time"
Try
   Dim easternZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(easternZoneId)
   Console.WriteLine("The date and time are {0} UTC.", _ 
                     TimeZoneInfo.ConvertTimeToUtc(easternTime, easternZone))
Catch e As TimeZoneNotFoundException
   Console.WriteLine("Unable to find the {0} zone in the registry.", _
                     easternZoneId)
Catch e As InvalidTimeZoneException
   Console.WriteLine("Registry data on the {0} zone has been corrupted.", _ 
                     easternZoneId)
End Try                           
DateTime easternTime = new DateTime(2007, 01, 02, 12, 16, 00);
string easternZoneId = "Eastern Standard Time";
try
{
   TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById(easternZoneId);
   Console.WriteLine("The date and time are {0} UTC.", 
                     TimeZoneInfo.ConvertTimeToUtc(easternTime, easternZone));
}
catch (TimeZoneNotFoundException)
{
   Console.WriteLine("Unable to find the {0} zone in the registry.", 
                     easternZoneId);
}                           
catch (InvalidTimeZoneException)
{
   Console.WriteLine("Registry data on the {0} zone has been corrupted.", 
                     easternZoneId);
}

Notez que cette méthode lève une exception ArgumentException si la propriété Kind de l'objet DateTime et le fuseau horaire ne correspondent pas. Une incompatibilité se produit si la propriété Kind est DateTimeKind.Local mais l'objet TimeZoneInfo ne représente pas le fuseau horaire local ou si la propriété Kind est DateTimeKind.Utc mais l'objet TimeZoneInfo n'a pas la valeur DateTimeKind.Utc.

Toutes ces méthodes prennent des valeurs DateTime comme paramètres et retournent une valeur DateTime. Pour les valeurs DateTimeOffset, la structure DateTimeOffset a une méthode d'instance ToUniversalTime qui convertit la date et l'heure de l'instance actuelle en heure UTC. L'exemple suivant appelle la méthode ToUniversalTime pour convertir une heure locale et d'autres heures en temps universel coordonné.

Dim localTime, otherTime, universalTime As DateTimeOffset

' Define local time in local time zone
localTime = New DateTimeOffset(#6/15/2007 12:00:00PM#)
Console.WriteLine("Local time: {0}", localTime)
Console.WriteLine()

' Convert local time to offset 0 and assign to otherTime
otherTime = localTime.ToOffset(TimeSpan.Zero)
Console.WriteLine("Other time: {0}", otherTime)
Console.WriteLine("{0} = {1}: {2}", _
                  localTime, otherTime, _
                  localTime.Equals(otherTime))
Console.WriteLine("{0} exactly equals {1}: {2}", _ 
                  localTime, otherTime, _
                  localTime.EqualsExact(otherTime))
Console.WriteLine()

' Convert other time to UTC
universalTime = localTime.ToUniversalTime() 
Console.WriteLine("Universal time: {0}", universalTime)
Console.WriteLine("{0} = {1}: {2}", _
                  otherTime, universalTime, _ 
                  universalTime.Equals(otherTime))
Console.WriteLine("{0} exactly equals {1}: {2}", _ 
                  otherTime, universalTime, _
                  universalTime.EqualsExact(otherTime))
Console.WriteLine()
' The example produces the following output to the console:
'    Local time: 6/15/2007 12:00:00 PM -07:00
'    
'    Other time: 6/15/2007 7:00:00 PM +00:00
'    6/15/2007 12:00:00 PM -07:00 = 6/15/2007 7:00:00 PM +00:00: True
'    6/15/2007 12:00:00 PM -07:00 exactly equals 6/15/2007 7:00:00 PM +00:00: False
'    
'    Universal time: 6/15/2007 7:00:00 PM +00:00
'    6/15/2007 7:00:00 PM +00:00 = 6/15/2007 7:00:00 PM +00:00: True
'    6/15/2007 7:00:00 PM +00:00 exactly equals 6/15/2007 7:00:00 PM +00:00: True   
DateTimeOffset localTime, otherTime, universalTime;

// Define local time in local time zone
localTime = new DateTimeOffset(new DateTime(2007, 6, 15, 12, 0, 0));
Console.WriteLine("Local time: {0}", localTime);
Console.WriteLine();

// Convert local time to offset 0 and assign to otherTime
otherTime = localTime.ToOffset(TimeSpan.Zero);
Console.WriteLine("Other time: {0}", otherTime);
Console.WriteLine("{0} = {1}: {2}", 
                  localTime, otherTime, 
                  localTime.Equals(otherTime));
Console.WriteLine("{0} exactly equals {1}: {2}", 
                  localTime, otherTime, 
                  localTime.EqualsExact(otherTime));
Console.WriteLine();

// Convert other time to UTC
universalTime = localTime.ToUniversalTime(); 
Console.WriteLine("Universal time: {0}", universalTime);
Console.WriteLine("{0} = {1}: {2}", 
                  otherTime, universalTime, 
                  universalTime.Equals(otherTime));
Console.WriteLine("{0} exactly equals {1}: {2}", 
                  otherTime, universalTime, 
                  universalTime.EqualsExact(otherTime));
Console.WriteLine();
// The example produces the following output to the console:
//    Local time: 6/15/2007 12:00:00 PM -07:00
//    
//    Other time: 6/15/2007 7:00:00 PM +00:00
//    6/15/2007 12:00:00 PM -07:00 = 6/15/2007 7:00:00 PM +00:00: True
//    6/15/2007 12:00:00 PM -07:00 exactly equals 6/15/2007 7:00:00 PM +00:00: False
//    
//    Universal time: 6/15/2007 7:00:00 PM +00:00
//    6/15/2007 7:00:00 PM +00:00 = 6/15/2007 7:00:00 PM +00:00: True
//    6/15/2007 7:00:00 PM +00:00 exactly equals 6/15/2007 7:00:00 PM +00:00: True   

Conversion de l'heure UTC en un fuseau horaire désigné

Pour convertir l'heure UTC en heure locale, consultez la section « Conversion de l'heure UTC en heure locale » ci-dessous. Pour convertir l'heure UTC en une heure dans n'importe quel fuseau horaire que vous désignez, appelez la méthode ConvertTimeFromUtc. Cette méthode accepte deux paramètres :

Le code suivant convertit l'heure UTC en heure du Centre (des États-Unis).

Dim timeUtc As Date = Date.UtcNow
Try
   Dim cstZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")
   Dim cstTime As Date = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, cstZone)
   Console.WriteLine("The date and time are {0} {1}.", _
                     cstTime, _
                     IIf(cstZone.IsDaylightSavingTime(cstTime), _
                         cstZone.DaylightName, cstZone.StandardName))
Catch e As TimeZoneNotFoundException
   Console.WriteLine("The registry does not define the Central Standard Time zone.")
Catch e As InvalidTimeZoneException
   Console.WriteLine("Registry data on the Central Standard Time zone has been corrupted.")
End Try
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.");
}

Conversion de l'heure UTC en heure locale

Pour convertir l'heure UTC en heure locale, appelez la méthode ToLocalTime de l'objet DateTime dont vous souhaitez convertir l'heure. Le comportement exact de la méthode dépend de la valeur de la propriété Kind de l'objet, comme indiqué dans le tableau suivant.

Propriété DateTime.Kind

Conversion

DateTimeKind.Local

Retourne la valeur DateTime sans la modifier.

DateTimeKind.Unspecified

Suppose que la valeur DateTime est exprimée en heure UTC et convertit l'heure UTC en heure locale.

DateTimeKind.Utc

Convertit la valeur DateTime en heure locale.

Remarque   La méthode TimeZone.ToLocalTime se comporte comme la méthode DateTime.ToLocalTime. Elle accepte un paramètre qui est la valeur de date et d'heure à convertir.

Vous pouvez également convertir l'heure d'un fuseau horaire désigné en heure locale en faisant appel à la méthode static (Shared dans Visual Basic) TimeZoneInfo.ConvertTime. Cette technique est expliquée dans la section suivante.

Conversion entre deux fuseaux horaires

Vous pouvez effectuer une conversion entre deux fuseaux horaires en utilisant l'une des deux méthodes static suivantes (Shared dans Visual Basic) de la classe TimeZoneInfo :

  • ConvertTime

    Les paramètres de cette méthode sont la valeur de date et d'heure à convertir, un objet TimeZoneInfo qui représente le fuseau horaire de la valeur de date et d'heure et un objet TimeZoneInfo qui représente le fuseau horaire vers lequel convertir la valeur de date et d'heure.

  • ConvertTimeBySystemTimeZoneId

    Les paramètres de cette méthode sont la valeur de date et d'heure à convertir, l'identificateur du fuseau horaire de la valeur de date et d'heure et l'identificateur du fuseau horaire vers lequel convertir la valeur de date et d'heure.

Quelle que soit la méthode utilisée, la propriété Kind de la valeur de date et d'heure à convertir ainsi que l'objet TimeZoneInfo et l'identificateur de fuseau horaire qui représente son fuseau horaire doivent correspondre. Sinon, une exception ArgumentException est levée. Par exemple, si la propriété Kind de la valeur de date et d'heure est DateTimeKind.Local, une exception est levée si l'objet TimeZoneInfo passé comme paramètre à la méthode n'est pas égal à TimeZoneInfo.Local. Une exception est également levée si l'identificateur passé comme paramètre à la méthode n'est pas égal à TimeZoneInfo.Local.Id.

L'exemple suivant utilise la méthode ConvertTime pour convertir l'heure d'Hawaii en heure locale.

Dim hwTime As Date = #2/01/2007 8:00:00 AM#
Try
   Dim hwZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Hawaiian Standard Time")
   Console.WriteLine("{0} {1} is {2} local time.", _
                     hwTime, _
                     IIf(hwZone.IsDaylightSavingTime(hwTime), hwZone.DaylightName, hwZone.StandardName), _
                     TimeZoneInfo.ConvertTime(hwTime, hwZone, TimeZoneInfo.Local))
Catch e As TimeZoneNotFoundException
   Console.WriteLine("The registry does not define the Hawaiian Standard Time zone.")
Catch e As InvalidTimeZoneException
   Console.WriteLine("Registry data on the Hawaiian Standard Time zone has been corrupted.")
End Try                     
DateTime hwTime = new DateTime(2007, 02, 01, 08, 00, 00);
try
{
   TimeZoneInfo hwZone = TimeZoneInfo.FindSystemTimeZoneById("Hawaiian Standard Time");
   Console.WriteLine("{0} {1} is {2} local time.", 
           hwTime, 
           hwZone.IsDaylightSavingTime(hwTime) ? hwZone.DaylightName : hwZone.StandardName, 
           TimeZoneInfo.ConvertTime(hwTime, hwZone, TimeZoneInfo.Local));
}
catch (TimeZoneNotFoundException)
{
   Console.WriteLine("The registry does not define the Hawaiian Standard Time zone.");
}                           
catch (InvalidTimeZoneException)
{
   Console.WriteLine("Registry data on the Hawaiian STandard Time zone has been corrupted.");
}

Conversion de valeurs DateTimeOffset

Les valeurs de date et d'heure représentées par les objets DateTimeOffset ne prennent pas complètement en charge les fuseaux horaires, car l'objet est dissocié de son fuseau horaire lors de son instanciation. Toutefois, dans de nombreux cas, les application ont simplement besoin de convertir une date et une heure en fonction de deux offsets différents par rapport à l'heure UTC plutôt que de l'heure de fuseaux horaires particuliers. Pour exécuter cette conversion, vous pouvez appeler la méthode ToOffset de l'instance actuelle. L'unique paramètre de la méthode est l'offset de la nouvelle valeur de date et d'heure que la méthode doit retourner.

Par exemple, si la date et l'heure d'une demande de page Web émanant d'un utilisateur est connue et sérialisée en tant que chaîne au format MM/jj/aaaa hh:mm:ss zzzz, la méthode ReturnTimeOnServer suivante convertit cette valeur de date et d'heure en date et heure sur le serveur Web.

Public Function ReturnTimeOnServer(clientString As String) As DateTimeOffset
   Dim format As String = "M/d/yyyy H:m:s zzz"
   Dim serverOffset As TimeSpan = TimeZoneInfo.Local.GetUtcOffset(DateTimeOffset.Now)

   Try      
      Dim clientTime As DateTimeOffset = DateTimeOffset.ParseExact(clientString, format, CultureInfo.InvariantCulture)
      Dim serverTime As DateTimeOffset = clientTime.ToOffset(serverOffset)
      Return serverTime
   Catch e As FormatException
      Return DateTimeOffset.MinValue
   End Try    
End Function
public DateTimeOffset ReturnTimeOnServer(string clientString)
{
   string format = @"M/d/yyyy H:m:s zzz";
   TimeSpan serverOffset = TimeZoneInfo.Local.GetUtcOffset(DateTimeOffset.Now);

   try
   {      
      DateTimeOffset clientTime = DateTimeOffset.ParseExact(clientString, format, CultureInfo.InvariantCulture);
      DateTimeOffset serverTime = clientTime.ToOffset(serverOffset);
      return serverTime;
   }
   catch (FormatException)
   {
      return DateTimeOffset.MinValue;
   }
}

Si la chaîne "9/1/2007 5:32:07 -05:00" qui représente la date et l'heure dans un fuseau horaire, cinq heures plus tôt que l'heure UTC, est passée à la méthode, la valeur 9/1/2007 3:32:07 AM -07: 00 est retournée pour un serveur situé dans le fuseau horaire Pacifique (États-Unis).

La classe TimeZoneInfo inclut également une surcharge de la méthode TimeZoneInfo.ConvertTime(DateTimeOffset, TimeZoneInfo) qui exécute des conversions de fuseau horaire avec les valeurs DateTimeOffset. Les paramètres de la méthode sont une valeur DateTimeOffset et une référence au fuseau horaire vers lequel convertir l'heure. L'appel de méthode retourne une valeur DateTimeOffset. La méthode ReturnTimeOnServer de l'exemple précédent pourrait être réécrite comme suit pour appeler la méthode ConvertTime(DateTimeOffset, TimeZoneInfo).

Public Function ReturnTimeOnServer(clientString As String) As DateTimeOffset
   Dim format As String = "M/d/yyyy H:m:s zzz"

   Try      
      Dim clientTime As DateTimeOffset = DateTimeOffset.ParseExact(clientString, format, CultureInfo.InvariantCulture)
      Dim serverTime As DateTimeOffset = TimeZoneInfo.ConvertTime(clientTime, TimeZoneInfo.Local)
      Return serverTime
   Catch e As FormatException
      Return DateTimeOffset.MinValue
   End Try    
End Function
public DateTimeOffset ReturnTimeOnServer(string clientString)
{
   string format = @"M/d/yyyy H:m:s zzz";

   try
   {      
      DateTimeOffset clientTime = DateTimeOffset.ParseExact(clientString, format, 
                                  CultureInfo.InvariantCulture);
      DateTimeOffset serverTime = TimeZoneInfo.ConvertTime(clientTime, 
                                  TimeZoneInfo.Local);
      return serverTime;
   }
   catch (FormatException)
   {
      return DateTimeOffset.MinValue;
   }
}

Voir aussi

Concepts

Recherche des fuseaux horaires définis sur un système local

Référence

TimeZoneInfo

Autres ressources

Heures et fuseaux horaires