Nous développons une application C # pour un client de service Web. Cela fonctionnera sur les PC Windows XP.
L'un des champs renvoyés par le service Web est un champ DateTime. Le serveur renvoie un champ au format GMT c'est-à-dire avec un "Z" à la fin.
Cependant, nous avons constaté que .NET semble faire une sorte de conversion implicite et le temps était toujours de 12 heures.
L'exemple de code suivant résout ce problème dans une certaine mesure en ce que la différence de 12 heures a disparu, mais il ne prend pas en compte l'heure d'été NZ.
CultureInfo ci = new CultureInfo("en-NZ");
string date = "Web service date".ToString("R", ci);
DateTime convertedDate = DateTime.Parse(date);
Selon ce site date :
Décalage UTC / GMT
Fuseau horaire standard: UTC / GMT +12 heures
Heure d'été: +1 heure
Décalage horaire actuel: UTC / GMT +13 heures
Comment ajustons-nous pour l'heure supplémentaire? Cela peut-il être fait par programme ou s'agit-il d'une sorte de paramètre sur les PC?
Z
heure se réfère à UTC, pas à GMT. Les deux peuvent différer jusqu'à 0,9 seconde.Réponses:
Pour les chaînes telles que
2012-09-19 01:27:30.000
,DateTime.Parse
ne peut pas dire de quel fuseau horaire proviennent la date et l'heure.DateTime
a une propriété Kind , qui peut avoir l'une des trois options de fuseau horaire:REMARQUE Si vous souhaitez représenter une date / heure autre que UTC ou votre fuseau horaire local, vous devez utiliser
DateTimeOffset
.Donc, pour le code dans votre question:
Vous dites que vous savez de quel type il s'agit, alors dites-le.
Maintenant, une fois que le système connaît son heure UTC, vous pouvez simplement appeler
ToLocalTime
:Cela vous donnera le résultat dont vous avez besoin.
la source
DateTime convertedTime = new DateTime(DateTime.Parse(dateStr).Ticks), DateTimeKind.Utc);
Kind
duDateTime
deUnspecified
àUTC
est inutile.Unspecified
est supposé êtreUTC
aux fins deToLocalTime
: msdn.microsoft.com/en-us/library/…Je chercherais à utiliser la classe System.TimeZoneInfo si vous êtes dans .NET 3.5. Voir http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx . Cela devrait prendre en compte les changements de l'heure d'été correctement.
la source
la source
DateTime
les objets ont leKind
deUnspecified
par défaut, aux fins deToLocalTime
est supposé êtreUTC
.Pour obtenir l'heure locale d'un
Unspecified
DateTime
objet, il vous suffit donc de faire ceci:L'étape de changement du
Kind
duDateTime
deUnspecified
àUTC
est inutile.Unspecified
est supposé êtreUTC
utilisé aux fins suivantesToLocalTime
: http://msdn.microsoft.com/en-us/library/system.datetime.tolocaltime.aspxla source
convertedDate.FromLocalTime();
se convertira enUTC
.Je sais que c'est une question plus ancienne, mais je suis tombé sur une situation similaire, et je voulais partager ce que j'avais trouvé pour les futurs chercheurs, peut-être moi-même :).
DateTime.Parse()
peut être délicat - voir ici par exemple.Si le produit
DateTime
provient d'un service Web ou d'une autre source avec un format connu, vous voudrez peut-être envisager quelque chose commeou, mieux encore,
L'
AssumeUniversal
indicateur indique à l'analyseur que la date / heure est déjà UTC; la combinaison deAssumeUniversal
et luiAdjustToUniversal
dit de ne pas convertir le résultat en heure "locale", ce qu'il essaiera de faire par défaut. (J'essaie personnellement de traiter exclusivement avec UTC dans les couches entreprise / application / service de toute façon. Mais contourner la conversion en heure locale accélère également les choses - de 50% ou plus dans mes tests, voir ci-dessous.)Voici ce que nous faisions auparavant:
Nous avions profilé l'application et constaté que le DateTime.Parse représentait un pourcentage important de l'utilisation du processeur. (Soit dit en passant, le
CultureInfo
constructeur n'était pas un contributeur important à l'utilisation du processeur.)J'ai donc mis en place une application console pour analyser une chaîne de date / heure 10000 fois de différentes manières. Conclusion:
Parse()
10 secParseExact()
(conversion en local) 20-45 msParseExact()
(pas de conversion en local) 10-15 ms... et oui, les résultats pour
Parse()
sont en secondes , tandis que les autres sont en millisecondes .la source
Je voudrais juste ajouter une note générale de prudence.
Si tout ce que vous faites est d'obtenir l'heure actuelle de l'horloge interne de l'ordinateur pour afficher une date / heure sur l'affichage ou un rapport, alors tout va bien. Mais si vous enregistrez les informations de date / heure pour référence ultérieure ou calculez la date / heure, méfiez-vous!
Disons que vous déterminez qu'un bateau de croisière est arrivé à Honolulu le 20 décembre 2007 à 15h00 UTC. Et vous voulez savoir quelle heure locale c'était.
1. Il y a probablement au moins trois «locaux» impliqués. Local peut signifier Honolulu, ou cela peut signifier où se trouve votre ordinateur, ou cela peut signifier l'emplacement où se trouve votre client.
2. Si vous utilisez les fonctions intégrées pour effectuer la conversion, ce sera probablement faux. Cela est dû au fait que l'heure d'été est (probablement) actuellement en vigueur sur votre ordinateur, mais n'était PAS en vigueur en décembre. Mais Windows ne le sait pas ... il ne dispose que d'un seul indicateur pour déterminer si l'heure d'été est actuellement en vigueur. Et si elle est actuellement en vigueur, elle ajoutera volontiers une heure même à une date en décembre.
3.L'heure d'été est mise en œuvre différemment (ou pas du tout) dans les différentes subdivisions politiques. Ne pensez pas que ce n'est pas parce que votre pays change à une date précise que d'autres pays le feront aussi.
la source
la source
N'oubliez pas que si vous avez déjà un objet DateTime et que vous n'êtes pas sûr qu'il soit UTC ou Local, il est assez facile d'utiliser directement les méthodes sur l'objet:
Sauf indication contraire, .net utilisera les paramètres du PC local. Je voudrais lire: http://msdn.microsoft.com/en-us/library/system.globalization.daylighttime.aspx
Par l'apparence, le code pourrait ressembler à quelque chose comme:
Et comme mentionné ci-dessus, vérifiez à nouveau le réglage du fuseau horaire sur votre serveur. Il existe des articles sur le net pour savoir comment affecter en toute sécurité les modifications apportées à IIS.
la source
En réponse à la suggestion de Dana:
L'exemple de code ressemble maintenant à:
La date d'origine était le 20/08/08; le genre était UTC.
"ConvertDate" et "dt" sont les mêmes:
21/08/08 10:00:26; le genre était local
la source
J'ai eu le problème avec le fait qu'il soit dans un ensemble de données poussé à travers le fil (service Web vers le client) qu'il changerait automatiquement parce que le champ DateType du DataColumn était défini sur local. Assurez-vous de vérifier quel est le DateType si vous transmettez DataSets.
Si vous ne souhaitez pas qu'il change, définissez-le sur Non spécifié
la source
Je suis tombé sur cette question car j'avais un problème avec les dates UTC que vous récupérez via l'API Twitter (champ created_at sur un statut); Je dois les convertir en DateTime. Aucun des réponses / exemples de code dans les réponses sur cette page n'était suffisant pour m'empêcher d'obtenir une erreur "La chaîne n'a pas été reconnue comme une DateTime valide" (mais c'est le plus proche que j'ai pu trouver la bonne réponse sur SO)
Publier ce lien ici au cas où cela aiderait quelqu'un d'autre - la réponse dont j'avais besoin a été trouvée sur ce blog: http://www.wduffy.co.uk/blog/parsing-dates-when-aspnets-datetimeparse-doesnt-work/ - utilisez essentiellement DateTime.ParseExact avec une chaîne de format au lieu de DateTime.Parse
la source