2012-04-10 9 views
5

yanlış Zaman beginning_of_day end_of_day formatı: Ben beklediğiniz Ben tam olsun DateTime.now.beginning_of_day çalıştırırsanızRaylar 3 DateTime ve ben bu kodla belirli günlerde olayları bulmaya çalışıyorum

Event.where('starttime BETWEEN ? AND ?', DateTime.now.beginning_of_day, DateTime.now.end_of_day) 

raylar konsolunda:

Mon, 09 Apr 2012 00:00:00 -0700

Sorunun nerede olduğunu görebiliyorum ancak SQL konsollarına bakıyorum. Her nasılsa tarih, SQL sorgusuna girdiğinde otomatik olarak yanlış tarihe ve saate biçimlendirilir.

SELECT "events".* FROM "events" WHERE (starttime BETWEEN '2012-04-09 07:00:00' AND '2012-04-10 06:59:59') 

Bu, yukarıdaki sql'ün söylediği gibi, bugün bugünden yarına kadar değişen sonuçlar veriyor. DateTime.now.beginning_of_day ayrıca DateTime.now.end_of_day, sql sorgusuna yaptıklarında yanlış biçimlendirildiğini görebiliyorum. Bunu belirli bir şekilde biçimlendirmem gerekiyor mu? Bugün 7:00 ve yarın saat 7'ye neden gideceği hakkında bir fikrin var mı?

Fark yaratıp yaratmadığını bilmiyorum ama PostgreSQL kullanıyorum.

Teşekkürler!

cevap

15

Bkz:

http://railscasts.com/episodes/106-time-zones-in-rails-2-1 Ben sadece bir UTC zamanı, yukarıdaki alıntı ediyoruz kez aslında aynı zaman olduğunu düşünüyorum (sağ pasifik zamanında geldin?). Bunu düzeltmek için ayarını deneyebilirsiniz:

config.time_zone = "Pasifik Saati (ABD & Kanada)"

sizin environment.rb

Şunu da deneyebilirsiniz:

DateTime.now.utc.beginning_of_day 
DateTime.now.utc.end_of_day 

Bu nedenle, UTC'yi DB

+0

Hey cevabı takdir ediyorum. Seni tamamen takip edip etmediğimi bilmiyorum, ama pasifik zamana göre yapılandırmamı değiştirmenin iyi bir fikir olduğunu düşünmüyorum, çünkü pasifik zamanda olmayan kullanıcılar ne olacak? Umarım söylediklerimi alırım. Ayrıca, DateTime.now.utc.beginning_of_day öğesinin kullanılması, ilk gönderiimde listelediğim sorguları çalıştırdığımda aynı soruna neden oluyor. – botbot

+0

evet, pasifik zamanında yaşıyorum. Bazı araştırmalar yaptıktan sonra bu olası bir çözüm gibi görünüyor. Bunu deneyeceğim. Önerin için teşekkürler. Hala NY'deki kullanıcılar için endişeleniyorum, bunun bir sorun olup olmadığını bilmiyorum, ancak uygulamanın pasifik zamanda çalışması bu noktada prototip yapmak için yeterince iyi. Teşekkürler. – botbot

+0

@masterkrang, NY'deki kullanıcılar ve farklı saat dilimleri hakkında endişelenmeniz gerekirse, kullanıcının hangi saat dilimini kaydettiğini kaydedin ve bu kullanıcılar için uygun şekilde ayarlayın. https://gist.github.com/809775 – rainkinz

2

Veritabanınızda büyük olasılıkla UTC saati kullanıyorsunuzdur. Bu iyi bir şey ama her türlü karışıklığa yol açar. -0700 ofset, gününüz UTC saatinde başladığından beri 07:00:00 olarak dönüştürülür.

+0

Cevabınız için teşekkürler. utc kullanmak iyi ise, o zaman sorguları çalıştırdığım zaman ofsetin dönüştürülmesini nasıl engellerim? – botbot

+0

UTC'yi kullanmanızın nedeni, veritabanının hangi saat diliminde oluşturulduğunu izlemeniz gerekmediğinden, sıfır ofset UTC'den gerektiği gibi yerel zamanlara kolayca dönüştürebilirsiniz. Çoğu bölge, DST nedeniyle yıl boyunca zaman dilimi ofsetlerini değiştirir. "00:00:00 -0700", "07:00:00 -0000" e eşittir. "Starttime" değerleriniz UTC'de mi depolanıyor yoksa bunları kaydetmeden önce saat dilimi bilgilerini istemeden ayırdınız mı? – tadman

+0

, postgresql veritabanındaki alan "zaman dilimi olmayan zaman damgası" dır. Uygulamamdaki tüm tarihler arasında oldukça büyük bir sorun olduğunu anlıyorum. ActiveRecord içinde bir özellik ayarlarsanız, Model.my_var = Time.now diyelim, sonra kaydet'i çağırın, Time.now veritabanında yarın bir süre olarak kaydedilir. örneğin, eğer Zaman.now = Çar Nis 11 22:48:12 -0700 2012, kaydetmeyi denediğimde, sql tarihinin "2012-04-11 05:47:47" olarak kaydedildiğini görebiliyorum. sonra. Bunun farkındayım çünkü Time.now'dan gelen -700. Sadece bunu nasıl çözeceğimi anlamaya çalışıyorum. herhangi bir fikir? – botbot

1

uyarınca kullanıyorsunuz. PostgreSQL AT TIME ZONE yapısını UTC zaman damgalarıyla kullanabilirsiniz:

SELECT e.* 
FROM events e 
WHERE starttime >= '2012-04-09 00:00' AT TIME ZONE 'UTC' 
AND starttime < '2012-04-10 00:00' AT TIME ZONE 'UTC' 

Yakın zamanda PostgreSQL timestamp and time zone handling in a related answer'u açıkladım.

+0

hey Erwin, cevabı takdir ediyorum. Bunu deneyeceğim ama çözüm olarak bunu kullanmakta isteksiz hissettiren tek şey, eğer mysql veya sqlite'ye dönmek istersem, tüm bu şeyleri değiştirmek zorunda olmanın utanç verici olması. Model.where ('datetime BETWEEN? AND?', Time.now.beginning_of_day, Time.now.end_of_day) 'i arayabilme konusunda gerçekten güzel bir şey var. belki de hayal ediyorum, bu noktada çözümünüzün en zarif olup olmadığı net değil. – botbot

+0

@masterkrang: Ben hep kolaylık için. Ama doğruluk önce gelir ve sonraki performans. Veritabanını agnostik etme fikri, sorgularınızı pek de optimize edemeyeceğiniz için düşük performansa yol açar. Soyutlama katmanları temel SQL için iyidir - ancak bunlar çoğunlukla ilkel koltuk değnekleridir. Ayrıca, 'ARKADAŞLAR… VE ...' genellikle hafifçe * yanlış * sonuç verir. Her iki aralık sınırları dahil edilmiştir. 00: 00 'önceki ve sonraki gün için ortaya çıkıyor. Sorgumda bundan kaçınmaya çalışıyorum - ki şu an sahip olduğunuzdan çok daha karmaşıktır. Son olarak: zaman dilimleriyle bütün problem * bir yanlış anlaşılma olabilir. –