Change system date programmatically

Viewed 95715

How can I change the local system's date & time programmatically with C#?

9 Answers

Here is where I found the answer.; I have reposted it here to improve clarity.

Define this structure:

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

Add the following extern method to your class:

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

Then call the method with an instance of your struct like this:

SYSTEMTIME st = new SYSTEMTIME();
st.wYear = 2009; // must be short
st.wMonth = 1;
st.wDay = 1;
st.wHour = 0;
st.wMinute = 0;
st.wSecond = 0;

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

You can use a call to a DOS command but the invoke of the function in the windows dll is a better way to do it.

public struct SystemTime
{
    public ushort Year;
    public ushort Month;
    public ushort DayOfWeek;
    public ushort Day;
    public ushort Hour;
    public ushort Minute;
    public ushort Second;
    public ushort Millisecond;
};

[DllImport("kernel32.dll", EntryPoint = "GetSystemTime", SetLastError = true)]
public extern static void Win32GetSystemTime(ref SystemTime sysTime);

[DllImport("kernel32.dll", EntryPoint = "SetSystemTime", SetLastError = true)]
public extern static bool Win32SetSystemTime(ref SystemTime sysTime);

private void button1_Click(object sender, EventArgs e)
{
    // Set system date and time
    SystemTime updatedTime = new SystemTime();
    updatedTime.Year = (ushort)2009;
    updatedTime.Month = (ushort)3;
    updatedTime.Day = (ushort)16;
    updatedTime.Hour = (ushort)10;
    updatedTime.Minute = (ushort)0;
    updatedTime.Second = (ushort)0;
    // Call the unmanaged function that sets the new date and time instantly
    Win32SetSystemTime(ref updatedTime);
}  
  1. PInvoke to call Win32 API SetSystemTime,(example)
  2. System.Management classes with WMI class Win32_OperatingSystem and call SetDateTime on that class.

Both require that the caller has been granted SeSystemTimePrivilege and that this privilege is enabled.

Since I mentioned it in a comment, here's a C++/CLI wrapper:

#include <windows.h>
namespace JDanielSmith
{
    public ref class Utilities abstract sealed /* abstract sealed = static */
    {
    public:
        CA_SUPPRESS_MESSAGE("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")
        static void SetSystemTime(System::DateTime dateTime) {
            LARGE_INTEGER largeInteger;
            largeInteger.QuadPart = dateTime.ToFileTimeUtc(); // "If your compiler has built-in support for 64-bit integers, use the QuadPart member to store the 64-bit integer."


            FILETIME fileTime; // "...copy the LowPart and HighPart members [of LARGE_INTEGER] into the FILETIME structure."
            fileTime.dwHighDateTime = largeInteger.HighPart;
            fileTime.dwLowDateTime = largeInteger.LowPart;


            SYSTEMTIME systemTime;
            if (FileTimeToSystemTime(&fileTime, &systemTime))
            {
                if (::SetSystemTime(&systemTime))
                    return;
            }


            HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
            throw System::Runtime::InteropServices::Marshal::GetExceptionForHR(hr);
        }
    };
}

The C# client code is now very simple:

JDanielSmith.Utilities.SetSystemTime(DateTime.Now);

A copy/paste class for anyone else who's looking for one

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;

public static class SystemDateTime
{
    [DllImport("kernel32.dll", EntryPoint = "SetSystemTime", SetLastError = true)]
    private static extern bool Win32SetSystemTime(ref SystemTime sysTime);

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

    public static void SetSystemDateTime(int year, int month, int day, int hour,
        int minute, int second, int millisecond)
    {
        SystemTime updatedTime = new SystemTime
        {
            Year = (ushort) year,
            Month = (ushort) month,
            Day = (ushort) day,
            Hour = (ushort) hour,
            Minute = (ushort) minute,
            Second = (ushort) second,
            Millisecond = (ushort) millisecond
        };

        // If this returns false, then the problem is most likely that you don't have the 
        // admin privileges required to set the system clock
        if (!Win32SetSystemTime(ref updatedTime))
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }
    }

    public static void SetSystemDateTime(DateTime dateTime)
    {
        SetSystemDateTime(dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute,
            dateTime.Second, dateTime.Millisecond);
    }
}

Be Careful!. If you delete unused property from the structure, it sets the time wrong. I ve lost 1 day because of this. I think order of the structure is important.

This is correct structure:

public struct SystemTime
        {
            public ushort Year;
            public ushort Month;
            public ushort DayOfWeek;
            public ushort Day;
            public ushort Hour;
            public ushort Minute;
            public ushort Second;
            public ushort Millisecond;

        };

If you run the SetSystemTime(), it works as expected. For test I set the time as below;

SystemTime st = new SystemTime();
st.Year = 2019;
st.Month = 10;
st.Day = 15;
st.Hour = 10;
st.Minute = 20;
st.Second = 30;

SetSystemTime(ref st);

The time set: 15.10.2019 10:20, its ok.

But I delete DayOfWeek property which not used ;

public struct SystemTime
            {
                public ushort Year;
                public ushort Month;
                public ushort Day;
                public ushort Hour;
                public ushort Minute;
                public ushort Second;
                public ushort Millisecond;

            };

SystemTime st = new SystemTime();
    st.Year = 2019;
    st.Month = 10;
    st.Day = 15;
    st.Hour = 10;
    st.Minute = 20;
    st.Second = 30;

    SetSystemTime(ref st);

Run same code but the time set to: 10.10.2019 20:30

Please be careful order and all fields of SystemTime structure. Yusuf

Related