C# DateTime.ToString o Формат возвращает другую строку в Azure

У меня есть сценарий, в котором я хочу преобразовать даты UTC в строки ISO 8601 с определенным часовым поясом для отправки через веб-API. Рекомендуемый способ сделать это — использовать TimeZoneInfo следующим образом:

var configuredTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneString);
var localTime = DateTime.SpecifyKind(TimeZoneInfo.ConvertTimeFromUtc(utcTime, configuredTimeZone), DateTimeKind.Local);
var stringResult = localTime.ToString("o");

Это отлично работает на моем локальном компьютере, но я сталкиваюсь с очень странной ситуацией, когда ToString выводит другую строку, когда код размещен в веб-приложении Azure. Локально я получаю 2017-02-20T00:00:00-06:00 (это то, что я хочу, так как он содержит нужную мне информацию о часовом поясе), но при размещении в Azure я получаю 2017-02-20T00:00:00+ 00:00 (в формате UTC, а не то, что мне нужно). Поскольку я вручную применяю нужный часовой пояс, я не уверен, почему формат добавляет неправильную информацию о часовом поясе. Кто-нибудь сталкивался с этим раньше?


person Nathan G    schedule 22.02.2017    source источник
comment
DateTime не может сохранить часовой пояс.   -  person SLaks    schedule 23.02.2017
comment
а местный часовой пояс в Azure — UTC.   -  person Mickaël Derriey    schedule 23.02.2017
comment
Я вручную указываю часовой пояс, который хочу, через TimeZoneInfo.ConvertTimeFromUtc, так как же использование Azure UTC может испортить преобразование?   -  person Nathan G    schedule 23.02.2017


Ответы (1)


Как упоминалось в комментариях, System.DateTime не может хранить часовые пояса. Все, что он знает, это «местный» или «UTC». Поскольку оно размещено в Azure, его "местное" время соответствует UTC.

Таким образом, ваше утверждение TimeZoneInfo.ConvertTimeFromUtc(utcTime, configuredTimeZone) преобразует время UTC в ваше время (полночь 20-го числа), но поскольку DateTime не содержит часового пояса, оно соответствует DateTimeKind.Unspecified. Ваш DateTime.SpecifyKind(..., DateTimeKind.Local) просто сообщает ему, что он имеет тип «локальный», а в случае узла Azure — UTC+00:00.

Если важны часовые пояса, вы можете использовать System.DateTimeOffset вместо DateTime. Он специально создан для хранения и управления (как следует из названия) смещениями часовых поясов.

person NPras    schedule 22.02.2017