Форум программистов, компьютерный форум, киберфорум
C#: ASP.NET Core
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.65/55: Рейтинг темы: голосов - 55, средняя оценка - 4.65
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775

DateTime и часовые пояса

27.07.2021, 18:39. Показов 11077. Ответов 25
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
На клиенте и на сервере net-core-5.
С обеих сторон используется 'System.Text.Json' (без ручных конвертеров, т.е. полностью дефолтные настройки).

Клиент: UTC +03:00.
Сервер: UTC +02:00.

На клиенте сериализуется 'DateTime', на сервере оно десериализуется, в итоге получается:
c: '27.07.2021 00:00:00 +03:00'.
s: '26.07.2021 23:00:00 +02:00' (т.е. сервер получил дату/время в своём часовом поясе).

Для данного типа данных это ожидаемое дефолтное поведение, судя по документации на используемый json-сериализатор.

Если использовать 'DateTimeOffset', то значение и на клиенте, и на сервере остаётся без изменений, т.е. ожидаемые '27.07.2021 0:00:00 +03:00', т.е. сервер получает оригинальное значение не преобразованное принудительно в его часовой пояс. И дальше два сценария:
1. Можно привести его к локальному времени, если необходимо, например, показать пользователю точное время какого-то события.
2. Можно проигнорировать часовой пояс, если задача передать не временную метку, а, скажем, выбор пользователем конкретной даты для фильтрации записей. Т.е. если клиент хочет все документы за '2021-07-27', а сервер ему вернёт за 26-е число, то это будет некорректно.

Получается, что тип 'DateTime' вообще не применим в DTO, т.к. при его использовании теряется информация о часовом поясе клиента и нет возможности однозначно интерпретировать передаваемые даты?

Добавлено через 32 минуты
----
Как же всё неочевидно с этими типами при дефолтной сериализаии:
DateTime.Now.Date
=> 2021-07-27T00:00:00+02:00

DateTimeOffset.Now.Date (оно возвращает DateTime, но с другим типом 'Kind', на что сериализатор реагирует отбрасыванием часового пояса)
=> 2021-07-27T00:00:00

(DateTimeOffset)DateTimeOffset.Now.Date
=> 2021-07-27T00:00:00+02:00

Т.е. при сериализации нет никакой разницы между дефолтным 'DateTime' и 'DateTimeOffset'.

А вот при десериализации различия появляются, т.к. в случае с 'DateTime' идёт неявное преобразование к текущему часовому поясу и выдача результата с 'Kind = Local', а в случае 'DateTimeOffset' оно восстанавливается в оригинальном состоянии как было на клиенте с его же часовым поясом.

И да, получается, что 'DateTime' в DTO опасен, т.к. приводит к потере информации.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
27.07.2021, 18:39
Ответы с готовыми решениями:

Часовые пояса.
Господа знатоки! Вопрос: ОС WIN7. Куда делись часовые пояса во вкладке "Изменить часовой пояс"? Кроме UTC +11.00 Магадан все пропали....

Часовые пояса
Как доделать часовые пояса? То есть, label показывает текущее время, другой label показывает: +4 часа . var Form1: TForm1; ...

Часовые пояса
Здравствуйте, подскажите пожалуйста как задать часовой пояс tvStatusDate.setText(new SimpleDateFormat("h:mm...

25
03.08.2021, 15:46
Студворк — интернет-сервис помощи студентам

Не по теме:

Цитата Сообщение от carrotik Посмотреть сообщение
как собственно и во всех аэропортах
Собственно во всех аэропортах в своем посадочном талоне вы видите местное время посадки/вылета.

0
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
03.08.2021, 16:24  [ТС]
Цитата Сообщение от carrotik Посмотреть сообщение
т.е. тут время создания/регистрации документа вообще ни о чем
Да, для этих целей подходит 'DateTimeOffset'.

Новый тип только с датой будет удобен там, где нужно именно дату выбрать/сохранить, без какой-либо привязки к часовому поясу.
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3461 / 2782 / 575
Регистрация: 04.09.2018
Сообщений: 8,745
Записей в блоге: 3
03.08.2021, 16:27
kotelok, и чем этот тип будет отличаться от обычного DateTime.Now ?
0
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
03.08.2021, 16:29  [ТС]
wizard41,
Тем, что описано в изначальном сообщении. Если пользователь в своей таймзоне выбрал '2021-01-01T00:00:00', то после дефолтной десериализации этого значения на сервере в другом часовом поясе, полученная дата автоматически превартится в '2020-12-31T22:00:00' и не будет никакой технической возможности понять что там изначально у клиента было (только если явно таймзону клиента передавать). У 'DateTimeOffset' этой проблемы с десериализацией нет.
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3461 / 2782 / 575
Регистрация: 04.09.2018
Сообщений: 8,745
Записей в блоге: 3
03.08.2021, 16:31
Цитата Сообщение от kotelok Посмотреть сообщение
Если пользователь в своей таймзоне выбрал '2021-01-01T00:00:00'
Цитата Сообщение от kotelok Посмотреть сообщение
полученная дата превартится в '2020-12-31T22:00:00'
Пока не углядел особой выгоды...
0
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
03.08.2021, 16:38  [ТС]
wizard41,
Выгода в том, что при использовании 'DateTime' и дефолтной десериализации без дополнительных костылей, в принципе не возможно понять, что именно было сериализовано на клиенте.

В контроллер/сервис приходит DTO, где уже есть свойство 'DateTime' со значением, автоматически преобразованным к часовому поясу сервера. И по самому значению в прицнипе не возможно понять что было у пользователя изначально.

Простейший пример - укажите таймзону больше вашей и посмотрите на результаты десериализации:
C#
1
2
3
var raw = "\"2021-01-01T00:00:00+06:00\"";
var dt = System.Text.Json.JsonSerializer.Deserialize<DateTime>(raw);
var dtOff= System.Text.Json.JsonSerializer.Deserialize<DateTimeOffset>(raw);
Добавлено через 1 минуту
Т.е. пользователь выбрал 1-е января, а на сервер пришло 31-го декабря.
Другой пользователь выбрал 31-е декабря и на сервер пришло 31-е декабря (т.к. он в другом часовом поясе). И при использовании 'DateTime', без запроса доп-информации о часовом поясе клиента, сервер не сможет понять что изначально было у пользователя.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
03.08.2021, 16:38

часовые пояса php
как сделать чтоб отображался норма часовой пояс тк сервер неруссыкий это надо сделать в этот код как осуществить все пробовал ппц ...

Часовые пояса в php
Доброго времени суток!!! Как сделать, что бы время отображалась для нужного часового пояса? Заранее спасибо!!!

Про часовые пояса
Добрый день! Вопрос таков: Я меняю время создания файла, и все бы ничего, но к вводимому времени прибавляется 4 часа. Как мне с помощью...

TIMESTAMP, date, часовые пояса
Добрый день! Хранится дата и время в БД в формате TIMESTAMP в виде '0000-00-00 00:00:00' я узнаю локальное время пользователя и задаю в...

Часовые пояса. Нужны названия, а не цифры(не +01:00,+02:00...)
Дело вот в чём. Решил я написать часовые пояса, написал собственно. А теперь проблема с летним/зимним временем. Сейчас вот у меня ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
26
Ответ Создать тему
Новые блоги и статьи
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru