web-dev-qa-db-fra.com

Comment utiliser TimeZoneInfo pour obtenir l'heure locale pendant l'heure d'été?

J'essaie d'utiliser DateTimeOffset pour transmettre un moment précis dans n'importe quel fuseau horaire. Je ne sais pas comment utiliser TimeZoneInfo pour gérer l'heure d'été.

var dt = DateTime.UtcNow;
Console.WriteLine(dt.ToLocalTime());

var tz = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
var utcOffset = new DateTimeOffset(dt, TimeSpan.Zero);
Console.WriteLine(utcOffset.ToOffset(tz.BaseUtcOffset));

Cela imprime:

6/2/2010 4:37:19 PM
6/2/2010 3:37:19 PM -06:00

Je suis dans le fuseau horaire central et nous sommes actuellement en heure d'été. J'essaie de lire la deuxième ligne:

6/2/2010 4:37:19 PM -05:00

BaseUtcOffset ne change apparemment pas en fonction de l'heure d'été.

Comment puis-je obtenir le bon moment avec la valeur de décalage appropriée?

78
jaminto

Vous devez obtenir l'UtcOffset du TimeZoneInfo, puis le transmettre à la méthode ToOffset ():

var dt = DateTime.UtcNow;
Console.WriteLine(dt.ToLocalTime());

var tz = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
var utcOffset = new DateTimeOffset(dt, TimeSpan.Zero);
Console.WriteLine(utcOffset.ToOffset(tz.GetUtcOffset(utcOffset)));
56

Vous pouvez également utiliser TimeZoneInfo.ConvertTimeFromUtc, qui autorisera l'heure d'été:

DateTime utc = DateTime.UtcNow;
TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
DateTime localDateTime = TimeZoneInfo.ConvertTimeFromUtc(utc, zone);
49
Karl Gjertsen

Ou mieux, si vous ne voulez pas coder en dur le identifiant de fuseau horaire:

TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(TimeZoneInfo.Local.Id);
DateTime localDateTime = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, tzi);
7
Pabinator

Je suis débutant à la fois sur .NET et stackoverflow, donc je peux me tromper, mais voici:

L'utilisation de TimeZoneInfo.ConvertTimeFromUtc permettra de passer à l'heure d'été et de la convertir à l'heure correcte en fonction du fuseau horaire + d'un éventuel décalage d'heure d'été. Cependant - le décalage lui-même dans l'objet résultant affichera le décalage pour l'heure standard, et ne tiendra pas compte de l'heure d'été. Donc, si vous voulez faire une ToString sur l'objet, vous vous retrouverez avec l'heure correcte (en heures et minutes), mais le mauvais décalage pendant l'heure d'été, ce qui peut conduire au mauvais moment dans le code plus tard.

Si vous utilisez à la place GetUtcOffset pour obtenir le décalage pour une heure spécifique, puis effectuez un ToOffset sur l'objet DateTimeOffset, les heures/minutes et le décalage lui-même seront correctement convertis, et vous pouvez effectuer une ToString en toute sécurité.

string ExpectedDateTimePattern = "yyyy'-'MM'-'dd'T'HH':'mm':'ss''zzz";
string timeZoneId = "FLE Standard Time";
string dateTimestr = "2017-10-09T09:00:00+02:00";

DateTimeOffset dto = DateTimeOffset.Parse(dateTimeStr);
TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
TimeSpan offset = zone.GetUtcOffset(dto);
dto = dto.ToOffset(offset);
string localTime = dto.ToString(ExpectedDateTimePattern);

localTime renverra "2017-10-09T10: 00: 00 + 03: 00".

datetimeoffsettimezoneinfogetutcoffset

4
Niels Pein