Разбрах го за моите цели. Ще обобщя това, което научих (съжалявам, тези бележки са многословни; те са толкова за моя бъдеща препоръка, колкото и всичко друго).
Противно на това, което казах в един от предишните си коментари, полетата DATETIME и TIMESTAMP правят се държат по различен начин. Полетата TIMESTAMP (както показват документите) приемат всичко, което им изпратите, във формат "ГГГГ-ММ-ДД чч:мм:сс" и го преобразуват от текущата ви часова зона в UTC време. Обратното се случва прозрачно всеки път, когато извличате данните. Полетата DATETIME не правят това преобразуване. Те вземат всичко, което им изпратите, и просто го съхраняват директно.
Нито типовете полета DATETIME, нито TIMESTAMP могат точно да съхраняват данни в часова зона, която спазва DST . Ако съхранявате "2009-11-01 01:30:00", полетата нямат начин да разграничат коя версия на 1:30 сутринта сте искали - версията -04:00 или -05:00.
Добре, така че трябва да съхраняваме нашите данни в часова зона, която не е DST (като UTC). TIMESTAMP полетата не могат да обработват точно тези данни поради причини, които ще обясня:ако вашата система е настроена на DST часова зона, тогава това, което сте поставили в TIMESTAMP, може да не е това, което получавате обратно. Дори ако му изпратите данни, които вече сте преобразували в UTC, той пак ще приеме, че данните са във вашата местна часова зона и ще направи още едно преобразуване в UTC. Това наложено от TIMESTAMP двупосочно пътуване от локално до UTC-обратно до локално се губи, когато местната ви часова зона спазва DST (тъй като „2009-11-01 01:30:00“ се съпоставя с 2 различни възможни времена).
С DATETIME можете да съхранявате данните си във всяка часова зона, която искате, и да сте уверени, че ще получите обратно всичко, което изпратите (няма да бъдете принудени да преобразувате обратно в обратна посока с загуба, които полетата на TIMESTAMP ви налагат). Така че решението е да използвате поле DATETIME и преди записване в полето преобразувайте от вашата системна часова зона във всяка не-DST зона, в която искате да я запишете (мисля, че UTC е може би най-добрият вариант). Това ви позволява да изградите логиката на преобразуването във вашия скриптов език, така че да можете изрично да запазите еквивалента на UTC на "2009-11-01 01:30:00 -04:00" или ""2009-11-01 01:30:00 -05:00".
Друго важно нещо, което трябва да се отбележи, е, че математическите функции за дата/час на MySQL не работят правилно около границите на DST, ако съхранявате датите си в DST TZ. Така че още една причина да записвате в UTC.
Накратко, сега правя това:
При извличане на данните от базата данни:
Изрично интерпретирайте данните от базата данни като UTC извън MySQL, за да получите точен времеви печат на Unix. Използвам функцията strtotime() на PHP или нейния клас DateTime за това. Това не може да бъде надеждно направено вътре в MySQL с помощта на функциите CONVERT_TZ() или UNIX_TIMESTAMP() на MySQL, тъй като CONVERT_TZ ще изведе само стойност 'YYYY-MM-DD hh:mm:ss', която страда от проблеми с неясноти, а UNIX_TIMESTAMP() приема своята входът е в часовата зона на системата, а не в часовата зона, в която данните ВЪЩЕСТВАЛНО са били съхранени (UTC).
Когато съхранявате данните в базата данни:
Преобразувайте датата си в точното UTC време, което желаете извън MySQL. Например:с клас DateTime на PHP можете да посочите "2009-11-01 1:30:00 EST" различно от "2009-11-01 1:30:00 EDT", след което да го преобразувате в UTC и да запишете правилното време по UTC към вашето поле DATETIME.
фу Благодаря много за приноса и помощта на всички. Надяваме се, че това ще спести на някой друг главоболия в бъдеще.
BTW, виждам това на MySQL 5.0.22 и 5.0.27