1

I already have this code that I got from: Change system date programmatically

I have a button that when I click the system time must be updated. But what is happening is that I don't get the result I want.

As you can see in the code below I set the Date and Time to April 25, 2018 1:00:00 AM but what I get is April 25, 2018 9:00:00 AM because of the added time by the UTC which is +8 in my time zone.

How can I set the system time directly to 1:00:00AM?

[StructLayout(LayoutKind.Sequential)]
public struct SYSTEMTIME
{
    public ushort wYear;
    public ushort wMonth;
    public ushort wDayOfWeek;
    public ushort wDay;
    public ushort wHour;
    public ushort wMinute;
    public ushort wSecond;
    public ushort wMilliseconds;
}

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

private void UpdateSystemTime(DateTime dt)
{
    SYSTEMTIME st = new SYSTEMTIME();
    st.wYear = (ushort)dt.Year;
    st.wMonth = (ushort)dt.Month;
    st.wDay = (ushort)dt.Day;
    st.wHour = (ushort)dt.Hour;
    st.wMinute = (ushort)dt.Minute;
    st.wSecond = (ushort)dt.Second;

    SetSystemTime(ref st); // invoke this method.
}

private void Button1_Click(object sender, RoutedEventArgs e)
{
    timeToSet = new DateTime(year, month, day, hour, minute, second, second, DateTimeKind.Utc);
    UpdateSystemTime(timeToSet);
}
Balagurunathan Marimuthu
  • 2,927
  • 4
  • 31
  • 44
Arch
  • 25
  • 8
  • Why are you trying to set the system time programatically at all? All modern Windows OS have the ability to set time automatically. Unless that setting is disabled (which it shouldn't be), then any adjustment you make through the code here will eventually be overwritten when the clock syncs again. – Matt Johnson-Pint Apr 24 '18 at 16:28
  • The app that I am developing will be the only that will run on the OS and most of the features will be disabled including win explorer so the only way the user can modify time is by the App. I will be using Windows 10 as its base OS. Btw do you have any advice on how will I safely enable/disable windows auto time sync? – Arch Apr 25 '18 at 02:05
  • It's the first setting in the settings page, but unless you are completely disconnected from all networks, I strongly suggest you leave it on and set time automatically. Very many things fail without accurate time. For example, SSL certificates have expiration dates, and Kerberos authentication has only a 5 minute tolerance. Many other things... – Matt Johnson-Pint Apr 25 '18 at 02:08
  • I'm sorry I didn't clarify on how I will disable/enable the auto sync. Since most of the UI for Windows 10 will be disabled, I would like to do all of this process through code. Because in the Time setting of my app there will be an option to Auto update time or not. Its my first time accessing system's date/time through code so please advise me on how will I do it properly. – Arch Apr 25 '18 at 02:25
  • You would need to disable the Windows Time Service, which other answers here on StackOverflow will show you if you search. Again, I recommend against such things. – Matt Johnson-Pint Apr 25 '18 at 03:48

1 Answers1

4

See the documentation of SetSystemTime:

Sets the current system time and date. The system time is expressed in Coordinated Universal Time (UTC).

This means that you'll have to pass the UTC, not the local time (or the time passed is interpreted as UTC).

When you created the DateTime object, you passed DateTimeKind.Utc, but this does not mean, that the values you pass are converted from local to UTC time, but rather the DateTime object is created as a UTC time object. When you pass 1 AM as the hour, when you call dt.Hour you will still get 1 AM, which is passed to SetSystemTime and interpreted as 1 AM UTC, not 1 AM in local time.

How to overcome this?

You'll have to create a DateTime for your local time, convert it to UTC and then pass the values to SetSystemTime

timeToSet = new DateTime(year, month, day, hour, minute, second, second, DateTimeKind.Local);
UpdateSystemTime(timeToSet.ToUniversalTime()); // this converts the local DateTime object to UTC
Paul Kertscher
  • 9,416
  • 5
  • 32
  • 57
  • It works fine now. Thanks! But in case I changed my time zone now. Will there be any problem that I may encounter when I used this code? – Arch Apr 24 '18 at 07:28
  • `DateTimeKind.Local` will always refer to the local time according to your system settings, hence the conversion to UTC should be correct in any case. – Paul Kertscher Apr 24 '18 at 07:35
  • Keep in mind that if the timezone in the system settings is "wrong" the time will be set to a "wrong" value, but there is nothing you can do about it (the system is effectively "lying" to the program). – Alex Apr 24 '18 at 07:44