Зберігання DateTime (UTC) проти зберігання DateTimeOffset


94

У мене зазвичай є "перехоплювач", який безпосередньо перед зчитуванням / записом з / в базу даних виконує перетворення DateTime (з UTC на місцевий час та з місцевого часу на UTC), тому я можу використовувати DateTime.Now(виведення та порівняння) по всій системі, не турбуючись про часові пояси.

Щодо серіалізації та переміщення даних між комп’ютерами, не потрібно турбуватися, оскільки час і дата завжди є UTC.

Чи слід продовжувати зберігати мої дати (SQL 2008 - дата-час) у форматі UTC, чи замість цього я повинен зберігати їх за допомогою DateTimeOffset(SQL 2008 - datetimeoffset)?

Дати UTC у базі даних (тип часу та часу) працюють і відомі так давно, навіщо її змінювати? Які переваги?

Я вже подивився в статтях , як цей , але я не 100% переконаний , хоча. Будь-які думки?


Питання, пов’язані з цим: stackoverflow.com/questions/2532729/…
відмінено

1
Дивіться також: DateTime vs DateTimeOffset - написано для .Net, але концептуально стосується і SQL.
Метт Джонсон-Пінт

Відповіді:


131

Є одна величезна різниця, коли ви не можете користуватися UTC самостійно.

  • Якщо у вас такий сценарій

    • Один сервер і кілька клієнтів (всі географічно в різних часових поясах )
    • Клієнти створюють деякі дані з інформацією про час
    • Клієнти зберігають все це на центральному сервері
  • Тоді:

    • datetimeoffset зберігає місцевий час клієнта та ТАКОЖ зміщення до часу UTC
    • всі клієнти знають час усіх даних по UTC, а також місцевий час у тому місці, де інформація походить
  • Але:

    • UTC datetime зберігає лише UTC datetime , тому ви не маєте інформації про місцевий час у місцезнаходженні клієнта, звідки походять дані
    • Інші клієнти не знають місцевого часу місця, звідки надходила інформація про дату
    • Інші клієнти можуть обчислювати лише свій локальний час із бази даних (використовуючи час UTC), а не місцевий час клієнта, звідки вони походять дані

Простий приклад - система бронювання авіаквитків ... Рейс повинен містити 2 рази: - час "зльоту" (у часовому поясі міста "З" міста) - час "посадки" (у часовому поясі міста "Місце призначення")


2
Це найкраще пояснення, про яке я читав, коли це було б доречно, і я багато читав. Для нас це, здається, не так. Ми отримуємо час в UTC за нашими зовнішніми даними, і ми знаємо місце з іншого джерела, якщо це потрібно (а цього ніколи не було). Дякуємо, що зробили це очевидним.
Ендрю Беккер

19
Ви сказали, що "timetimesetset зберігає UTC-час і ТАКОЖ зміщується на місцевий час клієнта", але timesetsetset зберігає LOCAL time + Offset, або UTC time + offset рівний +0.
Сергій Кислий

хоча ви можете просто передати DTO на DT, оскільки база DT - це UTC (хоча це буде додатковим кроком для всіх, хто використовує базу даних, і, мабуть, не простіший, ніж просто використання часу UTC)
iliketocode

2
Схоже, що DateTmeOffset зберігає "Місцевий час та зміщення UTC", а не "UTC Час та Зсув UTC". Якщо ви передаєте дату часу або використовуєте будь-яку з функцій частини дати, ви отримаєте локальні компоненти дати та часу.
Трайко

" усі клієнти знають час усіх даних по UTC, а також місцевий час у тому місці, де інформація походить" Хоча зберігання як частина поля дати в цьому випадку відчуває себе ненормалізованим. Який випадок використання - тобто чому б ви не використовували UTC і не витягували зсув для InputLocationId(або подібного нормалізованого об'єкта). Буде пов'язано з розрахунком (привіт, винятки ... особливо ви, Індіана ), але це все-таки детермінований процес - і тоді баланс логіки дати роботи додатка простий.
ruffin

23

Ви абсолютно правильно використовуєте UTC за всі історичні часи (тобто записуються події). Завжди можна переходити з UTC до місцевого часу, але не завжди навпаки.

Коли використовувати місцевий час? Відповідь на це запитання:

Якщо уряд раптом вирішить змінити економію денного світла, чи хотіли б ви, щоб ці дані змінювались?

Зберігайте місцевий час лише в тому випадку, якщо відповідь "так". Очевидно, що це буде тільки для майбутніх побачень, і, як правило, тільки для дат, які певним чином впливають на людей.

Навіщо зберігати часовий пояс / зсув?

По-перше, якщо ви хочете записати, яке зміщення було для користувача, який здійснив дію, вам, мабуть, краще всього це зробити, тобто записувати місце розташування та часовий пояс для цього користувача.

По-друге, якщо ви хочете перетворити для відображення, вам потрібно мати таблицю всіх локальних переходів за зміщенням часу за цей часовий пояс, просто знати поточне зміщення недостатньо, тому що якщо ви показуєте дату / час з півроку тому, компенсація буде бути іншим.


4
Конвертація UTC UTC з місцевим часом враховує зміну переходу на літній час для історичних дат. Я не розумію, чому в такому випадку ви хотіли б зберігати місцевий час.
Джеймігс,

1
@Jamiegs Windows лише історично знає "останню історичну інформацію" (про що натякає / зазначається в документації .NET DateTime). Це не є всеосяжним.

2
звичайно, вам також доведеться зберігати місце події, інакше ви не можете сказати, в який «місцевий час» подія сталася.
keuleJ

20

DATETIMEOFFSET надає вам можливість зберігати місцевий час та час UTC в одному полі.

Це дозволяє вести дуже просту та ефективну звітність у місцевий час або за UTC, без необхідності будь-яким чином обробляти дані для відображення.

Це дві найпоширеніші вимоги - місцевий час для місцевих звітів та час UTC для групових звітів.

Місцевий час зберігається в частині DATETIME DATETIMEOFFSET, а OFFSET від UTC зберігається в частині OFFSET, тому перетворення є простим і, оскільки воно не вимагає знання часового поясу, з якого отримані дані, все це можна зробити на рівні бази даних .

Якщо вам не потрібні періоди до мілісекунд, наприклад, до хвилин або секунд, ви можете використовувати DATETIMEOFFSET (0). Тоді для поля DATETIMEOFFSET буде потрібно лише 8 байт пам’яті - стільки ж, скільки для DATETIME.

Тому використання DATETIMEOFFSET замість UTC DATETIME забезпечує більшу гнучкість, ефективність та простоту для звітності.


Занадто поганий фреймворк сутності не має жодного способу отримати доступ до місцевого часу поля зміщення дати, що унеможливлює запит на певну локальну дату.
Трайнко

@Triynko, ти можеш пояснити, що ти маєш на увазі? Приклад?
reidLinden
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.