58

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

Paul Roub
  • 35,100
  • 27
  • 72
  • 83
Yoann. B
  • 10,667
  • 18
  • 65
  • 110

9 Answers9

87

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.
Ðаn
  • 10,400
  • 11
  • 57
  • 90
Andrew Hare
  • 320,708
  • 66
  • 621
  • 623
  • 4
    writing a custom C++/CLI wrapper and introcuding another assembly is easier than writing an ~9-line struct?? – Lucas Mar 16 '09 at 17:50
  • Just don't let Marc Gravell see your struct! ;-) – si618 Mar 16 '09 at 22:33
  • 1
    My edit to the answer was rejected for some reason, but at least for Win 7, I found I needed to run the program as administrator for this to work. See: http://stackoverflow.com/questions/2818179/how-to-force-my-net-app-to-run-as-administrator-on-windows-7 – Dan W Jan 30 '15 at 13:39
  • 6
    It would be good to say that this method sets UTC time. So if you take your local time by Datetime.Now then it will set a wrong time. I encountered this and couldn't understand what is wrong for a long time... – Denis Koreyba Dec 08 '16 at 14:19
  • 3
    It's worth mentioning that the program needs administrator permission for this to work... – Christopher Smit Apr 23 '18 at 17:02
18

A lot of great viewpoints and approaches are already here, but here are some specifications that are currently left out and that I feel might trip up and confuse some people.

  1. On Windows Vista, 7, 8 OS this will require a UAC Prompt in order to obtain the necessary administrative rights to successfully execute the SetSystemTime function. The reason is that calling process needs the SE_SYSTEMTIME_NAME privilege.
  2. The SetSystemTime function is expecting a SYSTEMTIME struct in coordinated universal time (UTC). It will not work as desired otherwise.

Depending on where/ how you are getting your DateTime values, it might be best to play it safe and use ToUniversalTime() before setting the corresponding values in the SYSTEMTIME struct.

Code example:

DateTime tempDateTime = GetDateTimeFromSomeService();
DateTime dateTime = tempDateTime.ToUniversalTime();

SYSTEMTIME st = new SYSTEMTIME();
// All of these must be short
st.wYear = (short)dateTime.Year;
st.wMonth = (short)dateTime.Month;
st.wDay = (short)dateTime.Day;
st.wHour = (short)dateTime.Hour;
st.wMinute = (short)dateTime.Minute;
st.wSecond = (short)dateTime.Second;

// invoke the SetSystemTime method now
SetSystemTime(ref st); 
Derek W
  • 9,010
  • 5
  • 50
  • 65
  • I cant directly change system time using this – Hiren Raiyani Apr 13 '15 at 12:54
  • 1
    I have used this code on multiple projects successfully. Are you running the executable as administrator? Otherwise this code will certainly not work. – Derek W Apr 13 '15 at 13:46
  • 2
    wow this one solved my problem. The issue is that the timezone for your local time is getting in the way to get the correct time so the line "DateTime dateTime = tempDateTime.ToUniversalTime();" solved it all. – Daren Delima Jun 13 '17 at 11:23
15

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);
}  
MarmouCorp
  • 1,423
  • 10
  • 9
7

Use this function to change the time of system (tested in window 8)

 void setDate(string dateInYourSystemFormat)
    {
        var proc = new System.Diagnostics.ProcessStartInfo();
        proc.UseShellExecute = true;
        proc.WorkingDirectory = @"C:\Windows\System32";
        proc.CreateNoWindow = true;
        proc.FileName = @"C:\Windows\System32\cmd.exe";
        proc.Verb = "runas";
        proc.Arguments = "/C date " + dateInYourSystemFormat;
        try
        {
            System.Diagnostics.Process.Start(proc);
        }
        catch
        {
            MessageBox.Show("Error to change time of your system");
            Application.ExitThread();
        }
    }
void setTime(string timeInYourSystemFormat)
    {
        var proc = new System.Diagnostics.ProcessStartInfo();
        proc.UseShellExecute = true;
        proc.WorkingDirectory = @"C:\Windows\System32";
        proc.CreateNoWindow = true;
        proc.FileName = @"C:\Windows\System32\cmd.exe";
        proc.Verb = "runas";
        proc.Arguments = "/C time " + timeInYourSystemFormat;
        try
        {
            System.Diagnostics.Process.Start(proc);
        }
        catch
        {
            MessageBox.Show("Error to change time of your system");
            Application.ExitThread();
        }
    }

Example: Call in load method of form setDate("5-6-92"); setTime("2:4:5 AM");

Jørgen R
  • 9,179
  • 7
  • 36
  • 56
Hiren Raiyani
  • 708
  • 1
  • 12
  • 25
  • Here's a tested, ready to compile and run version of your code https://github.com/jtara1/MiscScripts/blob/master/MiscScripts/UpdateOSTime.cs I had to go through at least 4 stackoverflows for this as I'm not familiar with c# or these libs. – James T. Dec 23 '17 at 06:02
7
  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.

Avram
  • 4,191
  • 29
  • 40
3

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);
Ðаn
  • 10,400
  • 11
  • 57
  • 90
  • I tried out your code, but it doesn't seem to work. https://gist.github.com/jtara1/07cfd5ebffab8296564f86000c50510e Anyways, I found a solution to what I wanted and tested it out https://github.com/jtara1/MiscScripts/blob/00a5d330d784d7e423c0f8a83172ddfc31aad3fa/MiscScripts/UpdateOSTime.cs – James T. Dec 23 '17 at 05:59
1

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

0

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);
    }
}
Will Calderwood
  • 3,878
  • 2
  • 31
  • 55
-4

proc.Arguments = "/C Date:" + dateInYourSystemFormat;

This Is Work Function:

void setDate(string dateInYourSystemFormat)
{
    var proc = new System.Diagnostics.ProcessStartInfo();
    proc.UseShellExecute = true;
    proc.WorkingDirectory = @"C:\Windows\System32";
    proc.CreateNoWindow = true;
    proc.FileName = @"C:\Windows\System32\cmd.exe";
    proc.Verb = "runas";
    proc.Arguments = "/C Date:" + dateInYourSystemFormat;
    try
    {
        System.Diagnostics.Process.Start(proc);
    }
    catch
    {
        MessageBox.Show("Error to change time of your system");
        Application.ExitThread();
    }
}