Struct System.DateTime

Cet article vous offre des remarques complémentaires à la documentation de référence pour cette API.

Important

Les ères des calendriers japonais sont basées sur le règne de l’empereur et sont donc amenées à changer. Par exemple, le 1 mai 2019 a marqué le début de l’ère Reiwa dans JapaneseCalendar et JapaneseLunisolarCalendar. Ce changement d’ère affecte toutes les applications qui utilisent ces calendriers. Pour plus d’informations et pour déterminer si vos applications sont affectées, consultez Gestion d’une nouvelle ère dans le calendrier japonais dans .NET. Pour plus d’informations sur le test de vos applications sur les systèmes Windows afin de garantir leur préparation au changement d’ère, consultez Préparer votre application pour le changement d’ère japonaise. Pour les fonctionnalités de .NET qui prennent en charge les calendriers avec plusieurs ères et pour les meilleures pratiques lors de l’utilisation de calendriers qui prennent en charge plusieurs ères, consultez Utilisation des ères.

Vue d’ensemble

Le DateTime type de valeur représente les dates et les heures avec des valeurs comprises entre 00 :00 :00 (minuit), le 1er janvier 0001 Anno Domini (Ère commune) à 11 :59 :59 :59 P.M., 31 décembre 9999 A.D. (C.E.) dans le calendrier grégorien.

Les valeurs temporelles sont mesurées en unités de 100 nanosecondes appelées graduations. Une date particulière est le nombre de graduations depuis 12 :00 minuit, le 1er janvier 0001 A.D. (C.E.) dans le GregorianCalendar calendrier. Le nombre exclut les graduations qui seraient ajoutées par secondes. Par exemple, une valeur de graduation de 3124137600000000L représente la date du vendredi 01 janvier 0100 12 :00 :00 minuit. Une DateTime valeur est toujours exprimée dans le contexte d’un calendrier explicite ou par défaut.

Remarque

Si vous utilisez une valeur de graduations que vous souhaitez convertir en un autre intervalle de temps, tel que des minutes ou des secondes, vous devez utiliser la TimeSpan.TicksPerDayvaleur , , TimeSpan.TicksPerSecondTimeSpan.TicksPerHourTimeSpan.TicksPerMinuteou TimeSpan.TicksPerMillisecond constante pour effectuer la conversion. Par exemple, pour ajouter le nombre de secondes représentées par un nombre spécifié de graduations au Second composant d’une DateTime valeur, vous pouvez utiliser l’expression dateValue.Second + nTicks/Timespan.TicksPerSecond.

Vous pouvez afficher la source pour l’ensemble complet d’exemples de cet article dans Visual Basic, F# ou C#.

Remarque

Une alternative à la structure permettant d’utiliser DateTime des valeurs de date et d’heure dans des fuseaux horaires particuliers est la DateTimeOffset structure. La DateTimeOffset structure stocke les informations de date et d’heure dans un champ privé DateTime et le nombre de minutes par lesquelles cette date et cette heure diffèrent de l’heure UTC dans un champ privé Int16 . Cela permet à une DateTimeOffset valeur de refléter l’heure dans un fuseau horaire particulier, tandis qu’une DateTime valeur ne peut refléter sans ambiguïté que l’heure UTC et l’heure du fuseau horaire local. Pour une discussion sur l’utilisation de la structure ou de la DateTime structure lors de l’utilisation DateTimeOffset des valeurs de date et d’heure, consultez Choix entre DateTime, DateTimeOffset, TimeSpan et TimeZoneInfo.

Remarque

Certains exemples C# de cet article s’exécutent dans l’exécuteur et le terrain de jeu du code inline Try.NET. Sélectionnez le bouton Exécuter pour exécuter un exemple dans une fenêtre interactive. Une fois que vous avez exécuté le code, vous pouvez le modifier et exécuter le code modifié en resélectionnant Exécuter. La code modifié s’exécute dans la fenêtre interactive ou, si la compilation échoue, la fenêtre interactive affiche tous les messages d’erreur du compilateur C#.

Le fuseau horaire local de l’exécuteur de code en ligne et du terrain de jeu inline Try.NET est le temps universel coordonné, ou UTC. Cela peut affecter le comportement et la sortie d’exemples qui illustrent les types DateTime, DateTimeOffset et TimeZoneInfo ainsi que leurs membres.

Cet article comprend plusieurs exemples qui utilisent le DateTime type :

Exemples d’initialisation

Mettre en forme DateTime des objets en tant qu’exemples de chaînes

Analyser des chaînes en tant qu’exemples DateTime d’objets

DateTime exemples de résolution

Exemples de culture et de calendriers

Exemples de persistance

Initialiser un objet DateTime

Vous pouvez affecter une valeur initiale à une nouvelle DateTime valeur de plusieurs façons différentes :

  • Appel d’un constructeur, soit l’un où vous spécifiez des arguments pour les valeurs, soit utilisez le constructeur sans paramètre implicite.
  • Affectation d’une DateTime valeur de retour d’une propriété ou d’une méthode.
  • Analyse d’une DateTime valeur à partir de sa représentation sous forme de chaîne.
  • Utilisation des fonctionnalités de langage propres à Visual Basic pour instancier un DateTime.

Les extraits de code suivants montrent des exemples de chacun d’eux.

Appeler des constructeurs

Vous appelez l’une des surcharges du DateTime constructeur qui spécifient des éléments de la valeur de date et d’heure (par exemple, l’année, le mois et le jour, ou le nombre de graduations). Le code suivant crée une date spécifique à l’aide du constructeur spécifiant l’année, le DateTime mois, le jour, l’heure, la minute et la seconde.

Dim date1 As New Date(2008, 5, 1, 8, 30, 52)
var date1 = new DateTime(2008, 5, 1, 8, 30, 52);
Console.WriteLine(date1);
let date1 = DateTime(2008, 5, 1, 8, 30, 52)
printfn $"{date1}"

Vous appelez le constructeur implicite sans paramètre de la DateTime structure lorsque vous souhaitez qu’une DateTime valeur par défaut soit initialisée. (Pour plus d’informations sur le constructeur sans paramètre implicite d’un type valeur, consultez Types valeur.) Certains compilateurs prennent également en charge la déclaration d’une DateTime valeur sans lui affecter explicitement une valeur. La création d’une valeur sans initialisation explicite entraîne également la valeur par défaut. L’exemple suivant illustre le DateTime constructeur sans paramètre implicite en C# et Visual Basic, ainsi qu’une DateTime déclaration sans affectation dans Visual Basic.

Dim dat1 As DateTime
' The following method call displays 1/1/0001 12:00:00 AM.
Console.WriteLine(dat1.ToString(System.Globalization.CultureInfo.InvariantCulture))
' The following method call displays True.
Console.WriteLine(dat1.Equals(Date.MinValue))

Dim dat2 As New DateTime()
' The following method call displays 1/1/0001 12:00:00 AM.
Console.WriteLine(dat2.ToString(System.Globalization.CultureInfo.InvariantCulture))
' The following method call displays True.
Console.WriteLine(dat2.Equals(Date.MinValue))
var dat1 = new DateTime();
// The following method call displays 1/1/0001 12:00:00 AM.
Console.WriteLine(dat1.ToString(System.Globalization.CultureInfo.InvariantCulture));
// The following method call displays True.
Console.WriteLine(dat1.Equals(DateTime.MinValue));
let dat1 = DateTime()

// The following method call displays 1/1/0001 12:00:00 AM.
printfn $"{dat1.ToString System.Globalization.CultureInfo.InvariantCulture}"

// The following method call displays True.
printfn $"{dat1.Equals DateTime.MinValue}"

Affecter une valeur calculée

Vous pouvez affecter à l’objet DateTime une valeur de date et d’heure retournée par une propriété ou une méthode. L’exemple suivant affecte la date et l’heure actuelles, la date et l’heure UTC (Temps universel coordonné) actuelles, ainsi que la date actuelle à trois nouvelles DateTime variables.

Dim date1 As Date = Date.Now
Dim date2 As Date = Date.UtcNow
Dim date3 As Date = Date.Today
DateTime date1 = DateTime.Now;
DateTime date2 = DateTime.UtcNow;
DateTime date3 = DateTime.Today;
let date1 = DateTime.Now
let date2 = DateTime.UtcNow
let date3 = DateTime.Today

Analyser une chaîne qui représente un DateTime

Les Parseméthodes , et TryParseTryParseExact les méthodes ParseExactconvertissent toutes une chaîne en sa valeur de date et d’heure équivalente. Les exemples suivants utilisent les méthodes et ParseExact les Parse méthodes pour analyser une chaîne et la convertir en DateTime valeur. Le deuxième format utilise un formulaire pris en charge par la norme ISO 8601 pour une date et une heure représentant au format de chaîne. Cette représentation standard est souvent utilisée pour transférer des informations de date dans les services web.

Dim dateString As String = "5/1/2008 8:30:52 AM"
Dim date1 As Date = Date.Parse(dateString,
                       System.Globalization.CultureInfo.InvariantCulture)
Dim iso8601String As String = "20080501T08:30:52Z"
Dim dateISO8602 As Date = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ",
                              System.Globalization.CultureInfo.InvariantCulture)
Console.WriteLine(dateISO8602)
var dateString = "5/1/2008 8:30:52 AM";
DateTime date1 = DateTime.Parse(dateString,
                          System.Globalization.CultureInfo.InvariantCulture);
var iso8601String = "20080501T08:30:52Z";
DateTime dateISO8602 = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ",
                                System.Globalization.CultureInfo.InvariantCulture);
let dateString = "5/1/2008 8:30:52 AM"
let date1 = DateTime.Parse(dateString, System.Globalization.CultureInfo.InvariantCulture)
let iso8601String = "20080501T08:30:52Z"
let dateISO8602 = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ", System.Globalization.CultureInfo.InvariantCulture)

Les TryParse méthodes et TryParseExact indiquent si une chaîne est une représentation valide d’une DateTime valeur et, le cas échéant, effectue la conversion.

Syntaxe propre au langage pour Visual Basic

L’instruction Visual Basic suivante initialise une nouvelle DateTime valeur.

Dim date1 As Date = #5/1/2008 8:30:52AM#

Valeurs DateTime et leurs représentations sous forme de chaîne

En interne, toutes les DateTime valeurs sont représentées comme le nombre de graduations (nombre d’intervalles de 100 nanosecondes) qui se sont écoulés depuis 12 :00 :00 minuit, le 1er janvier 0001. La valeur réelle DateTime est indépendante de la façon dont cette valeur apparaît lorsqu’elle s’affiche. L’apparence d’une DateTime valeur est le résultat d’une opération de mise en forme qui convertit une valeur en sa représentation sous forme de chaîne.

L’apparence des valeurs de date et d’heure dépend de la culture, des normes internationales, des exigences d’application et des préférences personnelles. La structure offre une flexibilité dans la DateTime mise en forme des valeurs de date et d’heure par le biais de surcharges de ToString. La méthode par défaut DateTime.ToString() retourne la représentation sous forme de chaîne d’une valeur de date et d’heure à l’aide du modèle de date et d’heure court de la culture actuelle. L’exemple suivant utilise la méthode par défaut DateTime.ToString() . Il affiche la date et l’heure à l’aide du modèle de date et de temps long pour la culture actuelle. La culture en-US est la culture actuelle sur l’ordinateur sur lequel l’exemple a été exécuté.

