Как получить правильное смещение часового пояса при переходе на летнее время в C # - PullRequest
0 голосов
/ 05 июля 2019

Я изо всех сил пытаюсь получить правильное смещение даты и времени при переходе с зимнего на летнее время.

Я пытаюсь отправить запрос в API, и параметры представляют собой две даты в следующем формате: "2018-03-01T01:00:00+01:00" Я создал два Datetimeoffset в Paris TimeZone (мой компьютер находится в Великобритании, но API - французская служба), вот как я это сделал:

var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Romance Standard Time");
DateTime dt = new DateTime(2018,03,01,00,00,00);
dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
DateTimeOffset startingDate = new DateTimeOffset(dt);
startingDate = TimeZoneInfo.ConvertTime(startingDate, timeZoneInfo);
DateTimeOffset endingDate = new DateTimeOffset();
for (int i = 0;i<700;i++)
{
     startingDate = startingDate.AddMonths(i);
     endingDate = startingDate.AddMonths(1);
     IRestResponse myquery= getAPIresult("", "", startingDate.ToString("yyyy-MM-ddTHH:mm:sszzzzzz"), endingDate.ToString("yyyy-MM-ddTHH:mm:sszzzzzz"));

При выполнении кода я получаю "2018-03-01T01:00:00+01:00" для startDate, чего я и ожидаю.

Но я получаю "2018-04-01T01:00:00+01:00" за окончание даты, что странно, поскольку 31 марта - летнее время во Франции, поэтому парижская часовая зона такая с GMT + 01 до GMT + 02.

Так что я должен получить "2018-04-01T01:00:00+02:00" на дату окончания.

Если бы вы могли помочь мне в этом, я был бы очень благодарен.

1 Ответ

1 голос
/ 08 июля 2019

Вы должны вызвать TimeZoneInfo.ConvertTime в цикле, чтобы каждое значение пересчитывалось в соответствии с часовым поясом.(DateTimeOffset содержит только смещение, а не часовой пояс.)

Кроме того, ваша логика .AddMonths(i) ошибочна, так как вы изменяете startingDate в цикле.Вы можете использовать .AddMonths(1) или оставить исходную дату начала в отдельной переменной, которая не изменяется.

Самое простое исправление, таким образом:

startingDate = TimeZoneInfo.ConvertTime(startingDate.AddMonths(1), timeZoneInfo);
endingDate = TimeZoneInfo.ConvertTime(startingDate.AddMonths(1), timeZoneInfo);

Кроме того, выВозможно, вы захотите подумать, почему вы вообще вводите DateTimeKind.Local в дату начала.Это должно быть неуместно для этой задачи.Рассмотрим, возможно, вместо этого:

DateTime dt = new DateTime(2018, 3, 1, 0, 0, 0);
TimeSpan offset = timeZoneInfo.GetUtcOffset(dt);
DateTimeOffset startingDate = new DateTimeOffset(dt, offset);
...