12
votes

C #: Assurez-vous que DateTime.Now retourne un GMT + 1 fois

J'utilise datetime.now pour afficher quelque chose en fonction de la date d'aujourd'hui, et lorsque vous travaillez localement (Malte, Europe), les temps apparaissent correctement (évidemment à cause du fuseau horaire), mais bien sûr lorsque je télécharge à mon serveur d'hébergement (USA), datetime.now ne représente pas le bon fuseau horaire.

Par conséquent, dans mon code, Comment puis-je convertir datetime.now pour renvoyer correctement l'heure à partir d'une fusible GMT + 1 Timezone ?


0 commentaires

3 Réponses :


5
votes

Je ne pense pas que vous puissiez définir une propriété dans votre code qui rendra DateTime.Nouvrez rien d'autre que l'heure actuelle de l'ordinateur dans lequel le code s'exécute. Si vous voulez avoir un moyen de toujours obtenir un autre moment, vous aurez probablement besoin d'envelopper une autre fonction. Vous pouvez faire le voyage aller-retour sur UTC et ajouter le décalage souhaité: xxx

(code de code mis à jour après le commentaire de Luke sur les travaux internes de DateTime.now)


5 commentaires

Utilisation de DateTime.utcnow.addhours (1) au lieu de vous sauver une frappe!


Oui, je me suis rendu compte que. Mais alors je ne suis pas sûr qu'ils font exactement la même chose; Utcnow récupère l'heure du système et certaines opérations avec des "nombres magiques", tandis que Touniversaltime utilise le fuseau horaire.CurrentTimezone pour obtenir l'heure UTC. Je suppose qu'ils reviendront toujours au même moment; o)


DateTime.now Utilise utcnow Dans les coulisses, votre code d'origine se traduit par quelque chose comme denttime.utcnow.tolocaltime (). Touniversaltime (). Addhours (1) .


Tellement vrai; n'a pas pensé à ça. Merci de le pointer. Mettra à jour la réponse. Je n'ai pas peur de taper, mais quand le code est inefficace comme celui-ci, c'est une question différente.


(Au fait, je pense que le premier numéro magique utilisé dans utcnow est de convertir de filétime - ticks depuis 01/01/1601 - à DateTime - Ticks depuis 01/01/0001. Le deuxième numéro magique est un masque utilisé à l'intérieur pour signifier denttimekind.utc .)



17
votes

Utilisez la classe TimeZoneInfo trouvée dans System.core;

Vous devez définir le DateTimeKind sur DateTimekind.utc pour cela. P>

DateTime MyTime = new DateTime(1990, 12, 02, 19, 31, 30, DateTimeKind.Utc);

DateTime MyTimeInWesternEurope = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(MyTime, "W. Europe Standard Time");


0 commentaires

15
votes

Cela dépend de ce que vous entendez par "une fuseau horaire GMT + 1". Voulez-vous dire de manière permanente UTC + 1, ou voulez-vous dire UTC + 1 ou UTC + 2 selon DST?

Si vous utilisez .NET 3.5, utilisez TimezoneInfo code> Pour obtenir un fuseau horaire approprié, puis utilisez: P>

// Be very careful when building this list, and make sure they're UTC times!
private static readonly IEnumerable<DateTime> DstChanges = ...;

static DateTime ConvertToLocalTime(DateTime utc)
{
    int hours = 1; // Or 2, depending on the first entry in your list
    foreach (DateTime dstChange in DstChanges)
    {
        if (utc < dstChange)
        {
            return DateTime.SpecifyKind(utc.AddHours(hours), DateTimeKind.Local);
        }
        hours = 3 - hours; // Alternate between 1 and 2
    }
    throw new ArgumentOutOfRangeException("I don't have enough DST data!");
}


9 commentaires

Jon, j'ai édité votre réponse pour inverser les paramètres de TimezoneInfo.ConvertiTimefromutc


Whoops, merci. La chose bizarre est que je les ai réellement vérifiées d'abord - puis de les avoir le mauvais chemin autour de toute façon!


Votre solution lance cette exception dans la méthode ConvertiTimeFromutc: la conversion n'a pas pu être complétée car la dateTime fournie n'avait pas le type de propriété en nature correctement. Par exemple, lorsque la propriété en nature est DateTimeKind.Local, le fuseau horaire source doit être TimeZoneInfo.Local. Nom du paramètre: Sourcetimezone


Êtes-vous sûr que vous le passez à DateTime.utcnow plutôt que DateTime.Now?


Oui, j'utilise votre extrait de code exact (changez évidemment l'ID à "W. Europe Standard Time")


Et êtes-vous sûr que vous appelez ConvertTimeFromutc plutôt que ConvertiMetoutC? Cela est plus susceptible d'être le problème, étant donné l'exception exacte que vous spécifiez ...


Je viens d'essayer cet extrait, et ça marche bien sur ma machine.


(Alors que la modification de ConvertMetoutc donne le message d'exception exacte que vous avez donné ici.)


Excusez ma bêtise, mais vous avez raison. J'utilisais ConvertiMetoutC au lieu de ConvertTimefromutc.