var date1 = new DateTime(2008, 3, 1, 7, 0, 0);
Console.WriteLine(date1.ToString());
// For en-US culture, displays 3/1/2008 7:00:00 AM
let date1 = DateTime(2008, 3, 1, 7, 0, 0)
printfn $"{date1.ToString()}"
// For en-US culture, displays 3/1/2008 7:00:00 AM
Dim date1 As Date = #3/1/2008 7:00AM#
Console.WriteLine(date1.ToString())
' For en-US culture, displays 3/1/2008 7:00:00 AM

Vous devrez peut-être mettre en forme des dates dans une culture spécifique pour prendre en charge les scénarios web où le serveur peut se trouver dans une culture différente du client. Vous spécifiez la culture à l’aide de la DateTime.ToString(IFormatProvider) méthode pour créer la représentation de date courte et de longue durée dans une culture spécifique. L’exemple suivant utilise la DateTime.ToString(IFormatProvider) méthode pour afficher la date et l’heure à l’aide du modèle de date et d’heure courte pour la culture fr-FR.

var date1 = new DateTime(2008, 3, 1, 7, 0, 0);
Console.WriteLine(date1.ToString(System.Globalization.CultureInfo.CreateSpecificCulture("fr-FR")));
// Displays 01/03/2008 07:00:00
let date1 = DateTime(2008, 3, 1, 7, 0, 0)
printfn $"""{date1.ToString(System.Globalization.CultureInfo.CreateSpecificCulture "fr-FR")}"""
// Displays 01/03/2008 07:00:00
Dim date1 As Date = #3/1/2008 7:00AM#
Console.WriteLine(date1.ToString(System.Globalization.CultureInfo.CreateSpecificCulture("fr-FR")))
' Displays 01/03/2008 07:00:00

D’autres applications peuvent nécessiter différentes représentations sous forme de chaîne d’une date. La DateTime.ToString(String) méthode retourne la représentation sous forme de chaîne définie par un spécificateur de format standard ou personnalisé à l’aide des conventions de mise en forme de la culture actuelle. L’exemple suivant utilise la DateTime.ToString(String) méthode pour afficher le modèle de date et d’heure complet pour la culture en-US, la culture actuelle sur l’ordinateur sur lequel l’exemple a été exécuté.

var date1 = new DateTime(2008, 3, 1, 7, 0, 0);
Console.WriteLine(date1.ToString("F"));
// Displays Saturday, March 01, 2008 7:00:00 AM
let date1 = DateTime(2008, 3, 1, 7, 0, 0)
printfn $"""{date1.ToString "F"}"""
// Displays Saturday, March 01, 2008 7:00:00 AM
Dim date1 As Date = #3/1/2008 7:00AM#
Console.WriteLine(date1.ToString("F"))
' Displays Saturday, March 01, 2008 7:00:00 AM

Enfin, vous pouvez spécifier la culture et le format à l’aide de la DateTime.ToString(String, IFormatProvider) méthode. L’exemple suivant utilise la DateTime.ToString(String, IFormatProvider) méthode pour afficher le modèle de date et d’heure complet pour la culture fr-FR.

var date1 = new DateTime(2008, 3, 1, 7, 0, 0);
Console.WriteLine(date1.ToString("F", new System.Globalization.CultureInfo("fr-FR")));
// Displays samedi 1 mars 2008 07:00:00
let date1 = DateTime(2008, 3, 1, 7, 0, 0)
printfn $"""{date1.ToString("F", new System.Globalization.CultureInfo "fr-FR")}"""
// Displays samedi 1 mars 2008 07:00:00
Dim date1 As Date = #3/1/2008 7:00AM#
Console.WriteLine(date1.ToString("F", New System.Globalization.CultureInfo("fr-FR")))
' Displays samedi 1 mars 2008 07:00:00

La DateTime.ToString(String) surcharge peut également être utilisée avec une chaîne de format personnalisée pour spécifier d’autres formats. L’exemple suivant montre comment mettre en forme une chaîne à l’aide du format standard ISO 8601 souvent utilisé pour les services web. Le format Iso 8601 n’a pas de chaîne de format standard correspondante.

var date1 = new DateTime(2008, 3, 1, 7, 0, 0, DateTimeKind.Utc);
Console.WriteLine(date1.ToString("yyyy-MM-ddTHH:mm:sszzz", System.Globalization.CultureInfo.InvariantCulture));
// Displays 2008-03-01T07:00:00+00:00
let date1 = DateTime(2008, 3, 1, 7, 0, 0, DateTimeKind.Utc)
printfn $"""{date1.ToString("yyyy-MM-ddTHH:mm:sszzz", System.Globalization.CultureInfo.InvariantCulture)}"""
// Displays 2008-03-01T07:00:00+00:00
Dim date1 As DateTime = New DateTime(2008, 3, 1, 7, 0, 0, DateTimeKind.Utc)
Console.WriteLine(date1.ToString("yyyy-MM-ddTHH:mm:sszzz", System.Globalization.CultureInfo.InvariantCulture))
' Displays 2008-03-01T07:00:00+00:00

Pour plus d’informations sur la mise en forme DateTime des valeurs, consultez Chaînes de format de date et d’heure standard et chaînes de format de date et d’heure personnalisées.

Analyser les valeurs DateTime à partir de chaînes

L’analyse convertit la représentation sous forme de chaîne d’une date et d’une heure en valeur DateTime . En règle générale, les chaînes de date et d’heure ont deux utilisations différentes dans les applications :

  • Une date et une heure prennent diverses formes et reflètent les conventions de la culture actuelle ou d’une culture spécifique. Par exemple, une application permet à un utilisateur dont la culture actuelle est en-US d’entrer une valeur de date comme « 12/15/2013 » ou « 15 décembre 2013 ». Il permet à un utilisateur dont la culture actuelle est en-gb d’entrer une valeur de date comme « 12/12/2013 » ou « 15 décembre 2013 ».

  • Une date et une heure sont représentées dans un format prédéfini. Par exemple, une application sérialise une date en tant que « 20130103 » indépendamment de la culture sur laquelle l’application s’exécute. Une application peut nécessiter une entrée dans le format de date court de la culture actuelle.

Vous utilisez la ou TryParse la Parse méthode pour convertir une chaîne à partir de l’un des formats de date et d’heure courants utilisés par une culture en DateTime valeur. L’exemple suivant montre comment convertir TryParse des chaînes de date dans différents formats spécifiques à la culture en valeur DateTime . Elle modifie la culture actuelle en anglais (Royaume-Uni) et appelle la GetDateTimeFormats() méthode pour générer un tableau de chaînes de date et d’heure. Il transmet ensuite chaque élément du tableau à la TryParse méthode. La sortie de l’exemple montre que la méthode d’analyse a réussi à convertir correctement chacune des chaînes de date et d’heure spécifiques à la culture.

System.Threading.Thread.CurrentThread.CurrentCulture =
    System.Globalization.CultureInfo.CreateSpecificCulture("en-GB");

var date1 = new DateTime(2013, 6, 1, 12, 32, 30);
var badFormats = new List<String>();

Console.WriteLine($"{"Date String",-37} {"Date",-19}\n");
foreach (var dateString in date1.GetDateTimeFormats())
{
    DateTime parsedDate;
    if (DateTime.TryParse(dateString, out parsedDate))
        Console.WriteLine($"{dateString,-37} {DateTime.Parse(dateString),-19}");
    else
        badFormats.Add(dateString);
}

// Display strings that could not be parsed.
if (badFormats.Count > 0)
{
    Console.WriteLine("\nStrings that could not be parsed: ");
    foreach (var badFormat in badFormats)
        Console.WriteLine($"   {badFormat}");
}
// Press "Run" to see the output.
System.Threading.Thread.CurrentThread.CurrentCulture <-
    System.Globalization.CultureInfo.CreateSpecificCulture "en-GB"

let date1 = DateTime(2013, 6, 1, 12, 32, 30)
let badFormats = ResizeArray<String>()

printfn "%-37s %-19s\n" "Date String" "Date"
for dateString in date1.GetDateTimeFormats() do
    match DateTime.TryParse dateString with
    | true, parsedDate ->
        printfn $"%-37s{dateString} %-19O{parsedDate}\n" 
    | _ ->
        badFormats.Add dateString

// Display strings that could not be parsed.
if badFormats.Count > 0 then
    printfn "\nStrings that could not be parsed: "
    for badFormat in badFormats do
        printfn $"   {badFormat}"
// Press "Run" to see the output.
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB")

Dim date1 As New DateTime(2013, 6, 1, 12, 32, 30)
Dim badFormats As New List(Of String)

Console.WriteLine($"{"Date String",-37} {"Date",-19}")
Console.WriteLine()
For Each dateString As String In date1.GetDateTimeFormats()
    Dim parsedDate As DateTime
    If DateTime.TryParse(dateString, parsedDate) Then
        Console.WriteLine($"{dateString,-37} {DateTime.Parse(dateString),-19:g}")
    Else
        badFormats.Add(dateString)
    End If
Next

' Display strings that could not be parsed.
If badFormats.Count > 0 Then
    Console.WriteLine()
    Console.WriteLine("Strings that could not be parsed: ")
    For Each badFormat In badFormats
        Console.WriteLine($"   {badFormat}")
    Next
