web-dev-qa-db-fra.com

Convertir UTC DateTime dans un autre fuseau horaire

J'ai une valeur UTC DateTime provenant d'un enregistrement de base de données. J'ai également un fuseau horaire spécifié par l'utilisateur (une instance de TimeZoneInfo). Comment convertir cet UTC DateTime dans le fuseau horaire local de l'utilisateur? De plus, comment puis-je déterminer si le fuseau horaire spécifié par l'utilisateur observe actuellement l'heure d'été? J'utilise .NET 3.5.

Merci, Mark

33
Mark Richman

Jetez un œil à la structure DateTimeOffset :

// user-specified time zone
TimeZoneInfo southPole =
    TimeZoneInfo.FindSystemTimeZoneById("Antarctica/South Pole Standard Time");

// an UTC DateTime
DateTime utcTime = new DateTime(2007, 07, 12, 06, 32, 00, DateTimeKind.Utc);

// DateTime with offset
DateTimeOffset dateAndOffset =
    new DateTimeOffset(utcTime, southPole.GetUtcOffset(utcTime));

Console.WriteLine(dateAndOffset);

Pour l'heure d'été, voir la méthode TimeZoneInfo.IsDaylightSavingTime .

bool isDst = southpole.IsDaylightSavingTime(DateTime.UtcNow);
17
dtb

La meilleure façon de le faire est simplement d'utiliser TimeZoneInfo.ConvertTimeFromUtc .

// you said you had these already
DateTime utc = new DateTime(2014, 6, 4, 12, 34, 0);
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");

// it's a simple one-liner
DateTime pacific = TimeZoneInfo.ConvertTimeFromUtc(utc, tzi);

Le seul hic est que la valeur DateTime entrante peut ne pas avoir le DateTimeKind.Local gentil. Il doit s'agir de Utc ou Unspecified.

34

Vous pouvez utiliser une fonction dédiée dans TimeZoneInfo si vous souhaitez convertir un DateTimeOffset en un autre DateTimeOffset:

DateTimeOffset newTime = TimeZoneInfo.ConvertTime(
    DateTimeOffset.UtcNow, 
    TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time")
);
20
Erwin Mayer

La réponse Antartica ne fonctionne que pour les fuseaux horaires correspondant à UTC. Je suis assez traumatisé par cette fonction DateTimeOffset et après des heures d'essais et d'erreurs, j'ai réussi à produire une fonction d'extension de conversion pratique qui fonctionne avec tous les fuseaux horaires.

static public class DateTimeFunctions
{
    static public DateTimeOffset ConvertUtcTimeToTimeZone(this DateTime dateTime, string toTimeZoneDesc)
    {
        if (dateTime.Kind != DateTimeKind.Utc) throw new Exception("dateTime needs to have Kind property set to Utc");
        var toUtcOffset = TimeZoneInfo.FindSystemTimeZoneById(toTimeZoneDesc).GetUtcOffset(dateTime);
        var convertedTime = DateTime.SpecifyKind(dateTime.Add(toUtcOffset), DateTimeKind.Unspecified);
        return new DateTimeOffset(convertedTime, toUtcOffset);
    }
}

Exemple:

var currentTimeInPacificTime = DateTime.UtcNow.ConvertUtcTimeToTimeZone("Pacific Standard Time");
12
Sean
       //  TO get Currrent Time in current Time Zone of your System

        var dt = DateTime.Now;

        Console.WriteLine(dt);

        // Display Time Zone of your System

        Console.WriteLine(TimeZoneInfo.Local);

        // Convert Current Date Time to UTC Date Time

        var utc = TimeZoneInfo.ConvertTimeToUtc(dt, TimeZoneInfo.Local);

        Console.WriteLine(utc);

        // Convert UTC Time to Current Time Zone

        DateTime pacific = TimeZoneInfo.ConvertTimeFromUtc(utc, TimeZoneInfo.Local);

        Console.WriteLine(pacific);

        Console.ReadLine();
0
Srinivas