Я зрозумів це для своїх цілей. Я підсумую те, що я дізнався (вибачте, ці нотатки є багатослівними; вони не менше, ніж будь-що інше для мого майбутнього направлення).
Попри те , що я сказав в одному з моїх попередніх коментарів, DATETIME і TIMESTAMP поля дійсно поводяться по- різному. Поля TIMESTAMP (як зазначено в документах) беруть все, що ви надсилаєте у форматі "РРРР-ММ-ДД ч: мм: сс", і перетворюють його з поточного часового поясу на час UTC. Зворотне відбувається прозоро кожного разу, коли ви отримуєте дані. Поля DATETIME не роблять цього перетворення. Вони беруть все, що ви їм надсилаєте, і просто зберігають це безпосередньо.
Ні типи полів DATETIME, ні TIMESTAMP не можуть точно зберігати дані в часовому поясі, що спостерігає за літнім часом . Якщо ви зберігаєте "2009-11-01 01:30:00", поля не мають можливості розрізнити, яку версію з 1:30 ранку ви хотіли - версію -04: 00 або -05: 00.
Гаразд, тому ми повинні зберігати наші дані у часовому поясі, що не за літнім часом (наприклад, UTC). Поля TIMESTAMP не можуть точно обробляти ці дані з причин, які я пояснимо: якщо для вашої системи встановлений часовий пояс літнього часу, то те, що ви вводите в TIMESTAMP, може бути не тим, що ви отримаєте назад. Навіть якщо ви надішлете йому дані, які ви вже перетворили на UTC, він все одно буде приймати дані у вашому місцевому часовому поясі та здійснить ще одне перетворення в UTC. Цей примусовий TIMESTAMP туди-назад до локального зворотного туру збитковий, коли ваш місцевий часовий пояс дотримується літнього часу (з "карт 2011-01-01 01:30:00" до 2 різних можливих часів).
Завдяки DATETIME ви можете зберігати свої дані в будь-якому часовому поясі та будьте впевнені, що отримаєте назад те, що надішлете (ви не будете змушені перетворювати туди і назад із втратами, які поля TIMESTAMP вимагають від вас). Отже, рішення полягає у використанні поля DATETIME і перед збереженням у поле перетворіть із часового поясу вашої системи в будь-яку зону, яка не є літнім часом, у якій ви хочете його зберегти (я думаю, що UTC, мабуть, найкращий варіант). Це дозволяє вбудувати логіку перетворення у вашу мову сценаріїв, щоб ви могли явно зберегти еквівалент UTC "2009-11-01 01:30:00 -04: 00" або "" 2009-11-01 01:30: 00 -05: 00 ".
Ще одне важливе, на що слід звернути увагу, - це те, що математичні функції дати / часу MySQL не працюють належним чином навколо меж літнього часу, якщо ви зберігаєте свої дати в TZ літнього часу. Тож тим більше причин економити в UTC.
У двох словах я зараз роблю це:
Під час отримання даних з бази даних:
Явно інтерпретуйте дані з бази даних як UTC поза MySQL, щоб отримати точну мітку часу Unix. Для цього я використовую функцію strtotime () або клас DateTime PHP. Це неможливо надійно зробити всередині MySQL, використовуючи функції CONVERT_TZ () або UNIX_TIMESTAMP () MySQL, оскільки CONVERT_TZ буде виводити лише значення "РРРР-ММ-ДД чч: мм: сс", яке страждає від проблем неоднозначності, а UNIX_TIMESTAMP () приймає своє вхід знаходиться в системному часовому поясі, а не в часовому поясі, ДЕЙСТВІ дані зберігались у (UTC).
При зберіганні даних у базі даних:
Перетворіть дату на точний час UTC, який ви бажаєте, поза MySQL. Наприклад: за допомогою класу DateTime PHP ви можете чітко вказати "2009-11-01 1:30:00 EST" від "2009-11-01 1:30:00 EDT", потім перетворити його на UTC і зберегти правильний час UTC до вашого поля DATETIME.
Фу. Щиро дякуємо за внески та допомогу кожного. Сподіваємось, це рятує когось іншого від головного болю в дорозі.
До речі, я бачу це на MySQL 5.0.22 та 5.0.27