2017-03-22 9 views
3

J'ai un appel à SetSystemTime depuis mon application C#. Toutefois, si le fuseau horaire de Windows est décalé par rapport à l'heure UTC, il semble parfois ajuster l'horloge du système comme si l'heure fournie était UTC (c'est-à-dire convertie en heure locale) et d'autres fois non. règle l'heure directement sur le paramètre date.SetSystemTime - UTC ou heure locale?

[StructLayout(LayoutKind.Sequential)] 
    internal struct SystemTime 
    { 
     public short Year; 
     public short Month; 
     public short DayOfWeek; 
     public short Day; 
     public short Hour; 
     public short Minute; 
     public short Second; 
     public short Milliseconds; 
    } 

    [DllImport("kernel32.dll", SetLastError = true)] 
    internal static extern bool SetSystemTime(ref SystemTime st); 

    public static bool AdjustSystemClock(DateTime date) 
    { 
     SystemTime systemTime = new SystemTime(); 
     systemTime.Year = (short)date.Year; 
     systemTime.Month = (short)date.Month; 
     systemTime.Day = (short)date.Day; 
     systemTime.Hour = (short)date.Hour; 
     systemTime.Minute = (short)date.Minute; 
     systemTime.Second = (short)date.Second; 
     return SetSystemTime(ref systemTime); 
    } 

La différence semble être: Quand je mets le fuseau horaire à l'aide de Windows, puis démarrez l'application, quand je l'appelle SetSystemTime() il ajuste le temps prévu comme si elle était UTC.

Mais lorsque je définis le fuseau horaire à l'aide de la fonction SetDynamicTimeZoneInformation(), redémarrez l'application, puis appelez le SetSystemTime(), puis réglez l'heure directement sur l'heure fournie, quel que soit le fuseau horaire.

Est-ce le comportement attendu? Comment puis-je obtenir la cohérence entre les deux méthodes pour définir le fuseau horaire?

+0

SetSystemTime() presque jamais "définit l'heure directement à l'heure que je fournis". Il définit l'heure UTC. Sauf lorsque vous habitez en Irlande, situé dans le fuseau horaire UTC + 0. Pas vraiment une bénédiction. Appeler aléatoirement SetDynamicTimeZoneInformation() n'est généralement pas judicieux, sauf si l'ordinateur est situé dans un avion :) Rendre un programme .NET conscient des changements de fuseau horaire nécessite de le redémarrer (comme vous l'avez fait) ou d'appeler CultureInfo.ClearCachedData + TimeZoneInfo.ClearCachedData. Ne fais pas ça. –

+0

Les ordinateurs Windows synchronisent automatiquement leur heure. Ne serait-il pas plus sûr d'utiliser la fonctionnalité intégrée? Vous pouvez modifier la fréquence de synchronisation ou forcer une synchronisation [via les paramètres et l'outil Win32tm] (https://technet.microsoft.com/fr-fr/windows-server-docs/identity/ad-ds/get-started/windows -time-service/windows-time-service-tools-and-settings) –

Répondre

1

Je crois que j'ai trouvé le problème.

Il s'avère que la personne qui a écrit le bit de code à SetDynamicTimeZoneInformation() a négligé de définir la propriété Bias. Par conséquent, les informations de fuseau horaire étant définies avec un décalage UTC de zéro, donc aucun ajustement n'aurait lieu.

+0

Au lieu de régler vous-même l'heure, pourquoi ne pas laisser le système d'exploitation le faire automatiquement? Les ordinateurs de domaine se synchronisent automatiquement avec le contrôleur de domaine. Les ordinateurs autonomes (ou DC) se synchronisent automatiquement avec les serveurs de temps spécifiés dans les paramètres de date et heure –

+0

@PanagiotisKanavos - Je n'étais pas le développeur d'origine de l'application, mais ils avaient apparemment de bonnes raisons de le faire de cette façon. D'une part, il s'agit d'un périphérique spécialisé (Windows Embedded 7) qui ne fournit pas d'accès utilisateur au système d'exploitation Windows principal. (Une application shell charge cette application lorsqu'elle allume l'appareil puis éteint l'appareil à la fermeture de l'application) – colmde

+0

La synchronisation horaire est également disponible sur Windows Embedded. Cochez cette question SO: [Paramétrer le serveur de temps Internet sur Windows Embedded standard par lot ou similaire] (http://stackoverflow.com/questions/34016933/setting-internet-time-server-on-windows-embedded-standard-through- lot-ou-simil). Sans les horloges synchronisées, vous ne pouvez pas utiliser SSL ou toute autre forme de chiffrement qui vérifie les paquets expirés. Cela inclut la communication avec les contrôleurs de domaine. –