如何在 C# 中获得正确的夏令时时区偏移量

How get correct time zone offset on daylight saving in C#

从冬令时切换到夏令时时,我很难获得正确的日期时间偏移量。

我想做的是向 API 发送请求,参数是两个日期,格式如下:“2018-03-01T01:00:00+01:00” 我在巴黎时区创建了两个 Datetimeoffset(我的电脑在英国,但 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”作为开始日期,这正是我所期望的。

但是我得到“2018-04-01T01:00:00+01:00”作为结束日期,这很奇怪,因为 3 月 31 日是法国的夏令时,所以巴黎时区从 GMT+01 到 GMT+02。

所以我应该得到“2018-04-01T01:00:00+02:00”作为结束日期。

如果你能帮我解决这个问题,我将不胜感激。

您必须在循环中调用 TimeZoneInfo.ConvertTime,这样每个值都是针对时区的 re-evaluated。 (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);