SORU
5 Mart 2012, PAZARTESİ


Görmezden gelerek tamamen Raylar ve PostgreSQL in dilimleri

Raylar tarihler ve saatler ve PostgreSQL ile ilgili ve bu sorunla karşılaştım.

Veritabanı UTC.

Kullanıcı Raylar seçtiğiniz saat dilimi uygulaması ayarlar, ama karşılaştırarak kez kullanıcılar yerel saat alırken kullanılacak.

Kullanıcı zaman, 17 Mart 2012, saat 7 demek saklar. Zaman dilimi dönüşümleri veya depolanmak üzere zaman dilimini istemiyorum. Ben sadece tarih ve saat kaydedilen istiyorum. Eğer kullanıcı kendi saat dilimini değiştirdi, hala 17 Mart 2012, saat 7 gösterirdi.

Ben kullanıcı kayıtları '' veya 'sonra' kullanıcılar yerel saat dilimi geçerli saat önce saat dilimi belirtilen sadece kullanın

Ben şu anda kullanıyorum 'zaman dilimi olmadan zaman damgası kayıtları, raylar ben almak, ama (?) istemediğim zaman için app zone dönüştürür.

Appointment.first.time
 => Fri, 02 Mar 2012 19:00:00 UTC  00:00 

Veritabanındaki kayıtları 'Tarih, hack şimdiki zaman, zaman kaldırmak UTC bölge olarak gelmek gibi görünüyor çünkü(, "%m/%d/%Y")' ve sonra bir sorgu yapmak: . str strptime

.where("time >= ?", date_start)

Sadece zaman dilimleri tüm görmezden gelmek daha kolay bir yolu olmalı gibi görünüyor. Herhangi bir fikir?

CEVAP
6 Mart 2012, Salı


PostgreSQL veri türü 53**timestamp without time zonevarsayılan olarak.
Diğer seçeneği timestamptz (timestamp with time zone).

Epoch

DAHİLİ olarakzaman damgaları epoch gelen sayısı olarak saklanır. İsim UTC, 2000-01-01T00:00:00z gibi 2000 yılı ilk günün ilk anda bir devrin kullanır. 56* *sekiz sayısı numarasını saklamak için kullanılır. Derleme zamanı seçeneği bağlı olarak, bu sayı da

  • Bir8 bayt tamsayı(varsayılan), kesirli saniye, 0 6 basamaklı
  • Kayan noktalı sayı (artık kullanılmıyor), epoch uzak hassas hızlı bir şekilde değerleri daha da düşüyor nerede kesirli saniye, 0-10 basamaklı.
    Modern İsim tesisler 8-bayt tamsayı kullanın.

PostgreSQL unutmayındeğilUnix time kullanın. ’ Çağın ilk Unıx’ 1970-01-01. yerine anın 2000-01-01. isim Unix zaman bütün saniye çözünürlüğe sahip iken, PostgreSQL saniye bölümlerini tutar.

timestamp

Bir veri türü tanımlartimestampİsim söylüyorsun [without time zone]: "açıkça bir zaman dilimi veren ben değilim, geçerli saat dilimi yerine varsayalım. PostgreSQL zaman damgası kaydedergibi-görmezdenbir saat dilimi varsa ekleyin olursanız değiştirici!

Ne zaman seni sonra timestamp, kelimenin tam anlamıyla girdiğiniz geri almanız görüntüler. İnce ise, aynı zaman dilimi. Eğer oturum için saat dilimi değişirse, timestamp - anlamıdeğerde aynı kalır.

timestamptz

Taşıma içintimestamp with time zonekurnazca farklı. I quote the manual here:

timestamp with time zone şirket içinde saklı değerher zaman UTC(Evrensel Koordineli Zaman ...)

Bold vurgu benim.saat dilimikendisidirasla saklı. Depolanan göre UTC zaman damgası, hesaplamak için kullanılır. Eğer giriş timestamptz bir zaman dilimi değiştiricisi ekleme yok eğer doğru değilse, oturum yerel saat dilimi kabul edilir. Tüm hesaplamaları UTC zaman damgası değerleri ile yapılır. Eğer (ya da olabilir) ile daha fazla zaman dilimi üzerinde daha anlaşma varsa, timestamptz kullanmalısınız.

psql müşteriler seviyor ya pgAdmin (veya Ruby) UTC zaman damgası değerine göre gösterilmiştirgeçerli zaman dilimiYa göre (timestamp timestamp with time zone hem)istedibölge (aşağıya bakınız). Her zamanaynı zaman içindebiçimi değişir görüntü. sadece Ya da, how the manual puts it:

Zaman dilimi tanımayan tüm tarihler ve saatler UTC DAHİLİ olarak saklanır. Onlar bölgenin zaman dilimini tarafından belirtilen yerel saate dönüştürülür istemciye görüntülenen önce Yapılandırma parametresi.

Bu basit bir örnek (numarasını) göz önünde bulundurun:

db=# SELECT '2012-03-05 20:00 03'::timestamp with time zone;
      timestamptz
------------------------
 2012-03-05 18:00:00 01

