Как правильно сравнивать DateTimeOffset полученный от дат созданных через new DateTime или полученных через DateTime.Now/Today ?
Иногда у них разные смещения часового пояса.
var newdate = new DateTime(2000,1,1);
newdate.Kind // Unspecifiednew DateTimeOffset(newdate).Offset.Hours // 2
var now = DateTime.Now;
now.Kind // Localnew DateTimeOffset(now).Offset.Hours // 3
Полный пример с временной зоной с летним временем и кодом запущенным летом:
using System;
namespace ConsoleApp1
{
public static class Program
{
public static void Main()
{
var today = DateTime.Today;
// Today YYYY-MM-01
var firstDayMonth = new DateTimeOffset(
new DateTime(today.Year, today.Month, 1, 0, 0, 0, today.Kind).AddHours(12));
// Add year offset from 2000
DateTimeOffset withYearOffset = firstDayMonth.AddYears(2000 - firstDayMonth.Year);
// Add month offset from 1
var withMonthOffset = withYearOffset.AddMonths(1 - withYearOffset.Month);
// Add day offset from 1
var calculated_dt_2000_1_1_12_0_0 = withMonthOffset.AddDays(1 - withMonthOffset.Day);
// 01.01.2000 12:00:00 +03:00
Console.WriteLine(calculated_dt_2000_1_1_12_0_0);
var dt_2000_1_1_12_0_0 = new DateTimeOffset(new DateTime(2000, 1, 1).AddHours(12));
// 01.01.2000 12:00:00 + 02:00
Console.WriteLine(dt_2000_1_1_12_0_0);
// False
Console.WriteLine(calculated_dt_2000_1_1_12_0_0.Equals(dt_2000_1_1_12_0_0));
}
}
}
Здравствуйте, _NN_, Вы писали:
_NN>Как правильно сравнивать DateTimeOffset полученный от дат созданных через new DateTime или полученных через DateTime.Now/Today ? _NN>Иногда у них разные смещения часового пояса.
Приводи к UTC и сравнивай. ИМХО
Здравствуйте, Mihas, Вы писали:
M>Здравствуйте, _NN_, Вы писали:
_NN>>Как правильно сравнивать DateTimeOffset полученный от дат созданных через new DateTime или полученных через DateTime.Now/Today ? _NN>>Иногда у них разные смещения часового пояса. M>Приводи к UTC и сравнивай. ИМХО
Это не помогает.
Получается один час разница.
Здравствуйте, _NN_, Вы писали:
M>>Приводи к UTC и сравнивай. ИМХО _NN>Это не помогает. _NN>Получается один час разница.
Небезызвестный Jon Skeet на эту тему много копий сломал. Даже написал свою библиотеку, кажется, IodaTime.
Скорее всего он писал про эту проблему у себя в блоге.
Здравствуйте, _NN_, Вы писали:
_NN>Это не помогает. _NN>Получается один час разница.
Мне, видимо, везло.. Есть пример? Все ли в порядке с DateTime.Kind?
Здравствуйте, _NN_, Вы писали:
_NN>Как правильно сравнивать DateTimeOffset полученный от дат созданных через new DateTime или полученных через DateTime.Now/Today ? _NN>Иногда у них разные смещения часового пояса.
_NN>
_NN>var newdate = new DateTime(2000,1,1);
_NN>newdate.Kind // Unspecified
_NN>new DateTimeOffset(newdate).Offset.Hours // 2
_NN>var now = DateTime.Now;
_NN>now.Kind // Local
_NN>new DateTimeOffset(now).Offset.Hours // 3
_NN>
поставь месяц летний (с летним временем) и будут одинаковые
Das Reich der Freiheit beginnt da, wo die Arbeit aufhört. (c) Karl Marx
Здравствуйте, _NN_, Вы писали:
_NN>Здравствуйте, ksg71, Вы писали:
K>>поставь месяц летний (с летним временем) и будут одинаковые
_NN>А когда код буду запускать зимой поставить зимний ? _NN>Попробую вывести в ветку минимальный пример кода, который падает.
в примере кода сравниваюся не моменты времени, а их смещения от UTC
не знаю проблемы, но очевидно что они будут зависеть от перехода на летнее/зимнее время
Das Reich der Freiheit beginnt da, wo die Arbeit aufhört. (c) Karl Marx
Здравствуйте, ksg71, Вы писали:
K>в примере кода сравниваюся не моменты времени, а их смещения от UTC K>не знаю проблемы, но очевидно что они будут зависеть от перехода на летнее/зимнее время
Здравствуйте, Mihas, Вы писали:
M>Здравствуйте, _NN_, Вы писали:
_NN>>Это не помогает. _NN>>Получается один час разница. M>Мне, видимо, везло.. Есть пример? Все ли в порядке с DateTime.Kind?
Ну, в РФ решили эту проблему кардинально
Обновил код с примером: https://rsdn.org/forum/dotnet/8048942.1
Идея переводить оба времени в универсальное и возвращать обратно offset:
var calculated_dt_2000_1_1_12_0_0 = withDayOffset.ToUniversalTime().AddHours(firstDayMonth.Offset.Hours);
var dt_2000_1_1_12_0_0_withOffset = new DateTimeOffset(new DateTime(2000, 1, 1).AddHours(12));
var dt_2000_1_1_12_0_0 = dt_2000_1_1_12_0_0_withOffset.ToUniversalTime().AddHours(dt_2000_1_1_12_0_0_withOffset.Offset.Hours);
Весь код:
var today = DateTime.Today;
// Today YYYY-MM-01var firstDayMonth = new DateTimeOffset(
new DateTime(today.Year, today.Month, today.Day).AddHours(12));
// Add year offset from 2000
DateTimeOffset withYearOffset = firstDayMonth.AddYears(2000 - firstDayMonth.Year);
// Add month offset from 1var withMonthOffset = withYearOffset.AddMonths(1 - withYearOffset.Month);
// Add day offset from 1var withDayOffset = withMonthOffset.AddDays(1 - withMonthOffset.Day);
var calculated_dt_2000_1_1_12_0_0 = withDayOffset.ToUniversalTime().AddHours(firstDayMonth.Offset.Hours);
// 01.01.2000 12:00:00 +00:00
Console.WriteLine(calculated_dt_2000_1_1_12_0_0);
var dt_2000_1_1_12_0_0_withOffset = new DateTimeOffset(new DateTime(2000, 1, 1).AddHours(12));
var dt_2000_1_1_12_0_0 = dt_2000_1_1_12_0_0_withOffset.ToUniversalTime().AddHours(dt_2000_1_1_12_0_0_withOffset.Offset.Hours);
// 01.01.2000 12:00:00 + 00:00
Console.WriteLine(dt_2000_1_1_12_0_0);
Здравствуйте, _NN_, Вы писали:
_NN>Здравствуйте, ksg71, Вы писали:
K>>в примере кода сравниваюся не моменты времени, а их смещения от UTC K>>не знаю проблемы, но очевидно что они будут зависеть от перехода на летнее/зимнее время
_NN>Обновил пример кода: https://rsdn.org/forum/dotnet/8048942.1
_NN>Как правильно сравнивать ? _NN>Для воспроизведения локально достаточно выставить временную зону с переходом на летнее время.
ну DateTime у них одинаковый, ну а так то все правильно — это разные моменты времени — что значит "правильно" их сравнить?
можно при создании DateTimeOffset ему явно смещение задавать или все даты в UTC вести чтобы оно нулевым было
Das Reich der Freiheit beginnt da, wo die Arbeit aufhört. (c) Karl Marx