Bunu amaçlarım için çözdüm. Öğrendiklerimi özetleyeceğim (üzgünüm, bu notlar ayrıntılı; bunlar benim gelecekteki tavsiyem için başka herhangi bir şey kadar çok).
Benim daha önceki yorumların birinde söylediklerini aksine, DATETIME ve TIMESTAMP alanları yok farklı davranır. TIMESTAMP alanları (belgelerde belirtildiği gibi) "YYYY-AA-GG ss: dd: ss" biçiminde gönderdiğiniz her şeyi alır ve geçerli saat diliminizden UTC saatine dönüştürür. Verileri her aldığınızda bunun tersi şeffaf bir şekilde gerçekleşir. DATETIME alanları bu dönüşümü yapmaz. Gönderdiğiniz her şeyi alırlar ve doğrudan saklarlar.
Ne DATETIME ne de TIMESTAMP alan türleri, DST'yi gözlemleyen bir saat diliminde verileri doğru şekilde depolayamaz . "2009-11-01 01:30:00" depolarsanız, alanların hangi 1:30 am sürümünü istediğinizi ayırt etme yolu yoktur - -04: 00 veya -05: 00 sürümü.
Tamam, bu nedenle verilerimizi DST olmayan bir saat diliminde (UTC gibi) saklamalıyız. TIMESTAMP alanları, açıklayacağım nedenlerden dolayı bu verileri doğru şekilde işleyemiyor: Eğer sisteminiz bir DST saat dilimine ayarlanmışsa, o zaman TIMESTAMP'a koyduğunuz şey, geri aldığınız şey olmayabilir. Daha önce UTC'ye dönüştürdüğünüz verileri gönderseniz bile, verilerin yerel saat diliminizde olduğunu varsayar ve yine UTC'ye başka bir dönüştürme yapar. Yerel saat diliminiz DST'yi gözlemlediğinde bu TIMESTAMP tarafından zorunlu kılınan yerel-UTC-dönüş-yerel gidiş-dönüş kayıplı olur ("2009-11-01 01:30:00", 2 farklı olası zamana eşleşir).
DATETIME ile verilerinizi istediğiniz herhangi bir saat diliminde saklayabilir ve ne gönderirseniz gönderin geri alacağınızdan emin olabilirsiniz (TIMESTAMP alanlarının size dayattığı kayıplı gidiş-dönüş dönüşümlerine zorlanamazsınız). Bu nedenle çözüm, bir DATETIME alanı kullanmak ve alana kaydetmeden önce , sistem saat diliminizden onu kaydetmek istediğiniz DST olmayan bölgeye dönüştürün (UTC'nin muhtemelen en iyi seçenek olduğunu düşünüyorum). Bu, "2009-11-01 01:30:00 -04: 00" veya "" 2009-11-01 01:30 UTC eşdeğerini açıkça kaydedebilmeniz için dönüştürme mantığını komut dosyası dilinize oluşturmanıza olanak tanır: 00-05: 00 ".
Unutulmaması gereken bir diğer önemli nokta da, tarihlerinizi bir DST TZ'de saklarsanız, MySQL'in tarih / saat matematik işlevlerinin DST sınırları etrafında düzgün çalışmamasıdır. Bu yüzden UTC'de kaydetmek için daha fazla neden var.
Özetle, şimdi şunu yapıyorum:
Veritabanından veri alırken:
Doğru bir Unix zaman damgası elde etmek için veritabanındaki verileri MySQL dışında UTC olarak açıkça yorumlayın. Bunun için PHP'nin strtotime () işlevini veya DateTime sınıfını kullanıyorum. MySQL'in CONVERT_TZ () veya UNIX_TIMESTAMP () fonksiyonları kullanılarak MySQL içinde güvenilir bir şekilde yapılamaz çünkü CONVERT_TZ yalnızca belirsizlik problemlerinden muzdarip bir 'YYYY-AA-GG ss: dd: ss' değeri verir ve UNIX_TIMESTAMP (), girdi sistem saat dilimindedir, verilerin GERÇEKTEN (UTC) olarak depolandığı saat diliminde değildir.
Verileri veritabanına saklarken:
Tarihinizi MySQL dışında istediğiniz kesin UTC saatine dönüştürün. Örneğin: PHP'nin DateTime sınıfı ile "2009-11-01 1:30:00 EST" yi "2009-11-01 1:30:00 EDT" den farklı olarak belirleyebilir, ardından UTC'ye çevirebilir ve doğru UTC saatini kaydedebilirsiniz. DATETIME alanınıza.
Phew. Herkesin katkısı ve yardımı için çok teşekkürler. Umarım bu, bir başkasını yolda baş ağrısından kurtarır.
BTW, bunu MySQL 5.0.22 ve 5.0.27'de görüyorum