End If
' The example displays the following output:
'       Date String                           Date               
'       
'       01/06/2013                            01/06/2013 00:00:00
'       01/06/13                              01/06/2013 00:00:00
'       1/6/13                                01/06/2013 00:00:00
'       1.6.13                                01/06/2013 00:00:00
'       2013-06-01                            01/06/2013 00:00:00
'       01 June 2013                          01/06/2013 00:00:00
'       1 June 2013                           01/06/2013 00:00:00
'       01 June 2013 12:32                    01/06/2013 12:32:00
'       01 June 2013 12:32                    01/06/2013 12:32:00
'       01 June 2013 12:32 PM                 01/06/2013 12:32:00
'       01 June 2013 12:32 PM                 01/06/2013 12:32:00
'       1 June 2013 12:32                     01/06/2013 12:32:00
'       1 June 2013 12:32                     01/06/2013 12:32:00
'       1 June 2013 12:32 PM                  01/06/2013 12:32:00
'       1 June 2013 12:32 PM                  01/06/2013 12:32:00
'       01 June 2013 12:32:30                 01/06/2013 12:32:30
'       01 June 2013 12:32:30                 01/06/2013 12:32:30
'       01 June 2013 12:32:30 PM              01/06/2013 12:32:30
'       01 June 2013 12:32:30 PM              01/06/2013 12:32:30
'       1 June 2013 12:32:30                  01/06/2013 12:32:30
'       1 June 2013 12:32:30                  01/06/2013 12:32:30
'       1 June 2013 12:32:30 PM               01/06/2013 12:32:30
'       1 June 2013 12:32:30 PM               01/06/2013 12:32:30
'       01/06/2013 12:32                      01/06/2013 12:32:00
'       01/06/2013 12:32                      01/06/2013 12:32:00
'       01/06/2013 12:32 PM                   01/06/2013 12:32:00
'       01/06/2013 12:32 PM                   01/06/2013 12:32:00
'       01/06/13 12:32                        01/06/2013 12:32:00
'       01/06/13 12:32                        01/06/2013 12:32:00
'       01/06/13 12:32 PM                     01/06/2013 12:32:00
'       01/06/13 12:32 PM                     01/06/2013 12:32:00
'       1/6/13 12:32                          01/06/2013 12:32:00
'       1/6/13 12:32                          01/06/2013 12:32:00
'       1/6/13 12:32 PM                       01/06/2013 12:32:00
'       1/6/13 12:32 PM                       01/06/2013 12:32:00
'       1.6.13 12:32                          01/06/2013 12:32:00
'       1.6.13 12:32                          01/06/2013 12:32:00
'       1.6.13 12:32 PM                       01/06/2013 12:32:00
'       1.6.13 12:32 PM                       01/06/2013 12:32:00
'       2013-06-01 12:32                      01/06/2013 12:32:00
'       2013-06-01 12:32                      01/06/2013 12:32:00
'       2013-06-01 12:32 PM                   01/06/2013 12:32:00
'       2013-06-01 12:32 PM                   01/06/2013 12:32:00
'       01/06/2013 12:32:30                   01/06/2013 12:32:30
'       01/06/2013 12:32:30                   01/06/2013 12:32:30
'       01/06/2013 12:32:30 PM                01/06/2013 12:32:30
'       01/06/2013 12:32:30 PM                01/06/2013 12:32:30
'       01/06/13 12:32:30                     01/06/2013 12:32:30
'       01/06/13 12:32:30                     01/06/2013 12:32:30
'       01/06/13 12:32:30 PM                  01/06/2013 12:32:30
'       01/06/13 12:32:30 PM                  01/06/2013 12:32:30
'       1/6/13 12:32:30                       01/06/2013 12:32:30
'       1/6/13 12:32:30                       01/06/2013 12:32:30
'       1/6/13 12:32:30 PM                    01/06/2013 12:32:30
'       1/6/13 12:32:30 PM                    01/06/2013 12:32:30
'       1.6.13 12:32:30                       01/06/2013 12:32:30
'       1.6.13 12:32:30                       01/06/2013 12:32:30
'       1.6.13 12:32:30 PM                    01/06/2013 12:32:30
'       1.6.13 12:32:30 PM                    01/06/2013 12:32:30
'       2013-06-01 12:32:30                   01/06/2013 12:32:30
'       2013-06-01 12:32:30                   01/06/2013 12:32:30
'       2013-06-01 12:32:30 PM                01/06/2013 12:32:30
'       2013-06-01 12:32:30 PM                01/06/2013 12:32:30
'       01 June                               01/06/2013 00:00:00
'       01 June                               01/06/2013 00:00:00
'       2013-06-01T12:32:30.0000000           01/06/2013 12:32:30
'       2013-06-01T12:32:30.0000000           01/06/2013 12:32:30
'       Sat, 01 Jun 2013 12:32:30 GMT         01/06/2013 05:32:30
'       Sat, 01 Jun 2013 12:32:30 GMT         01/06/2013 05:32:30
'       2013-06-01T12:32:30                   01/06/2013 12:32:30
'       12:32                                 22/04/2013 12:32:00
'       12:32                                 22/04/2013 12:32:00
'       12:32 PM                              22/04/2013 12:32:00
'       12:32 PM                              22/04/2013 12:32:00
'       12:32:30                              22/04/2013 12:32:30
'       12:32:30                              22/04/2013 12:32:30
'       12:32:30 PM                           22/04/2013 12:32:30
'       12:32:30 PM                           22/04/2013 12:32:30
'       2013-06-01 12:32:30Z                  01/06/2013 05:32:30
'       01 June 2013 19:32:30                 01/06/2013 19:32:30
'       01 June 2013 19:32:30                 01/06/2013 19:32:30
'       01 June 2013 07:32:30 PM              01/06/2013 19:32:30
'       01 June 2013 7:32:30 PM               01/06/2013 19:32:30
'       1 June 2013 19:32:30                  01/06/2013 19:32:30
'       1 June 2013 19:32:30                  01/06/2013 19:32:30
'       1 June 2013 07:32:30 PM               01/06/2013 19:32:30
'       1 June 2013 7:32:30 PM                01/06/2013 19:32:30
'       June 2013                             01/06/2013 00:00:00
'       June 2013                             01/06/2013 00:00:00

Vous utilisez les méthodes et TryParseExact les ParseExact méthodes pour convertir une chaîne qui doit correspondre à un format ou un format particulier en valeurDateTime. Vous spécifiez une ou plusieurs chaînes de format de date et d’heure en tant que paramètre pour la méthode d’analyse. L’exemple suivant utilise la TryParseExact(String, String[], IFormatProvider, DateTimeStyles, DateTime) méthode pour convertir des chaînes qui doivent être au format « aaaaMMdd » ou au format « HHmmss » en DateTime valeurs.

string[] formats = { "yyyyMMdd", "HHmmss" };
string[] dateStrings = { "20130816", "20131608", "  20130816   ",
                   "115216", "521116", "  115216  " };
DateTime parsedDate;

foreach (var dateString in dateStrings)
{
    if (DateTime.TryParseExact(dateString, formats, null,
                               System.Globalization.DateTimeStyles.AllowWhiteSpaces |
                               System.Globalization.DateTimeStyles.AdjustToUniversal,
                               out parsedDate))
        Console.WriteLine($"{dateString} --> {parsedDate:g}");
    else
        Console.WriteLine($"Cannot convert {dateString}");
}
// The example displays the following output:
//       20130816 --> 8/16/2013 12:00 AM
//       Cannot convert 20131608
//         20130816    --> 8/16/2013 12:00 AM
//       115216 --> 4/22/2013 11:52 AM
//       Cannot convert 521116
//         115216   --> 4/22/2013 11:52 AM
let formats = [| "yyyyMMdd"; "HHmmss" |]
let dateStrings = 
    [ "20130816"; "20131608"; "  20130816   "
      "115216"; "521116"; "  115216  " ]

for dateString in dateStrings do
    match DateTime.TryParseExact(dateString, formats, null,
                                System.Globalization.DateTimeStyles.AllowWhiteSpaces |||
                                System.Globalization.DateTimeStyles.AdjustToUniversal) with
    | true, parsedDate ->
        printfn $"{dateString} --> {parsedDate:g}"
    | _ ->
        printfn $"Cannot convert {dateString}"

// The example displays the following output:
//       20130816 --> 8/16/2013 12:00 AM
//       Cannot convert 20131608
//         20130816    --> 8/16/2013 12:00 AM
//       115216 --> 4/22/2013 11:52 AM
//       Cannot convert 521116
//         115216   --> 4/22/2013 11:52 AM
Dim formats() As String = {"yyyyMMdd", "HHmmss"}
Dim dateStrings() As String = {"20130816", "20131608",
                              "  20130816   ", "115216",
                              "521116", "  115216  "}
Dim parsedDate As DateTime

For Each dateString As String In dateStrings
    If DateTime.TryParseExact(dateString, formats, Nothing,
                           DateTimeStyles.AllowWhiteSpaces Or
                           DateTimeStyles.AdjustToUniversal,
                           parsedDate) Then
        Console.WriteLine($"{dateString} --> {parsedDate:g}")
    Else
        Console.WriteLine($"Cannot convert {dateString}")
    End If
Next
' The example displays the following output:
'       20130816 --> 8/16/2013 12:00 AM
'       Cannot convert 20131608
'         20130816    --> 8/16/2013 12:00 AM
'       115216 --> 4/22/2013 11:52 AM
'       Cannot convert 521116
'         115216   --> 4/22/2013 11:52 AM

L’une des utilisations ParseExact courantes consiste à convertir une représentation sous forme de chaîne à partir d’un service web, généralement au format standard ISO 8601 . Le code suivant montre la chaîne de format appropriée à utiliser :

var iso8601String = "20080501T08:30:52Z";
DateTime dateISO8602 = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ",
    System.Globalization.CultureInfo.InvariantCulture);
Console.WriteLine($"{iso8601String} --> {dateISO8602:g}");
let iso8601String = "20080501T08:30:52Z"
let dateISO8602 = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ", System.Globalization.CultureInfo.InvariantCulture)

printfn $"{iso8601String} --> {dateISO8602:g}"
Dim iso8601String As String = "20080501T08:30:52Z"
Dim dateISO8602 As DateTime = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ", CultureInfo.InvariantCulture)
Console.WriteLine($"{iso8601String} --> {dateISO8602:g}")

Si une chaîne ne peut pas être analysée, les méthodes et ParseExact les Parse méthodes lèvent une exception. Les TryParse méthodes retournent TryParseExact une Boolean valeur qui indique si la conversion a réussi ou échoué. Vous devez utiliser les méthodes ou TryParseExact les TryParse méthodes dans les scénarios où les performances sont importantes. L’opération d’analyse pour les chaînes de date et d’heure a tendance à avoir un taux d’échec élevé, et la gestion des exceptions est coûteuse. Utilisez ces méthodes si les chaînes sont entrées par les utilisateurs ou proviennent d’une source inconnue.

Pour plus d’informations sur l’analyse des valeurs de date et d’heure, consultez Analyse des chaînes de date et d’heure.

Valeurs DateTime

Les descriptions des valeurs de temps dans le DateTime type sont souvent exprimées à l’aide de la norme UTC (Temps universel coordonné). Le temps universel coordonné est le nom internationalement reconnu pour l’heure moyenne de Greenwich (GMT). Le temps universel coordonné est le temps mesuré à zéro degrés de longitude, le point d’origine UTC. L’heure d’été n’est pas applicable à UTC.

L’heure locale est relative à un fuseau horaire particulier. Un fuseau horaire est associé à un décalage de fuseau horaire. Un décalage de fuseau horaire est le déplacement du fuseau horaire mesuré en heures à partir du point d’origine UTC. En outre, l’heure locale est éventuellement affectée par l’heure d’été, ce qui ajoute ou soustrait un ajustement d’intervalle de temps. L’heure locale est calculée en ajoutant le décalage de fuseau horaire à UTC et en ajustant l’heure d’été si nécessaire. Le décalage de fuseau horaire au point d’origine UTC est égal à zéro.

L’heure UTC convient aux calculs, comparaisons et stockage de dates et d’heure dans les fichiers. L’heure locale est appropriée pour l’affichage dans les interfaces utilisateur des applications de bureau. Les applications prenant en charge les fuseaux horaires (telles que de nombreuses applications web) doivent également fonctionner avec un certain nombre d’autres fuseaux horaires.

Si la Kind propriété d’un DateTime objet est DateTimeKind.Unspecified, elle n’est pas spécifiée si l’heure représentée est l’heure locale, l’heure UTC ou une heure dans un autre fuseau horaire.

Résolution DateTime

Remarque

En guise d’alternative à l’exécution de l’arithmétique de date et d’heure sur DateTime les valeurs pour mesurer le temps écoulé, vous pouvez utiliser la Stopwatch classe.

La Ticks propriété exprime les valeurs de date et d’heure en unités d’un dix millionième de seconde. La Millisecond propriété retourne les millièmes d’une seconde dans une valeur de date et d’heure. L’utilisation d’appels répétés à la DateTime.Now propriété pour mesurer le temps écoulé dépend de l’horloge système. L’horloge système sur les systèmes Windows 7 et Windows 8 a une résolution d’environ 15 millisecondes. Cette résolution affecte de petits intervalles de temps inférieurs à 100 millisecondes.

