How can I change the local system's date & time programmatically with C#?
问题:
回答1:
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.
回答2:
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); }
回答3:
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.
- 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. - The
SetSystemTime
function is expecting aSYSTEMTIME
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);
回答4:
- PInvoke to call Win32 API SetSystemTime,(example)
- 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.
回答5:
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");
回答6:
Since I mentioned it in a comment, here's a C++/CLI wrapper:
#include 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);
回答7:
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(); } }