How can I change the local system's date & time programmatically with C#?
How can I change the local system's date & time programmatically with C#?
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);
}
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