L’exemple suivant illustre la dépendance des valeurs de date et d’heure actuelles sur la résolution de l’horloge système. Dans l’exemple, une boucle externe se répète 20 fois et une boucle interne sert à retarder la boucle externe. Si la valeur du compteur de boucle externe est 10, un appel à la Thread.Sleep méthode introduit un délai de cinq millisecondes. L’exemple suivant montre le nombre de millisecondes retournées par la DateTime.Now.Milliseconds propriété change uniquement après l’appel à Thread.Sleep.

string output = "";
for (int ctr = 0; ctr <= 20; ctr++)
{
    output += String.Format($"{DateTime.Now.Millisecond}\n");
    // Introduce a delay loop.
    for (int delay = 0; delay <= 1000; delay++)
    { }

    if (ctr == 10)
    {
        output += "Thread.Sleep called...\n";
        System.Threading.Thread.Sleep(5);
    }
}
Console.WriteLine(output);
// Press "Run" to see the output.
let mutable output = ""
for i = 0 to 20 do
    output <- output + $"{DateTime.Now.Millisecond}\n"
    // Introduce a delay loop.
    for _ = 0 to 1000 do ()

    if i = 10 then
        output <- output + "Thread.Sleep called...\n"
        System.Threading.Thread.Sleep 5

printfn $"{output}"
// Press "Run" to see the output.
Dim output As String = ""
For ctr As Integer = 0 To 20
    output += Date.Now.Millisecond.ToString() + vbCrLf
    ' Introduce a delay loop.
    For delay As Integer = 0 To 1000
    Next

    If ctr = 10 Then
        output += "Thread.Sleep called..." + vbCrLf
        Thread.Sleep(5)
    End If
Next
Console.WriteLine(output)
' The example displays output like the following:
'       111
'       111
'       111
'       111
'       111
'       111
'       111
'       111
'       111
'       111
'       111
'       Thread.Sleep called...
'       143
'       143
'       143
'       143
'       143
'       143
'       143
'       143
'       143
'       143

Opérations DateTime

Un calcul à l’aide d’une DateTime structure, telle que Add ou Subtract, ne modifie pas la valeur de la structure. Au lieu de cela, le calcul retourne une nouvelle DateTime structure dont la valeur est le résultat du calcul.

Les opérations de conversion entre les fuseaux horaires (par exemple, entre l’heure UTC et l’heure locale, ou entre un fuseau horaire et une autre) prennent en compte l’heure d’été, mais les opérations arithmétiques et de comparaison ne le sont pas.

La DateTime structure elle-même offre une prise en charge limitée de la conversion d’un fuseau horaire à un autre. Vous pouvez utiliser la ToLocalTime méthode pour convertir l’heure UTC en heure locale, ou vous pouvez utiliser la méthode pour effectuer une ToUniversalTime conversion de l’heure locale au format UTC. Toutefois, un ensemble complet de méthodes de conversion de fuseau horaire est disponible dans la TimeZoneInfo classe. Vous convertissez l’heure dans un des fuseaux horaires du monde en heure dans n’importe quel autre fuseau horaire à l’aide de ces méthodes.

Les calculs et les comparaisons d’objets DateTime sont significatifs uniquement si les objets représentent des heures dans le même fuseau horaire. Vous pouvez utiliser un TimeZoneInfo objet pour représenter le fuseau horaire d’une DateTime valeur, bien que les deux soient faiblement couplés. Un DateTime objet n’a pas de propriété qui retourne un objet qui représente le fuseau horaire de cette valeur de date et d’heure. La Kind propriété indique s’il s’agit d’une DateTime valeur UTC, d’heure locale ou non spécifiée. Dans une application prenant en charge les fuseaux horaires, vous devez vous appuyer sur un mécanisme externe pour déterminer le fuseau horaire dans lequel un DateTime objet a été créé. Vous pouvez utiliser une structure qui encapsule à la fois la DateTime valeur et l’objet TimeZoneInfo qui représente le fuseau horaire de la DateTime valeur. Pour plus d’informations sur l’utilisation de UTC dans les calculs et les comparaisons avec DateTime des valeurs, consultez Exécution d’opérations arithmétiques avec des dates et des heures.

Chaque DateTime membre utilise implicitement le calendrier grégorien pour effectuer son opération. Les exceptions sont des méthodes qui spécifient implicitement un calendrier. Ceux-ci incluent des constructeurs qui spécifient un calendrier et des méthodes avec un paramètre dérivé de IFormatProvider, par System.Globalization.DateTimeFormatInfoexemple .

Les opérations effectuées par les membres du DateTime type tiennent compte des détails tels que les années bissextiles et le nombre de jours en un mois.

Valeurs et calendriers DateTime

La bibliothèque de classes .NET inclut un certain nombre de classes de calendrier, qui sont toutes dérivées de la Calendar classe. Il s'agit des éléments suivants :

Important

Les ères des calendriers japonais sont basées sur le règne de l’empereur et sont donc amenées à changer. Par exemple, le 1 mai 2019 a marqué le début de l’ère Reiwa dans JapaneseCalendar et JapaneseLunisolarCalendar. Ce changement d’ère affecte toutes les applications qui utilisent ces calendriers. Pour plus d’informations et pour déterminer si vos applications sont affectées, consultez Gestion d’une nouvelle ère dans le calendrier japonais dans .NET. Pour plus d’informations sur le test de vos applications sur les systèmes Windows afin de garantir leur préparation au changement d’ère, consultez Préparer votre application pour le changement d’ère japonaise. Pour les fonctionnalités de .NET qui prennent en charge les calendriers avec plusieurs ères et pour les meilleures pratiques lors de l’utilisation de calendriers qui prennent en charge plusieurs ères, consultez Utilisation des ères.

Chaque culture utilise un calendrier par défaut défini par sa propriété en lecture seule CultureInfo.Calendar . Chaque culture peut prendre en charge un ou plusieurs calendriers définis par sa propriété en lecture seule CultureInfo.OptionalCalendars . Le calendrier actuellement utilisé par un objet spécifique CultureInfo est défini par sa DateTimeFormatInfo.Calendar propriété. Il doit s’agir de l’un des calendriers trouvés dans le CultureInfo.OptionalCalendars tableau.

Le calendrier actuel d’une culture est utilisé dans toutes les opérations de mise en forme de cette culture. Par exemple, le calendrier par défaut de la culture bouddhiste thaïlandaise est le calendrier de l’ère bouddhiste thaïlandaise, qui est représenté par la ThaiBuddhistCalendar classe. Lorsqu’un CultureInfo objet qui représente la culture bouddhiste thaïlandaise est utilisé dans une opération de mise en forme de date et d’heure, le calendrier de l’ère bouddhiste thaïlandaise est utilisé par défaut. Le calendrier grégorien est utilisé uniquement si la propriété de DateTimeFormatInfo.Calendar la culture est modifiée, comme l’illustre l’exemple suivant :

var thTH = new System.Globalization.CultureInfo("th-TH");
var value = new DateTime(2016, 5, 28);

Console.WriteLine(value.ToString(thTH));

thTH.DateTimeFormat.Calendar = new System.Globalization.GregorianCalendar();
Console.WriteLine(value.ToString(thTH));
// The example displays the following output:
//       28/5/2559 0:00:00
//       28/5/2016 0:00:00
let thTH = System.Globalization.CultureInfo "th-TH"
let value = DateTime(2016, 5, 28)

printfn $"{value.ToString thTH}"

thTH.DateTimeFormat.Calendar <- System.Globalization.GregorianCalendar()

printfn $"{value.ToString thTH}"

// The example displays the following output:
//       28/5/2559 0:00:00
//       28/5/2016 0:00:00
Dim thTH As New CultureInfo("th-TH")
Dim value As New DateTime(2016, 5, 28)

Console.WriteLine(value.ToString(thTH))

thTH.DateTimeFormat.Calendar = New GregorianCalendar()
Console.WriteLine(value.ToString(thTH))
' The example displays the following output:
'       28/5/2559 0:00:00
'       28/5/2016 0:00:00

Le calendrier actuel d’une culture est également utilisé dans toutes les opérations d’analyse pour cette culture, comme l’illustre l’exemple suivant.

var thTH = new System.Globalization.CultureInfo("th-TH");
var value = DateTime.Parse("28/05/2559", thTH);
Console.WriteLine(value.ToString(thTH));

thTH.DateTimeFormat.Calendar = new System.Globalization.GregorianCalendar();
Console.WriteLine(value.ToString(thTH));
// The example displays the following output:
//       28/5/2559 0:00:00
//       28/5/2016 0:00:00
let thTH = System.Globalization.CultureInfo "th-TH"
let value = DateTime.Parse("28/05/2559", thTH)
printfn $"{value.ToString thTH}"

thTH.DateTimeFormat.Calendar <- System.Globalization.GregorianCalendar()
printfn $"{value.ToString thTH}"

// The example displays the following output:
//       28/5/2559 0:00:00
//       28/5/2016 0:00:00
Private Sub ThaiBuddhistEraParse()
    Dim thTH As New CultureInfo("th-TH")
    Dim value As DateTime = DateTime.Parse("28/5/2559", thTH)
    Console.WriteLine(value.ToString(thTH))

    thTH.DateTimeFormat.Calendar = New GregorianCalendar()
    Console.WriteLine(value.ToString(thTH))
    ' The example displays the following output:
    '       28/5/2559 0:00:00
    '       28/5/2016 0:00:00
End Sub

Vous instanciez une DateTime valeur à l’aide des éléments date et heure (nombre de l’année, du mois et du jour) d’un calendrier spécifique en appelant un constructeur DateTime qui inclut un calendar paramètre et en lui transmettant un Calendar objet qui représente ce calendrier. L’exemple suivant utilise les éléments de date et d’heure du ThaiBuddhistCalendar calendrier.

var thTH = new System.Globalization.CultureInfo("th-TH");
var dat = new DateTime(2559, 5, 28, thTH.DateTimeFormat.Calendar);
Console.WriteLine($"Thai Buddhist era date: {dat.ToString("d", thTH)}");
Console.WriteLine($"Gregorian date:   {dat:d}");
// The example displays the following output:
//       Thai Buddhist Era Date:  28/5/2559
//       Gregorian Date:     28/05/2016
let thTH = System.Globalization.CultureInfo "th-TH"
let dat = DateTime(2559, 5, 28, thTH.DateTimeFormat.Calendar)

printfn $"""Thai Buddhist era date: {dat.ToString("d", thTH)}"""
printfn $"Gregorian date:   {dat:d}"

// The example displays the following output:
//       Thai Buddhist Era Date:  28/5/2559
//       Gregorian Date:     28/05/2016
Dim thTH As New CultureInfo("th-TH")
Dim dat As New DateTime(2559, 5, 28, thTH.DateTimeFormat.Calendar)
Console.WriteLine($"Thai Buddhist Era date: {dat.ToString("d", thTH)}")
Console.WriteLine($"Gregorian date:   {dat:d}")
' The example displays the following output:
'       Thai Buddhist Era Date:  28/5/2559
'       Gregorian Date:     28/05/2016