Bold vurgu benim. Burada ne oldu?
Keyfi bir zaman dilimi 3 ofset seçtim. PostgreSQL için, bu giriş için birçok yolu vardır UTC zaman damgası 2012-03-05 17:00:00. Geçerli saat dilimini biçimde görüntülenir sorgu sonucu: 2012-03-05 18:00:00 01. (Viyana benim server/Austria göre saat dilimi ile yapılandırılmış 1.)

İsim zaten bu değer girildi nasıl unuttu. Hatırlar tüm değeri ve veri türü. Sadece bir ondalık sayı ile gibi. '03.4'::numeric, '3.40'::numeric '3.4'::numeric - aynı iç değer bir araçtır.

AT TIME ZONE

Bu mantık bir kavrayışa alır almaz, istediğiniz her şeyi yapabilirsiniz. Artık kayıp veya zaman damgası rakamları yorumlamak temsil etmek için bir araçtır, belirli bir zaman dilimine göre. Bu yapı devreye giriyor. İki farklı kullanım durumları farkında olun. timestamptz timestamp dönüştürülen ya da tam tersi.

UTC girmek için zaman damgası 2012-03-05 17:00:00:

SELECT '2012-03-05 17:00:00'::timestamp AT TIME ZONE 'UTC'

UTC zaman damgası aynı zaman damgası değerini görüntülemek için:

SELECT '2012-03-05 17:00:00'::timestamp AT TIME ZONE 'UTC' AT TIME ZONE 'UTC'

Bu, AT TIME ZONE 'UTC' iki kez haklı. İlk bir UTC zaman damgası zaman damgası, literal olarak yorumlayan ve 43* *bu tür çıkışları. İkinci bir timestamp [without time zone] için geri dönüştürür.

Örnekler

SELECT ts AT TIME ZONE 'UTC'
FROM  (VALUES
      ('2012-03-05 17:00:00 0')
     ,('2012-03-05 18:00:00 1'::timestamp with time zone)
     ,('2012-03-05 18:00:00 1'::timestamp) --1loaded footgun!
     ,('2012-03-05 11:00:00'::timestamp AT TIME ZONE ' 6') 
     ,('2012-03-05 17:00:00'::timestamp AT TIME ZONE 'UTC') 
     ,('2012-03-05 10:00:00'::timestamp AT TIME ZONE 'US/Hawaii') --2
     ,( TIMESTAMP '2012-03-05 07:00:00' AT TIME ZONE 'HST') --2
      ) AS v(ts);

(6) aynı UTC özdeş satır zaman damgası döndürür 7 2012-03-05 17:00:00.

1Üçüncü satır olarak işaretlenmişfootgun yüklendiçalışırbenim içinama sadece tesadüf. Eğer açıkça bir zaman damgası timestamp [without time zone], the time zone offset will be ignored edebi bir düşünün! Göre yorumlanıryerelzaman benim durumumda aynı zaman 1 bölge olan bölge yerine,. Ama muhtemelen farklı bir değer olarak, sizin için değil.

2Saat dilimi ile son iki satır notadıve zaman dilimikısaltmaHawaii için zaman DST tabidir ve farklı olabilir. Bir saat dilimi adı gibi 'US/Hawaii' farkında DST (Yaz Saati) kurallar ve tüm diğer (tarihi) vardiya otomatik olarak, süre kısaltma gibi HST sadece aptal bir kod için sabit bir uzaklık. Yaz / kış saati için farklı bir kısaltma eklemek gerekebilir.adıdoğru yorumlarherhangi birverilen zaman damgası bölge. Bir kısaltma daha. ama yılın belirli yıl ve bu zaman için doğru olması gerekir

Gün ışığından yararlanma Saati en parlak fikirler arasında insanlığın bugüne kadar geldi.

Veritabanı UTC, AT TIME ZONE 'UTC' varsayılan olarak düşmüş olabilir çünkü.

Sorularınıza gelince

Kullanıcı zaman, 17 Mart 2012, saat 7 demek saklar. Zaman dilimi istemiyorum dönüşüm veya saat dilimini depolanacak.

Zaman dilimi kendisi asla saklanır. Yukarıdaki yöntemlerden birini UTC zaman damgası girmek için kullanın.

Ve:

Ben sadece kullanıcılar, belirtilen zaman dilimi kayıtlarını almak için kullanın '' ya önce 'sonra' kullanıcı geçerli saati yerel saat dilimi.

Farklı zaman dilimlerinde tüm istemciler için tek bir sorgu kullanabilirsiniz.
Mutlak küresel zaman için:

SELECT * FROM tbl WHERE time_col > (now() AT TIME ZONE 'UTC')::time

Yerel saate göre saat:

SELECT * FROM tbl WHERE time_col > now()::time

Zaman yönetimi/tarih hakkında her türlü bilgi yorgun değil mi? There is more in the manual.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Floortile83

    Floortile83

    16 Ocak 2010
  • THE RED DRAGON

    THE RED DRAG

    6 ŞUBAT 2009
  • ThePhestor

    ThePhestor

    22 Mart 2011