How to update the system's date and/or time using .NET

13,968

Solution 1

Part of your problem is that you have a couple of incorrect PInvoke signatures. Most notable SetSystemTime should have a non-void return value. Here is the correct signature

    /// Return Type: BOOL->int
    ///lpSystemTime: SYSTEMTIME*
    [System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint="SetSystemTime")]
    [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
public static extern  bool SetSystemTime([InAttribute()] ref SYSTEMTIME lpSystemTime) ;

My suspicion is that the lock of a return value messed up the stack and the SetSystemTime function essentially ended up with bad data.

Solution 2

According to the code you have right there, you're not incrementing the hour. It looks like you're setting your system time to the exact same time as it was when you called Win32GetSystemTime.

Try:

systime.wHour = (ushort)(sysTime.Hour + 1);

Solution 3


TimeSpan diffLocalTime = DateTime.Now - DateTime.UtcNow; 
SystemTime systemTime = new SystemTime(); 
systemTime.Second = ... 
systemTime.Minute =.... 
systemTime.Hour -= (ushort)(diffLocalTime.Hours + 1); // 00:59:59 I rounded as 1 hour 
bool result = SetSystemTime(ref systemTime); 

This using It's working correctly for local time zone.

Solution 4

No need for P/Invoke - there is a simpler way (but not well known) available from the Microsoft.VisualBasic assembly. If you are in C#, just remember to add a reference to it.

You can use the Microsoft.VisualBasic.DateAndTime class to get and change the Date or Time. The properties Today and TimeOfDay have setters that will make the changes to the date or time.

You still need the relevant privileges - refer to the MSDN documentation link below.

Here's an arbitrary example to change the time:

public static void SetTimeToPast()
{
    Microsoft.VisualBasic.DateAndTime.TimeOfDay = DateTime.Now.AddMinutes( -2 );
}

Reference on MSDN: http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.dateandtime(v=vs.110).aspx

Solution 5

The problem is about UTC time and local time. See this link: http://www.codeproject.com/Messages/2998246/problem-with-SetSystemTime-fucntion-of-Kernel32-dl.aspx

Hope this maybe helpful for you.

Share:
13,968

Related videos on Youtube

user62958
Author by

user62958

Updated on May 18, 2022

Comments

  • user62958
    user62958 almost 2 years

    I am trying to update my system time using the following:

    [StructLayout(LayoutKind.Sequential)] 
    private 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", EntryPoint = "GetSystemTime", SetLastError = true)]
    private extern static void Win32GetSystemTime(ref SYSTEMTIME lpSystemTime);
    
    [DllImport("kernel32.dll", EntryPoint = "SetSystemTime", SetLastError = true)]
    private extern static bool Win32SetSystemTime(ref SYSTEMTIME lpSystemTime);
    
    public void SetTime()
    {
        TimeSystem correctTime = new TimeSystem();
        DateTime sysTime = correctTime.GetSystemTime();
        // Call the native GetSystemTime method
        // with the defined structure.
        SYSTEMTIME systime = new SYSTEMTIME();
        Win32GetSystemTime(ref systime);
    
        // Set the system clock ahead one hour. 
        systime.wYear = (ushort)sysTime.Year;
        systime.wMonth = (ushort)sysTime.Month;
        systime.wDayOfWeek = (ushort)sysTime.DayOfWeek;
        systime.wDay = (ushort)sysTime.Day;
        systime.wHour = (ushort)sysTime.Hour;
        systime.wMinute = (ushort)sysTime.Minute;
        systime.wSecond = (ushort)sysTime.Second;
        systime.wMilliseconds = (ushort)sysTime.Millisecond;
    
        Win32SetSystemTime(ref systime);
    }
    

    When I debug everything looks good and all the values are correct but when it calles the Win32SetSystemTime(ref systime) th actual time of system(display time) doesn't change and stays the same. The strange part is that when I call the Win32GetSystemTime(ref systime) it gives me the new updated time. Can someone give me some help on this?

  • user62958
    user62958 about 15 years
    But I don't want to increment the hour. I want to set it to another time.
  • David Morton
    David Morton about 15 years
    The code comment in your code specifically states "set the system clock ahead one hour". You're not changing your system time simply because you're not changing it. To set it to another time, you have to set the struct you're sending into the method to a different time than the current time.
  • FrenkyB
    FrenkyB about 9 years
    For me, changing system date Microsoft.VisualBasic.DateAndTime.TimeOfDay.Today = [new Date] did the trick. Thanks a lot. This is so far the easiest and cleanest solution.
  • Matt
    Matt almost 9 years
    Using Win32SetSystemTime works for me, but unfortunately this doesn't.