DateTime les constructeurs qui n’incluent pas de calendar paramètre supposent que les éléments de date et d’heure sont exprimés sous forme d’unités dans le calendrier grégorien.

Toutes les autres DateTime propriétés et méthodes utilisent le calendrier grégorien. Par exemple, la propriété retourne l’année DateTime.Year dans le calendrier grégorien, et la DateTime.IsLeapYear(Int32) méthode suppose que le year paramètre est une année dans le calendrier grégorien. Chaque DateTime membre qui utilise le calendrier grégorien a un membre correspondant de la Calendar classe qui utilise un calendrier spécifique. Par exemple, la méthode retourne l’année Calendar.GetYear dans un calendrier spécifique, et la Calendar.IsLeapYear méthode interprète le year paramètre comme un numéro d’année dans un calendrier spécifique. L’exemple suivant utilise à la fois les DateTime membres et les membres correspondants de la ThaiBuddhistCalendar classe.

var thTH = new System.Globalization.CultureInfo("th-TH");
var cal = thTH.DateTimeFormat.Calendar;
var dat = new DateTime(2559, 5, 28, cal);
Console.WriteLine("Using the Thai Buddhist Era calendar:");
Console.WriteLine($"Date: {dat.ToString("d", thTH)}");
Console.WriteLine($"Year: {cal.GetYear(dat)}");
Console.WriteLine($"Leap year: {cal.IsLeapYear(cal.GetYear(dat))}\n");

Console.WriteLine("Using the Gregorian calendar:");
Console.WriteLine($"Date: {dat:d}");
Console.WriteLine($"Year: {dat.Year}");
Console.WriteLine($"Leap year: {DateTime.IsLeapYear(dat.Year)}");
// The example displays the following output:
//       Using the Thai Buddhist Era calendar
//       Date :   28/5/2559
//       Year: 2559
//       Leap year :   True
//
//       Using the Gregorian calendar
//       Date :   28/05/2016
//       Year: 2016
//       Leap year :   True
let thTH = System.Globalization.CultureInfo "th-TH"
let cal = thTH.DateTimeFormat.Calendar
let dat = DateTime(2559, 5, 28, cal)
printfn "Using the Thai Buddhist Era calendar:"
printfn $"""Date: {dat.ToString("d", thTH)}"""
printfn $"Year: {cal.GetYear dat}"
printfn $"Leap year: {cal.IsLeapYear(cal.GetYear dat)}\n"

printfn "Using the Gregorian calendar:"
printfn $"Date: {dat:d}"
printfn $"Year: {dat.Year}"
printfn $"Leap year: {DateTime.IsLeapYear dat.Year}"

// The example displays the following output:
//       Using the Thai Buddhist Era calendar
//       Date :   28/5/2559
//       Year: 2559
//       Leap year :   True
//
//       Using the Gregorian calendar
//       Date :   28/05/2016
//       Year: 2016
//       Leap year :   True
Dim thTH As New CultureInfo("th-TH")
Dim cal As Calendar = thTH.DateTimeFormat.Calendar
Dim dat As New DateTime(2559, 5, 28, cal)
Console.WriteLine("Using the Thai Buddhist Era calendar:")
Console.WriteLine($"Date: {dat.ToString("d", thTH)}")
Console.WriteLine($"Year: {cal.GetYear(dat)}")
Console.WriteLine($"Leap year: {cal.IsLeapYear(cal.GetYear(dat))}")
Console.WriteLine()

Console.WriteLine("Using the Gregorian calendar:")
Console.WriteLine($"Date: {dat:d}")
Console.WriteLine($"Year: {dat.Year}")
Console.WriteLine($"Leap year: {DateTime.IsLeapYear(dat.Year)}")
' The example displays the following output:
'       Using the Thai Buddhist Era calendar
'       Date :   28/5/2559
'       Year: 2559
'       Leap year :   True
'
'       Using the Gregorian calendar
'       Date :   28/05/2016
'       Year: 2016
'       Leap year :   True

La DateTime structure inclut une DayOfWeek propriété qui retourne le jour de la semaine dans le calendrier grégorien. Il n’inclut pas de membre qui vous permet de récupérer le numéro de semaine de l’année. Pour récupérer la semaine de l’année, appelez la méthode du Calendar.GetWeekOfYear calendrier individuel. L'exemple suivant illustre cette situation.

var thTH = new System.Globalization.CultureInfo("th-TH");
var thCalendar = thTH.DateTimeFormat.Calendar;
var dat = new DateTime(1395, 8, 18, thCalendar);
Console.WriteLine("Using the Thai Buddhist Era calendar:");
Console.WriteLine($"Date: {dat.ToString("d", thTH)}");
Console.WriteLine($"Day of Week: {thCalendar.GetDayOfWeek(dat)}");
Console.WriteLine($"Week of year: {thCalendar.GetWeekOfYear(dat, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Sunday)}\n");

var greg = new System.Globalization.GregorianCalendar();
Console.WriteLine("Using the Gregorian calendar:");
Console.WriteLine($"Date: {dat:d}");
Console.WriteLine($"Day of Week: {dat.DayOfWeek}");
Console.WriteLine($"Week of year: {greg.GetWeekOfYear(dat, System.Globalization.CalendarWeekRule.FirstDay,DayOfWeek.Sunday)}");
// The example displays the following output:
//       Using the Thai Buddhist Era calendar
//       Date :  18/8/1395
//       Day of Week: Sunday
//       Week of year: 34
//
//       Using the Gregorian calendar
//       Date :  18/08/0852
//       Day of Week: Sunday
//       Week of year: 34
let thTH = System.Globalization.CultureInfo "th-TH"
let thCalendar = thTH.DateTimeFormat.Calendar
let dat = DateTime(1395, 8, 18, thCalendar)
printfn "Using the Thai Buddhist Era calendar:"
printfn $"""Date: {dat.ToString("d", thTH)}"""
printfn $"Day of Week: {thCalendar.GetDayOfWeek dat}"
printfn $"Week of year: {thCalendar.GetWeekOfYear(dat, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Sunday)}\n"

let greg = System.Globalization.GregorianCalendar()
printfn "Using the Gregorian calendar:"
printfn $"Date: {dat:d}"
printfn $"Day of Week: {dat.DayOfWeek}"
printfn $"Week of year: {greg.GetWeekOfYear(dat, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Sunday)}"

// The example displays the following output:
//       Using the Thai Buddhist Era calendar
//       Date :  18/8/1395
//       Day of Week: Sunday
//       Week of year: 34
//
//       Using the Gregorian calendar
//       Date :  18/08/0852
//       Day of Week: Sunday
//       Week of year: 34
Dim thTH As New CultureInfo("th-TH")
Dim thCalendar As Calendar = thTH.DateTimeFormat.Calendar
Dim dat As New DateTime(1395, 8, 18, thCalendar)
Console.WriteLine("Using the Thai Buddhist Era calendar:")
Console.WriteLine($"Date: {dat.ToString("d", thTH)}")
Console.WriteLine($"Day of Week: {thCalendar.GetDayOfWeek(dat)}")
Console.WriteLine($"Week of year: {thCalendar.GetWeekOfYear(dat, CalendarWeekRule.FirstDay, DayOfWeek.Sunday)}")
Console.WriteLine()

Dim greg As Calendar = New GregorianCalendar()
Console.WriteLine("Using the Gregorian calendar:")
Console.WriteLine($"Date: {dat:d}")
Console.WriteLine($"Day of Week: {dat.DayOfWeek}")
Console.WriteLine($"Week of year: {greg.GetWeekOfYear(dat, CalendarWeekRule.FirstDay, DayOfWeek.Sunday)}")
' The example displays the following output:
'       Using the Thai Buddhist Era calendar
'       Date :  18/8/1395
'       Day of Week: Sunday
'       Week of year: 34
'       
'       Using the Gregorian calendar
'       Date :  18/08/0852
'       Day of Week: Sunday
'       Week of year: 34

Pour plus d’informations sur les dates et les calendriers, consultez Utilisation des calendriers.

Conserver les valeurs DateTime

Vous pouvez conserver DateTime les valeurs de la manière suivante :

Vous devez vous assurer que la routine qui restaure les DateTime valeurs ne perd pas de données ni lève une exception quelle que soit la technique que vous choisissez. DateTime les valeurs doivent aller-retour. Autrement dit, la valeur d’origine et la valeur restaurée doivent être identiques. Et si la valeur d’origine DateTime représente un instant de temps unique, elle doit identifier le même moment de temps lorsqu’elle est restaurée.

Conserver les valeurs sous forme de chaînes

Pour restaurer DateTime les valeurs qui sont conservées en tant que chaînes, suivez les règles suivantes :

  • Faites les mêmes hypothèses sur la mise en forme propre à la culture lorsque vous restaurez la chaîne que lorsque vous l’avez conservée. Pour vous assurer qu’une chaîne peut être restaurée sur un système dont la culture actuelle est différente de la culture du système sur laquelle elle a été enregistrée, appelez la ToString surcharge pour enregistrer la chaîne à l’aide des conventions de la culture invariante. Appelez la ou TryParse(String, IFormatProvider, DateTimeStyles, DateTime) la Parse(String, IFormatProvider, DateTimeStyles) surcharge pour restaurer la chaîne à l’aide des conventions de la culture invariante. N’utilisez jamais les surcharges ou TryParse(String, DateTime) les ToString()conventions Parse(String)de la culture actuelle.

  • Si la date représente un seul moment d’heure, assurez-vous qu’elle représente le même moment dans l’heure où elle est restaurée, même sur un fuseau horaire différent. Convertissez la DateTime valeur en temps universel coordonné (UTC) avant de l’enregistrer ou de l’utiliser DateTimeOffset.

L’erreur la plus courante lors de la persistance des DateTime valeurs sous forme de chaînes consiste à s’appuyer sur les conventions de mise en forme de la culture par défaut ou actuelle. Des problèmes se produisent si la culture actuelle est différente lors de l’enregistrement et de la restauration des chaînes. L’exemple suivant illustre ces problèmes. Il enregistre cinq dates à l’aide des conventions de mise en forme de la culture actuelle, qui, dans ce cas, est l’anglais (États-Unis). Il restaure les dates à l’aide des conventions de mise en forme d’une autre culture, qui, dans ce cas, est l’anglais (Royaume-Uni). Étant donné que les conventions de mise en forme des deux cultures sont différentes, deux des dates ne peuvent pas être restaurées et les trois dates restantes sont interprétées de manière incorrecte. En outre, si les valeurs de date et d’heure d’origine représentent des moments uniques dans l’heure, les heures restaurées sont incorrectes, car les informations de fuseau horaire sont perdues.

public static void PersistAsLocalStrings()
{
    SaveLocalDatesAsString();
    RestoreLocalDatesFromString();
}

private static void SaveLocalDatesAsString()
{
    DateTime[] dates = { new DateTime(2014, 6, 14, 6, 32, 0),
                   new DateTime(2014, 7, 10, 23, 49, 0),
                   new DateTime(2015, 1, 10, 1, 16, 0),
                   new DateTime(2014, 12, 20, 21, 45, 0),
                   new DateTime(2014, 6, 2, 15, 14, 0) };
    string? output = null;

    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
    Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:");
    for (int ctr = 0; ctr < dates.Length; ctr++)
    {
        Console.WriteLine(dates[ctr].ToString("f"));
        output += dates[ctr].ToString() + (ctr != dates.Length - 1 ? "|" : "");
    }
    var sw = new StreamWriter(filenameTxt);
    sw.Write(output);
    sw.Close();
    Console.WriteLine("Saved dates...");
}

