Мои времена, они меняются, то есть потому, что они мне нужны. Я тестирую некоторые случаи использования планировщика, который я использую, и это включает в себя поведение вокруг переходов в летнее время.
Код
Из этого сообщения У меня есть рабочий метод, который позволяет мне программно изменить системную дату (перепрошивая большую часть кода):
[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;
}
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetSystemTime(ref SYSTEMTIME st);
и для моего удобства я просто обертываю, что в этой функции, которую я действительно вызываю:
public static void SetSytemDateTime(DateTime timeToSet)
{
DateTime uniTime = timeToSet.ToUniversalTime();
SYSTEMTIME setTime = new SYSTEMTIME()
{
wYear = (short)uniTime.Year,
wMonth = (short)uniTime.Month,
wDay = (short)uniTime.Day,
wHour = (short)uniTime.Hour,
wMinute = (short)uniTime.Minute,
wSecond = (short)uniTime.Second,
wMilliseconds = (short)uniTime.Millisecond
};
SetSystemTime(ref setTime);
}
Необходимо дополнительное преобразование в универсальное время, иначе я не увижу дату, которую я передал методу в своих часах (вниз на панели задач).
Теперь это отлично работает с учетом этого кода, например:
DateTime timeToSet = new DateTime(2014, 3, 10, 1, 59, 59, 0);
Console.WriteLine("Attemting to set time to {0}", timeToSet);
SetSytemDateTime(timeToSet);
Console.WriteLine("Now time is {0}, which is {1} (UTC)", DateTime.Now, DateTime.UtcNow);
Thread.Sleep(TimeSpan.FromSeconds(5));
DateTime actualSystemTime = GetNetworkTime();
SetSytemDateTime(actualSystemTime);
Метод GetNetworkTime
на самом деле просто захвачен из здесь, поэтому я могу вернуть часы в "реальное" время после тестирования, вы можете его игнорировать для этого вопроса.
Пример вывода # 1
Это делает, что вы ожидаете (немецкий формат DateTime, не путайте):
И в панели задач я также вижу, чего я ожидаю:
Пример вывода # 2 (переход на летнее время)
Но теперь к странной части: Переключите первую строку вызывающего кода для
// one second before transition to daylight saving time in Berlin
DateTime timeToSet = new DateTime(2015, 3, 29, 1, 59, 59, 0);
Теперь вывод командной строки, по-видимому, удовлетворяет тому, что мы ожидаем увидеть:
Но затем мы посмотрим вниз справа от нашей панели задач и войдем в хмурые земли и увидим время, которое на самом деле не должно существовать на этот день:
Пример вывода # 3 (Переход от летнего времени)
Теперь самое смешное, когда я пытаюсь сделать то же самое для второго до перехода от летнего времени, изменение получает "принято" (снова переключает первую строку кода вызова):
// one second before transition out of daylight saving time in Berlin
DateTime timeToSet = new DateTime(2014, 10, 26, 2, 59, 59, 0);
Мы видим, что мы ожидаем в выводе командной строки:
также в часах панели задач:
Но эта история также имеет печальный конец, пусть один второй проход, и вы ожидаете, что часы показывают 2 'o часы, но вместо этого:
Какое время должно произойти через час в этот конкретный день (если вы вручную переключите время в окнах, это произойдет, как ожидается).
Вопрос
Теперь, чего я здесь не вижу, почему я не могу настроить таргетинг на секунду до перехода на летнее время и почему я не вижу переход от летнего времени, когда я делаю DateTime, программно изменяется таким образом?
Что мне нужно добавить/установить, чтобы я мог?