Изменить системную дату программно

Как программно изменить дату и время локальной системы с помощью С#?


person Yoann. B    schedule 16.03.2009    source источник
comment
Забавно, что на некоторые вопросы, подобные этим, просто отвечают, в то время как другие рассылаются спамом с тем, что вы пробовали? ... странный ...   -  person Tim Kathete Stadler    schedule 18.12.2012


Ответы (9)


Вот где я нашел ответ.; Я разместил его здесь, чтобы улучшить ясность.

Определите эту структуру:

[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;
}

Добавьте в свой класс следующий метод extern:

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

Затем вызовите метод с экземпляром вашей структуры следующим образом:

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.
person Andrew Hare    schedule 16.03.2009
comment
написать собственную оболочку C++/CLI и внедрить другую сборку проще, чем написать ~ 9-строчную структуру ?? - person Lucas; 16.03.2009
comment
Только не позволяйте Марку Гравеллу увидеть вашу структуру! ;-) - person si618; 17.03.2009
comment
Мое редактирование ответа было отклонено по какой-то причине, но, по крайней мере, для Win 7 я обнаружил, что мне нужно запустить программу от имени администратора, чтобы это работало. См.: stackoverflow.com/questions/2818179/ - person Dan W; 30.01.2015
comment
Было бы хорошо сказать, что этот метод устанавливает время UTC. Поэтому, если вы возьмете свое местное время по Datetime.Now, оно установит неправильное время. Я столкнулся с этим и долго не мог понять, что не так... - person Denis Koreyba; 08.12.2016
comment
Стоит отметить, что для работы программе требуется разрешение администратора... - person Christopher Smit; 23.04.2018

Множество замечательных точек зрения и подходов уже здесь, но вот некоторые спецификации, которые в настоящее время не учитываются и которые, как мне кажется, могут сбить с толку и запутать некоторых людей.

  1. В ОС Windows Vista, 7, 8 для этого требуется запрос UAC, чтобы получить необходимые административные права для успешного выполнения функции SetSystemTime. Причина в том, что вызывающему процессу требуется привилегия SE_SYSTEMTIME_NAME.
  2. Функция SetSystemTime ожидает структуру SYSTEMTIME в формате всемирного координированного времени (UTC). В противном случае он не будет работать так, как хотелось бы.

В зависимости от того, где/как вы получаете значения DateTime, лучше всего перестраховаться и использовать ToUniversalTime() перед установкой соответствующих значений в структуре SYSTEMTIME.

Пример кода:

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); 
person Derek W    schedule 30.12.2013
comment
Я не могу напрямую изменить системное время, используя это - person Hiren Raiyani; 13.04.2015
comment
Я успешно использовал этот код в нескольких проектах. Вы запускаете исполняемый файл от имени администратора? В противном случае этот код точно не будет работать. - person Derek W; 13.04.2015
comment
вау, это решило мою проблему. Проблема в том, что часовой пояс для вашего местного времени мешает получить правильное время, поэтому строка DateTime dateTime = tempDateTime.ToUniversalTime(); все решил. - person Daren Delima; 13.06.2017

Вы можете использовать вызов команды DOS, но вызов функции в Windows dll — лучший способ сделать это.

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);
}  
person MarmouCorp    schedule 16.03.2009

Используйте эту функцию для изменения системного времени (проверено в окне 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();
        }
    }

Пример: Вызов метода загрузки формы setDate("5-6-92"); setTime("2:4:5");

person Hiren Raiyani    schedule 04.09.2014
comment
Вот проверенная, готовая к компиляции и запуску версия вашего кода github.com /jtara1/MiscScripts/blob/master/MiscScripts/ Для этого мне пришлось пройти как минимум 4 переполнения стека, так как я не знаком с С# или этими библиотеками. - person James T.; 23.12.2017

  1. PInvoke для вызова Win32 API SetSystemTime (пример)
  2. System.Management с классом WMI Win32_OperatingSystem и вызовом SetDateTime для этого класса.

Оба требуют, чтобы вызывающему объекту был предоставлен SeSystemTimePrivilege и чтобы эта привилегия была включена.

person Avram    schedule 16.03.2009

Поскольку я упомянул об этом в комментарии, вот оболочка C++/CLI:

#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);
        }
    };
}

Код клиента C# теперь очень прост:

JDanielSmith.Utilities.SetSystemTime(DateTime.Now);
person Ðаn    schedule 16.03.2009
comment
Я попробовал ваш код, но он не работает. gist.github.com/jtara1/07cfd5ebffab8296564f86000c50510e В любом случае, я нашел решение того, что хотел, и проверил это github.com/jtara1/MiscScripts/blob/ - person James T.; 23.12.2017

Будь осторожен!. Если вы удалите неиспользуемое свойство из структуры, оно установит время неправильно. Я потерял 1 день из-за этого. Я думаю, что порядок структуры важен.

Это правильная структура:

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;

        };

Если вы запустите SetSystemTime(), он будет работать, как и ожидалось. Для теста я установил время, как показано ниже;

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);

Установлено время: 15.10.2019 10:20, все в порядке.

Но я удаляю неиспользуемое свойство DayOfWeek;

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);

Запустить тот же код, но установить время: 10.10.2019 20:30

Пожалуйста, обратите внимание на порядок и все поля структуры SystemTime. Юсуф

person Yusuf GURDAG    schedule 07.05.2019

Класс копирования/вставки для всех, кто ищет его

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);
    }
}
person Will Calderwood    schedule 07.05.2021

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

Это рабочая функция:

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();
    }
}
person Javad_Raouf    schedule 28.12.2014