private static void RestoreLocalDatesFromString()
{
    TimeZoneInfo.ClearCachedData();
    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");
    StreamReader sr = new StreamReader(filenameTxt);
    string[] inputValues = sr.ReadToEnd().Split(new char[] { '|' },
                                                StringSplitOptions.RemoveEmptyEntries);
    sr.Close();
    Console.WriteLine("The dates on an {0} system:",
                      Thread.CurrentThread.CurrentCulture.Name);
    foreach (var inputValue in inputValues)
    {
        DateTime dateValue;
        if (DateTime.TryParse(inputValue, out dateValue))
        {
            Console.WriteLine($"'{inputValue}' --> {dateValue:f}");
        }
        else
        {
            Console.WriteLine($"Cannot parse '{inputValue}'");
        }
    }
    Console.WriteLine("Restored dates...");
}
// When saved on an en-US system, the example displays the following output:
//       Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
//       The dates on an en-US system:
//       Saturday, June 14, 2014 6:32 AM
//       Thursday, July 10, 2014 11:49 PM
//       Saturday, January 10, 2015 1:16 AM
//       Saturday, December 20, 2014 9:45 PM
//       Monday, June 02, 2014 3:14 PM
//       Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
//       Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
//       The dates on an en-GB system:
//       Cannot parse //6/14/2014 6:32:00 AM//
//       //7/10/2014 11:49:00 PM// --> 07 October 2014 23:49
//       //1/10/2015 1:16:00 AM// --> 01 October 2015 01:16
//       Cannot parse //12/20/2014 9:45:00 PM//
//       //6/2/2014 3:14:00 PM// --> 06 February 2014 15:14
//       Restored dates...
let saveLocalDatesAsString () =
    let dates = 
        [ DateTime(2014, 6, 14, 6, 32, 0)
          DateTime(2014, 7, 10, 23, 49, 0)
          DateTime(2015, 1, 10, 1, 16, 0)
          DateTime(2014, 12, 20, 21, 45, 0)
          DateTime(2014, 6, 2, 15, 14, 0) ]

    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"

    let output =
        [ for date in dates do
            printfn $"{date}"
            string date ]
        |> String.concat "|"

    use sw = new StreamWriter(filenameTxt)
    sw.Write output
    printfn "Saved dates..."

let restoreLocalDatesFromString () =
    TimeZoneInfo.ClearCachedData()
    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    Thread.CurrentThread.CurrentCulture <- CultureInfo.CreateSpecificCulture "en-GB"

    use sr = new StreamReader(filenameTxt)
    let inputValues = 
        sr.ReadToEnd().Split('|', StringSplitOptions.RemoveEmptyEntries)

    printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"

    for inputValue in inputValues do
        match DateTime.TryParse inputValue with
        | true, dateValue ->
            printfn $"'{inputValue}' --> {dateValue:f}"
        | _ ->
            printfn $"Cannot parse '{inputValue}'"

    printfn "Restored dates..."

let persistAsLocalStrings () =
    saveLocalDatesAsString ()
    restoreLocalDatesFromString ()

// When saved on an en-US system, the example displays the following output:
//       Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
//       The dates on an en-US system:
//       Saturday, June 14, 2014 6:32 AM
//       Thursday, July 10, 2014 11:49 PM
//       Saturday, January 10, 2015 1:16 AM
//       Saturday, December 20, 2014 9:45 PM
//       Monday, June 02, 2014 3:14 PM
//       Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
//       Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
//       The dates on an en-GB system:
//       Cannot parse //6/14/2014 6:32:00 AM//
//       //7/10/2014 11:49:00 PM// --> 07 October 2014 23:49
//       //1/10/2015 1:16:00 AM// --> 01 October 2015 01:16
//       Cannot parse //12/20/2014 9:45:00 PM//
//       //6/2/2014 3:14:00 PM// --> 06 February 2014 15:14
//       Restored dates...

Pour effectuer un aller-retour DateTime avec succès, procédez comme suit :

  1. Si les valeurs représentent des moments de temps uniques, convertissez-les de l’heure locale en UTC en appelant la ToUniversalTime méthode.
  2. Convertissez les dates en représentations sous forme de chaînes en appelant le ou String.Format(IFormatProvider, String, Object[]) la ToString(String, IFormatProvider) surcharge. Utilisez les conventions de mise en forme de la culture invariante en spécifiant CultureInfo.InvariantCulture comme provider argument. Spécifiez que la valeur doit aller-retour à l’aide de la chaîne de format standard « O » ou « R ».

Pour restaurer les valeurs persistantes DateTime sans perte de données, procédez comme suit :

  1. Analysez les données en appelant le ou TryParseExact la ParseExact surcharge. Spécifiez CultureInfo.InvariantCulture l’argument provider et utilisez la même chaîne de format standard que celle utilisée pour l’argument lors de la format conversion. Incluez la DateTimeStyles.RoundtripKind valeur dans l’argument styles .
  2. Si les DateTime valeurs représentent des moments uniques dans le temps, appelez la ToLocalTime méthode pour convertir la date analysée de l’heure UTC en heure locale.

L’exemple suivant utilise la culture invariante et la chaîne de format standard « O » pour vous assurer que les DateTime valeurs enregistrées et restaurées représentent le même moment dans le temps, quel que soit le système, la culture ou le fuseau horaire des systèmes source et cible.

public static void PersistAsInvariantStrings()
{
    SaveDatesAsInvariantStrings();
    RestoreDatesAsInvariantStrings();
}

private static void SaveDatesAsInvariantStrings()
{
    DateTime[] dates = { new DateTime(2014, 6, 14, 6, 32, 0),
                   new DateTime(2014, 7, 10, 23, 49, 0),
                   new DateTime(2015, 1, 10, 1, 16, 0),
                   new DateTime(2014, 12, 20, 21, 45, 0),
                   new DateTime(2014, 6, 2, 15, 14, 0) };
    string? output = null;

    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
    Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:");
    for (int ctr = 0; ctr < dates.Length; ctr++)
    {
        Console.WriteLine(dates[ctr].ToString("f"));
        output += dates[ctr].ToUniversalTime().ToString("O", CultureInfo.InvariantCulture)
                  + (ctr != dates.Length - 1 ? "|" : "");
    }
    var sw = new StreamWriter(filenameTxt);
    sw.Write(output);
    sw.Close();
    Console.WriteLine("Saved dates...");
}

private static void RestoreDatesAsInvariantStrings()
{
    TimeZoneInfo.ClearCachedData();
    Console.WriteLine("Current Time Zone: {0}",
                      TimeZoneInfo.Local.DisplayName);
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");
    StreamReader sr = new StreamReader(filenameTxt);
    string[] inputValues = sr.ReadToEnd().Split(new char[] { '|' },
                                                StringSplitOptions.RemoveEmptyEntries);
    sr.Close();
    Console.WriteLine("The dates on an {0} system:",
                      Thread.CurrentThread.CurrentCulture.Name);
    foreach (var inputValue in inputValues)
    {
        DateTime dateValue;
        if (DateTime.TryParseExact(inputValue, "O", CultureInfo.InvariantCulture,
                              DateTimeStyles.RoundtripKind, out dateValue))
        {
            Console.WriteLine($"'{inputValue}' --> {dateValue.ToLocalTime():f}");
        }
        else
        {
            Console.WriteLine("Cannot parse '{0}'", inputValue);
        }
    }
    Console.WriteLine("Restored dates...");
}
// When saved on an en-US system, the example displays the following output:
//       Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
//       The dates on an en-US system:
//       Saturday, June 14, 2014 6:32 AM
//       Thursday, July 10, 2014 11:49 PM
//       Saturday, January 10, 2015 1:16 AM
//       Saturday, December 20, 2014 9:45 PM
//       Monday, June 02, 2014 3:14 PM
//       Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
//       Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
//       The dates on an en-GB system:
//       '2014-06-14T13:32:00.0000000Z' --> 14 June 2014 14:32
//       '2014-07-11T06:49:00.0000000Z' --> 11 July 2014 07:49
//       '2015-01-10T09:16:00.0000000Z' --> 10 January 2015 09:16
//       '2014-12-21T05:45:00.0000000Z' --> 21 December 2014 05:45
//       '2014-06-02T22:14:00.0000000Z' --> 02 June 2014 23:14
//       Restored dates...
let saveDatesAsInvariantStrings () =
    let dates = 
        [ DateTime(2014, 6, 14, 6, 32, 0)
          DateTime(2014, 7, 10, 23, 49, 0)
          DateTime(2015, 1, 10, 1, 16, 0)
          DateTime(2014, 12, 20, 21, 45, 0)
          DateTime(2014, 6, 2, 15, 14, 0) ]

    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"

    let output =
        [ for date in dates do
            printfn $"{date:f}"
            date.ToUniversalTime().ToString("O", CultureInfo.InvariantCulture) ]
        |> String.concat "|"

    use sw = new StreamWriter(filenameTxt)
    sw.Write output
    printfn "Saved dates..."

let restoreDatesAsInvariantStrings () =
    TimeZoneInfo.ClearCachedData()
    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    Thread.CurrentThread.CurrentCulture <- CultureInfo.CreateSpecificCulture "en-GB"
    
    use sr = new StreamReader(filenameTxt)
    let inputValues = 
        sr.ReadToEnd().Split('|', StringSplitOptions.RemoveEmptyEntries)

    printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"

    for inputValue in inputValues do
        match DateTime.TryParseExact(inputValue, "O", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind) with
        | true, dateValue ->
            printfn $"'{inputValue}' --> {dateValue.ToLocalTime():f}"
        | _ ->
            printfn $"Cannot parse '{inputValue}'"

    printfn "Restored dates..."

let persistAsInvariantStrings () =
    saveDatesAsInvariantStrings ()
    restoreDatesAsInvariantStrings ()

// When saved on an en-US system, the example displays the following output:
//       Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
//       The dates on an en-US system:
//       Saturday, June 14, 2014 6:32 AM
//       Thursday, July 10, 2014 11:49 PM
//       Saturday, January 10, 2015 1:16 AM
//       Saturday, December 20, 2014 9:45 PM
//       Monday, June 02, 2014 3:14 PM
//       Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
//       Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
//       The dates on an en-GB system:
//       '2014-06-14T13:32:00.0000000Z' --> 14 June 2014 14:32
//       '2014-07-11T06:49:00.0000000Z' --> 11 July 2014 07:49
//       '2015-01-10T09:16:00.0000000Z' --> 10 January 2015 09:16
//       '2014-12-21T05:45:00.0000000Z' --> 21 December 2014 05:45
//       '2014-06-02T22:14:00.0000000Z' --> 02 June 2014 23:14
//       Restored dates...

Conserver les valeurs en tant qu’entiers

Vous pouvez conserver une date et une heure sous forme de Int64 valeur qui représente un certain nombre de graduations. Dans ce cas, vous n’avez pas besoin de prendre en compte la culture des systèmes sur lesquelles les DateTime valeurs sont conservées et restaurées.

Pour conserver une DateTime valeur en tant qu’entier :

  1. Si les valeurs représentent des moments uniques dans le DateTime temps, convertissez-les en UTC en appelant la ToUniversalTime méthode.
  2. Récupérez le nombre de graduations représentées par la DateTime valeur de sa Ticks propriété.

Pour restaurer une DateTime valeur qui a été conservée sous forme d’entier :

  1. Instanciez un nouvel DateTime objet en transmettant la Int64 valeur au DateTime(Int64) constructeur.
  2. Si la valeur représente un moment unique dans le DateTime temps, convertissez-la d’UTC en heure locale en appelant la ToLocalTime méthode.

L’exemple suivant conserve un tableau de valeurs sous forme d’entiers DateTime sur un système du fuseau horaire américain pacifique. Il le restaure sur un système dans la zone UTC. Le fichier qui contient les entiers inclut une Int32 valeur qui indique le nombre total de Int64 valeurs qui le suivent immédiatement.

public static void PersistAsIntegers()
{
    SaveDatesAsInts();
    RestoreDatesAsInts();
}

private static void SaveDatesAsInts()
{
    DateTime[] dates = { new DateTime(2014, 6, 14, 6, 32, 0),
                   new DateTime(2014, 7, 10, 23, 49, 0),
                   new DateTime(2015, 1, 10, 1, 16, 0),
                   new DateTime(2014, 12, 20, 21, 45, 0),
                   new DateTime(2014, 6, 2, 15, 14, 0) };

    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
    Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:");
    var ticks = new long[dates.Length];
    for (int ctr = 0; ctr < dates.Length; ctr++)
    {
        Console.WriteLine(dates[ctr].ToString("f"));
        ticks[ctr] = dates[ctr].ToUniversalTime().Ticks;
    }
    var fs = new FileStream(filenameInts, FileMode.Create);
    var bw = new BinaryWriter(fs);
    bw.Write(ticks.Length);
    foreach (var tick in ticks)
        bw.Write(tick);

    bw.Close();
    Console.WriteLine("Saved dates...");
}

private static void RestoreDatesAsInts()
{
    TimeZoneInfo.ClearCachedData();
    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");
    FileStream fs = new FileStream(filenameInts, FileMode.Open);
    BinaryReader br = new BinaryReader(fs);
    int items;
    DateTime[] dates;

    try
    {
        items = br.ReadInt32();
        dates = new DateTime[items];

        for (int ctr = 0; ctr < items; ctr++)
        {
            long ticks = br.ReadInt64();
            dates[ctr] = new DateTime(ticks).ToLocalTime();
        }
    }
    catch (EndOfStreamException)
    {
        Console.WriteLine("File corruption detected. Unable to restore data...");
        return;
    }
    catch (IOException)
    {
        Console.WriteLine("Unspecified I/O error. Unable to restore data...");
        return;
    }
    // Thrown during array initialization.
    catch (OutOfMemoryException)
    {
        Console.WriteLine("File corruption detected. Unable to restore data...");
        return;
    }
    finally
    {
        br.Close();
    }

    Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:");
    foreach (var value in dates)
        Console.WriteLine(value.ToString("f"));

    Console.WriteLine("Restored dates...");
}
// When saved on an en-US system, the example displays the following output:
//       Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
//       The dates on an en-US system:
//       Saturday, June 14, 2014 6:32 AM
//       Thursday, July 10, 2014 11:49 PM
//       Saturday, January 10, 2015 1:16 AM
//       Saturday, December 20, 2014 9:45 PM
//       Monday, June 02, 2014 3:14 PM
//       Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
//       Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
//       The dates on an en-GB system:
//       14 June 2014 14:32
//       11 July 2014 07:49
//       10 January 2015 09:16
//       21 December 2014 05:45
//       02 June 2014 23:14
//       Restored dates...
let saveDatesAsInts () =
    let dates = 
        [ DateTime(2014, 6, 14, 6, 32, 0)
          DateTime(2014, 7, 10, 23, 49, 0)
          DateTime(2015, 1, 10, 1, 16, 0)
          DateTime(2014, 12, 20, 21, 45, 0)
          DateTime(2014, 6, 2, 15, 14, 0) ]

    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"
    let ticks =
        [| for date in dates do
            printfn $"{date:f}"
            date.ToUniversalTime().Ticks |]
    use fs = new FileStream(filenameInts, FileMode.Create)
    use bw = new BinaryWriter(fs)
    bw.Write ticks.Length

    for tick in ticks do
        bw.Write tick

    printfn "Saved dates..."

let restoreDatesAsInts () =
    TimeZoneInfo.ClearCachedData()
    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    Thread.CurrentThread.CurrentCulture <- CultureInfo.CreateSpecificCulture "en-GB"
    use fs = new FileStream(filenameInts, FileMode.Open)
    use br = new BinaryReader(fs)

    try
        let items = br.ReadInt32()
        let dates =
            [| for _ in 0..items do
                let ticks = br.ReadInt64()
                DateTime(ticks).ToLocalTime() |]

        printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"
        for value in dates do
            printfn $"{value:f}"
    with 
    | :? EndOfStreamException ->
        printfn "File corruption detected. Unable to restore data..."
    | :? IOException ->
        printfn "Unspecified I/O error. Unable to restore data..."
    // Thrown during array initialization.
    | :? OutOfMemoryException ->
        printfn"File corruption detected. Unable to restore data..."

    printfn "Restored dates..."

let persistAsIntegers () =
    saveDatesAsInts ()
    restoreDatesAsInts ()

// When saved on an en-US system, the example displays the following output:
//       Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
//       The dates on an en-US system:
//       Saturday, June 14, 2014 6:32 AM
//       Thursday, July 10, 2014 11:49 PM
//       Saturday, January 10, 2015 1:16 AM
//       Saturday, December 20, 2014 9:45 PM
//       Monday, June 02, 2014 3:14 PM
//       Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
//       Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
//       The dates on an en-GB system:
//       14 June 2014 14:32
//       11 July 2014 07:49
//       10 January 2015 09:16
//       21 December 2014 05:45
//       02 June 2014 23:14
//       Restored dates...

Sérialiser les valeurs DateTime

Vous pouvez conserver DateTime des valeurs via la sérialisation vers un flux ou un fichier, puis les restaurer via la désérialisation. DateTime les données sont sérialisées dans un format d’objet spécifié. Les objets sont restaurés lorsqu’ils sont désérialisés. Un formateur ou un sérialiseur, tel que JsonSerializer ou XmlSerializer, gère le processus de sérialisation et de désérialisation. Pour plus d’informations sur la sérialisation et les types de sérialisation pris en charge par .NET, consultez Sérialisation.

L’exemple suivant utilise la XmlSerializer classe pour sérialiser et désérialiser des DateTime valeurs. Les valeurs représentent tous les jours bissextiles du XXIe siècle. La sortie représente le résultat si l’exemple est exécuté sur un système dont la culture actuelle est l’anglais (Royaume-Uni). Étant donné que vous avez désérialisé l’objet DateTime lui-même, le code n’a pas besoin de gérer les différences culturelles dans les formats de date et d’heure.

public static void PersistAsXML()
{
    // Serialize the data.
    var leapYears = new List<DateTime>();
    for (int year = 2000; year <= 2100; year += 4)
    {
        if (DateTime.IsLeapYear(year))
            leapYears.Add(new DateTime(year, 2, 29));
    }
    DateTime[] dateArray = leapYears.ToArray();

    var serializer = new XmlSerializer(dateArray.GetType());
    TextWriter sw = new StreamWriter(filenameXml);

    try
    {
        serializer.Serialize(sw, dateArray);
    }
    catch (InvalidOperationException e)
    {
        Console.WriteLine(e.InnerException?.Message);
    }
    finally
    {
        if (sw != null) sw.Close();
    }

    // Deserialize the data.
    DateTime[]? deserializedDates;
    using (var fs = new FileStream(filenameXml, FileMode.Open))
    {
        deserializedDates = (DateTime[]?)serializer.Deserialize(fs);
    }

    // Display the dates.
    Console.WriteLine($"Leap year days from 2000-2100 on an {Thread.CurrentThread.CurrentCulture.Name} system:");
    int nItems = 0;
    if (deserializedDates is not null)
    {
        foreach (var dat in deserializedDates)
        {
            Console.Write($"   {dat:d}     ");
            nItems++;
            if (nItems % 5 == 0)
                Console.WriteLine();
        }
    }
}
// The example displays the following output:
//    Leap year days from 2000-2100 on an en-GB system:
//       29/02/2000       29/02/2004       29/02/2008       29/02/2012       29/02/2016
//       29/02/2020       29/02/2024       29/02/2028       29/02/2032       29/02/2036
//       29/02/2040       29/02/2044       29/02/2048       29/02/2052       29/02/2056
//       29/02/2060       29/02/2064       29/02/2068       29/02/2072       29/02/2076
//       29/02/2080       29/02/2084       29/02/2088       29/02/2092       29/02/2096
let persistAsXML () =
    // Serialize the data.
    let leapYears =
        [| for year in 2000..4..2100 do
            if DateTime.IsLeapYear year then
                DateTime(year, 2, 29) |]

    let serializer = XmlSerializer(leapYears.GetType())
    use sw = new StreamWriter(filenameXml)

    try
        serializer.Serialize(sw, leapYears)
    with :? InvalidOperationException as e ->
        printfn $"{e.InnerException.Message}"

    // Deserialize the data.
    use fs = new FileStream(filenameXml, FileMode.Open)
        
    let deserializedDates = serializer.Deserialize fs :?> DateTime []

    // Display the dates.
    printfn $"Leap year days from 2000-2100 on an {Thread.CurrentThread.CurrentCulture.Name} system:"
    
    let mutable nItems = 0
    for dat in deserializedDates do
        printf $"   {dat:d}     "
        nItems <- nItems + 1
        if nItems % 5 = 0 then
            printfn ""

// The example displays the following output:
//    Leap year days from 2000-2100 on an en-GB system:
//       29/02/2000       29/02/2004       29/02/2008       29/02/2012       29/02/2016
//       29/02/2020       29/02/2024       29/02/2028       29/02/2032       29/02/2036
//       29/02/2040       29/02/2044       29/02/2048       29/02/2052       29/02/2056
//       29/02/2060       29/02/2064       29/02/2068       29/02/2072       29/02/2076
//       29/02/2080       29/02/2084       29/02/2088       29/02/2092       29/02/2096

L’exemple précédent n’inclut pas d’informations de temps. Si une DateTime valeur représente un moment dans le temps et est exprimée en tant qu’heure locale, convertissez-la de l’heure locale en heure UTC avant de la sérialiser en appelant la ToUniversalTime méthode. Après l’avoir désérialisé, convertissez-le d’UTC en heure locale en appelant la ToLocalTime méthode.

DateTime et TimeSpan

Les DateTime types et TimeSpan valeur diffèrent selon qu’un DateTime instant dans le temps représente un instant, tandis qu’un TimeSpan intervalle de temps représente un intervalle de temps. Vous pouvez soustraire une instance d’une DateTime autre pour obtenir un TimeSpan objet qui représente l’intervalle de temps entre eux. Vous pouvez également ajouter un positif TimeSpan au courant DateTime pour obtenir une DateTime valeur qui représente une date ultérieure.

Vous pouvez ajouter ou soustraire un intervalle de temps d’un DateTime objet. Les intervalles de temps peuvent être négatifs ou positifs, et ils peuvent être exprimés en unités telles que les cycles, les secondes ou l’objet TimeSpan .

Comparer pour l’égalité dans la tolérance

Les comparaisons d’égalité pour DateTime les valeurs sont exactes. Pour être considéré comme égal, deux valeurs doivent être exprimées comme le même nombre de cycles. Cette précision est souvent inutile ou même incorrecte pour de nombreuses applications. Souvent, vous souhaitez tester si DateTime les objets sont à peu près égaux.

L’exemple suivant montre comment comparer des valeurs à peu près équivalentes DateTime . Il accepte une petite marge de différence lors de leur déclaration égale.

public static bool RoughlyEquals(DateTime time, DateTime timeWithWindow, int windowInSeconds, int frequencyInSeconds)
{
    long delta = (long)((TimeSpan)(timeWithWindow - time)).TotalSeconds % frequencyInSeconds;
    delta = delta > windowInSeconds ? frequencyInSeconds - delta : delta;
    return Math.Abs(delta) < windowInSeconds;
}

public static void TestRoughlyEquals()
{
    int window = 10;
    int freq = 60 * 60 * 2; // 2 hours;

    DateTime d1 = DateTime.Now;

    DateTime d2 = d1.AddSeconds(2 * window);
    DateTime d3 = d1.AddSeconds(-2 * window);
    DateTime d4 = d1.AddSeconds(window / 2);
    DateTime d5 = d1.AddSeconds(-window / 2);

    DateTime d6 = (d1.AddHours(2)).AddSeconds(2 * window);
    DateTime d7 = (d1.AddHours(2)).AddSeconds(-2 * window);
    DateTime d8 = (d1.AddHours(2)).AddSeconds(window / 2);
    DateTime d9 = (d1.AddHours(2)).AddSeconds(-window / 2);

    Console.WriteLine($"d1 ({d1}) ~= d1 ({d1}): {RoughlyEquals(d1, d1, window, freq)}");
    Console.WriteLine($"d1 ({d1}) ~= d2 ({d2}): {RoughlyEquals(d1, d2, window, freq)}");
    Console.WriteLine($"d1 ({d1}) ~= d3 ({d3}): {RoughlyEquals(d1, d3, window, freq)}");
    Console.WriteLine($"d1 ({d1}) ~= d4 ({d4}): {RoughlyEquals(d1, d4, window, freq)}");
    Console.WriteLine($"d1 ({d1}) ~= d5 ({d5}): {RoughlyEquals(d1, d5, window, freq)}");

    Console.WriteLine($"d1 ({d1}) ~= d6 ({d6}): {RoughlyEquals(d1, d6, window, freq)}");
    Console.WriteLine($"d1 ({d1}) ~= d7 ({d7}): {RoughlyEquals(d1, d7, window, freq)}");
    Console.WriteLine($"d1 ({d1}) ~= d8 ({d8}): {RoughlyEquals(d1, d8, window, freq)}");
    Console.WriteLine($"d1 ({d1}) ~= d9 ({d9}): {RoughlyEquals(d1, d9, window, freq)}");
}
// The example displays output similar to the following:
//    d1 (1/28/2010 9:01:26 PM) ~= d1 (1/28/2010 9:01:26 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d2 (1/28/2010 9:01:46 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d3 (1/28/2010 9:01:06 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d4 (1/28/2010 9:01:31 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d5 (1/28/2010 9:01:21 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d6 (1/28/2010 11:01:46 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d7 (1/28/2010 11:01:06 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d8 (1/28/2010 11:01:31 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d9 (1/28/2010 11:01:21 PM): True
let roughlyEquals (time: DateTime) (timeWithWindow: DateTime) windowInSeconds frequencyInSeconds =
    let delta = 
        int64 (timeWithWindow - time).TotalSeconds % frequencyInSeconds
    
    let delta = if delta > windowInSeconds then frequencyInSeconds - delta else delta
    abs delta < windowInSeconds

let testRoughlyEquals () =
    let window = 10
    let window' = 10.
    let freq = 60 * 60 * 2 // 2 hours

    let d1 = DateTime.Now

    let d2 = d1.AddSeconds(2. * window')
    let d3 = d1.AddSeconds(-2. * window')
    let d4 = d1.AddSeconds(window' / 2.)
    let d5 = d1.AddSeconds(-window' / 2.)

    let d6 = (d1.AddHours 2).AddSeconds(2. * window')
    let d7 = (d1.AddHours 2).AddSeconds(-2. * window')
    let d8 = (d1.AddHours 2).AddSeconds(window' / 2.)
    let d9 = (d1.AddHours 2).AddSeconds(-window' / 2.)

    printfn $"d1 ({d1}) ~= d1 ({d1}): {roughlyEquals d1 d1 window freq}"
    printfn $"d1 ({d1}) ~= d2 ({d2}): {roughlyEquals d1 d2 window freq}"
    printfn $"d1 ({d1}) ~= d3 ({d3}): {roughlyEquals d1 d3 window freq}"
    printfn $"d1 ({d1}) ~= d4 ({d4}): {roughlyEquals d1 d4 window freq}"
    printfn $"d1 ({d1}) ~= d5 ({d5}): {roughlyEquals d1 d5 window freq}"

    printfn $"d1 ({d1}) ~= d6 ({d6}): {roughlyEquals d1 d6 window freq}"
    printfn $"d1 ({d1}) ~= d7 ({d7}): {roughlyEquals d1 d7 window freq}"
    printfn $"d1 ({d1}) ~= d8 ({d8}): {roughlyEquals d1 d8 window freq}"
    printfn $"d1 ({d1}) ~= d9 ({d9}): {roughlyEquals d1 d9 window freq}"

// The example displays output similar to the following:
//    d1 (1/28/2010 9:01:26 PM) ~= d1 (1/28/2010 9:01:26 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d2 (1/28/2010 9:01:46 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d3 (1/28/2010 9:01:06 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d4 (1/28/2010 9:01:31 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d5 (1/28/2010 9:01:21 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d6 (1/28/2010 11:01:46 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d7 (1/28/2010 11:01:06 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d8 (1/28/2010 11:01:31 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d9 (1/28/2010 11:01:21 PM): True
Public Shared Function RoughlyEquals(time As DateTime, timeWithWindow As DateTime,
                             windowInSeconds As Integer,
                             frequencyInSeconds As Integer) As Boolean
    Dim delta As Long = (timeWithWindow.Subtract(time)).TotalSeconds _
                                            Mod frequencyInSeconds

    If delta > windowInSeconds Then
        delta = frequencyInSeconds - delta
    End If

    Return Math.Abs(delta) < windowInSeconds
End Function

Public Shared Sub TestRoughlyEquals()
    Dim window As Integer = 10
    Dim freq As Integer = 60 * 60 * 2 ' 2 hours;
    Dim d1 As DateTime = DateTime.Now

    Dim d2 As DateTime = d1.AddSeconds(2 * window)
    Dim d3 As DateTime = d1.AddSeconds(-2 * window)
    Dim d4 As DateTime = d1.AddSeconds(window / 2)
    Dim d5 As DateTime = d1.AddSeconds(-window / 2)

    Dim d6 As DateTime = d1.AddHours(2).AddSeconds(2 * window)
    Dim d7 As DateTime = d1.AddHours(2).AddSeconds(-2 * window)
    Dim d8 As DateTime = d1.AddHours(2).AddSeconds(window / 2)
    Dim d9 As DateTime = d1.AddHours(2).AddSeconds(-window / 2)

    Console.WriteLine($"d1 ({d1}) ~= d1 ({d1}): {RoughlyEquals(d1, d1, window, freq)}")
    Console.WriteLine($"d1 ({d1}) ~= d2 ({d2}): {RoughlyEquals(d1, d2, window, freq)}")
    Console.WriteLine($"d1 ({d1}) ~= d3 ({d3}): {RoughlyEquals(d1, d3, window, freq)}")
    Console.WriteLine($"d1 ({d1}) ~= d4 ({d4}): {RoughlyEquals(d1, d4, window, freq)}")
    Console.WriteLine($"d1 ({d1}) ~= d5 ({d5}): {RoughlyEquals(d1, d5, window, freq)}")

    Console.WriteLine($"d1 ({d1}) ~= d6 ({d6}): {RoughlyEquals(d1, d6, window, freq)}")
    Console.WriteLine($"d1 ({d1}) ~= d7 ({d7}): {RoughlyEquals(d1, d7, window, freq)}")
    Console.WriteLine($"d1 ({d1}) ~= d8 ({d8}): {RoughlyEquals(d1, d8, window, freq)}")
    Console.WriteLine($"d1 ({d1}) ~= d9 ({d9}): {RoughlyEquals(d1, d9, window, freq)}")
End Sub
' The example displays output similar to the following:
'    d1 (1/28/2010 9:01:26 PM) ~= d1 (1/28/2010 9:01:26 PM): True
'    d1 (1/28/2010 9:01:26 PM) ~= d2 (1/28/2010 9:01:46 PM): False
'    d1 (1/28/2010 9:01:26 PM) ~= d3 (1/28/2010 9:01:06 PM): False
'    d1 (1/28/2010 9:01:26 PM) ~= d4 (1/28/2010 9:01:31 PM): True
'    d1 (1/28/2010 9:01:26 PM) ~= d5 (1/28/2010 9:01:21 PM): True
'    d1 (1/28/2010 9:01:26 PM) ~= d6 (1/28/2010 11:01:46 PM): False
'    d1 (1/28/2010 9:01:26 PM) ~= d7 (1/28/2010 11:01:06 PM): False
'    d1 (1/28/2010 9:01:26 PM) ~= d8 (1/28/2010 11:01:31 PM): True
'    d1 (1/28/2010 9:01:26 PM) ~= d9 (1/28/2010 11:01:21 PM): True

Considérations relatives à l’interopérabilité COM

Une DateTime valeur transférée vers une application COM, puis renvoyée à une application managée, est dite aller-retour. Toutefois, une DateTime valeur qui spécifie uniquement une heure n’est pas aller-retour comme prévu.

Si vous effectuez un aller-retour uniquement à une heure, par exemple 3 h, la date finale et l’heure sont le 30 décembre 1899 C.E. à 13 h 00, au lieu du 1er janvier 0001 C.E. à 3 h 00 . NET et COM supposent une date par défaut quand seule une heure est spécifiée. Toutefois, le système COM suppose une date de base du 30 décembre 1899 C.E., tandis que .NET suppose une date de base du 1er janvier 0001 C.E.

Lorsqu’une seule heure est passée de .NET à COM, un traitement spécial est effectué qui convertit l’heure au format utilisé par COM. Lorsqu’une seule heure est passée de COM à .NET, aucun traitement spécial n’est effectué, car cela endommagerait les dates et heures légitimes le 30 décembre 1899. Si une date démarre son aller-retour à partir de COM, .NET et COM conservent la date.

Le comportement de .NET et COM signifie que si votre application effectue un aller-retour à une DateTime heure qui spécifie uniquement une heure, votre application doit se rappeler de modifier ou d’ignorer la date erronée de l’objet final DateTime .