แปลง UTC เป็นเวลาท้องถิ่นใน Rails 3


96

ฉันมีปัญหาในการแปลง UTC TimeหรือTimeWithZoneเวลาท้องถิ่นใน Rails 3

บอกว่าmomentเป็นTimeตัวแปรบางตัวใน UTC (เช่นmoment = Time.now.utc) ฉันจะแปลงmomentเป็นเขตเวลาของฉันโดยดูแล DST ได้อย่างไร (เช่นใช้ EST / EDT)

อย่างแม่นยำยิ่งขึ้นฉันต้องการพิมพ์ "วันจันทร์ที่ 14 มีนาคม 9.00 น." หากเวลาตรงกับเช้าวันนี้ 9.00 น. EDT และ "วันจันทร์ที่ 7 มีนาคม 9.00 น." หากเวลาคือ 9.00 น. EST ของวันจันทร์ที่ผ่านมา

หวังว่าจะมีวิธีอื่น?

แก้ไข : ก่อนอื่นฉันคิดว่า "EDT" ควรเป็นเขตเวลาที่รู้จัก แต่ "EDT" ไม่ใช่เขตเวลาจริงคล้ายกับสถานะของเขตเวลามากกว่า ยกตัวอย่างเช่นมันจะไม่ทำให้รู้สึกใด ๆ Time.utc(2011,1,1).in_time_zone("EDT")ที่จะขอ เป็นเรื่องที่น่าสับสนเล็กน้อยเนื่องจาก "EST" เป็นเขตเวลาจริงซึ่งใช้ในสถานที่บางแห่งที่ไม่ใช้เวลาออมแสงและเป็น (UTC-5) ตลอดปี

คำตอบ:


113

Rails มีชื่อของตัวเอง ดูพวกเขาด้วย:

rake time:zones:us

คุณยังสามารถเรียกใช้rake time:zones:allสำหรับโซนเวลาทั้งหมด หากต้องการดูงานคราดที่เกี่ยวข้องกับโซนเพิ่มเติม:rake -D time

ดังนั้นในการแปลงเป็น EST ให้จัดเตรียม DST โดยอัตโนมัติ:

Time.now.in_time_zone("Eastern Time (US & Canada)")

21
คุณจะใช้เขตเวลาโดยอัตโนมัติสำหรับผู้ใช้ที่เข้าถึงเว็บแอปได้อย่างไร
dmonopoly

วิธีเดียวที่ฉันพบคือใช้ Javascript แล้วส่งกลับไปที่เซิร์ฟเวอร์ (new Date()).getTimeZoneOffset(). แต่มันค่อนข้างไม่สอดคล้องกันดังนั้นดูเหมือนว่าผู้ชายคนนี้จะเขียนของเขาเอง: onlineaspect.com/2007/06/08/…
Duke

2
เพิ่มเขตเวลาให้กับวันที่ ActiveRecord ทั้งหมดโดยอัตโนมัติ - config.time_zone = 'เวลาตะวันออก (สหรัฐอเมริกาและแคนาดา)' - ใน config / application.rb
idrinkpabst

อัปเดต: เจ้าของโซลูชัน JS ที่เชื่อมโยงชี้ไปที่โซลูชันใหม่กว่า: pellepim.bitbucket.org/jstz
Miles

@dmonopoly คุณสามารถกำหนดเขตเวลาในการกำหนดค่าแอปพลิเคชันconfig.time_zone = 'Wellington'จากนั้นใช้ Time.current (ซึ่งเทียบเท่ากับ time.now แต่ใช้เขตเวลาที่คุณตั้งไว้)
ฌอน

117

Time#localtime จะให้เวลาในเขตเวลาปัจจุบันของเครื่องที่ใช้รหัส:

> moment = Time.now.utc
  => 2011-03-14 15:15:58 UTC 
> moment.localtime
  => 2011-03-14 08:15:58 -0700 

อัปเดต: หากคุณต้องการบรรจบกับเขตเวลาเฉพาะแทนที่จะเป็นเขตเวลาของคุณเองแสดงว่าคุณมาถูกทางแล้ว อย่างไรก็ตามแทนที่จะกังวลเกี่ยวกับ EST กับ EDT เพียงแค่ส่งผ่านในเขตเวลาตะวันออกทั่วไป - มันจะรู้ตามวันไม่ว่าจะเป็น EDT หรือ EST:

> Time.now.utc.in_time_zone("Eastern Time (US & Canada)")
  => Mon, 14 Mar 2011 11:21:05 EDT -04:00 
> (Time.now.utc + 10.months).in_time_zone("Eastern Time (US & Canada)")
  => Sat, 14 Jan 2012 10:21:18 EST -05:00 

นั่นคือจุดเริ่มต้น ฉันจะกำหนดเขตเวลาปัจจุบันได้อย่างไร (เนื่องจากฉันไม่แน่ใจด้วยซ้ำว่าจะโฮสต์แอปไว้ที่ใดเซิร์ฟเวอร์อาจอยู่ในเขตเวลาอื่นแล้วควรใช้อะไร)
Marc-André Lafortune

6
วิธี "localtime" นั้นยอดเยี่ยม แต่เขตเวลาของเครื่องที่เรียกใช้รหัสนั้นไม่เป็นประโยชน์เท่ากับเขตเวลาของผู้ใช้ที่เข้าถึงเว็บแอป (ตามที่กล่าวไว้ที่นี่: stackoverflow.com/questions/6003491/rails-3-user-timezones/… ) คุณจะได้รับเขตเวลาสำหรับผู้ใช้ที่เข้าถึงเว็บแอปได้อย่างไร?
dmonopoly

@daze ฉันคิดว่าคุณสามารถตั้งค่าตัวเลือกให้ผู้ใช้ของคุณเลือกเขตเวลาจากนั้นใช้in_time_zoneวิธีการนี้กับเขตเวลาของพวกเขา
Dylan Markow

1
ขอบคุณวิธี localtime คือสิ่งที่ฉันต้องการ
Bob

Time.now.localtimeทำงานในเซสชัน irb ปกติ แต่เมื่อฉันพยายามเรียกใช้บนเครื่องที่อยู่ในเขตเวลา UTC มันไม่ทำงาน
อวา

15

ง่ายต่อการกำหนดค่าโดยใช้โซนภายในระบบของคุณเพียงแค่ใน application.rb เพิ่มสิ่งนี้

config.time_zone = Time.now.zone

จากนั้นรางควรแสดงการประทับเวลาในเวลาท้องถิ่นของคุณหรือคุณสามารถใช้คำสั่งเช่นนี้เพื่อรับเวลาท้องถิ่น

Post.created_at.localtime

15

จริงๆแล้วมีอัญมณีที่ดีที่เรียกlocal_timeโดย basecamp เพื่อทำทุกอย่างในฝั่งไคลเอ็นต์เท่านั้นฉันเชื่อว่า:

https://github.com/basecamp/local_time


วิธีนี้ได้ผลดีที่สุด เราทราบเวลาที่จัดเก็บไว้แล้ววิธีแสดงในรูปแบบต่อผู้ใช้นั้นทำได้ดีที่สุดในฝั่งไคลเอ็นต์ในความคิดของฉันและสิ่งนี้ก็ทำได้
Neeraj Shukla

1

ไม่รู้ว่าทำไม แต่ในกรณีของฉันมันไม่ได้ผลตามที่แนะนำไว้ก่อนหน้านี้ แต่ใช้งานได้ดังนี้:

Time.now.change(offset: "-3000")

แน่นอนคุณต้องเปลี่ยนoffsetมูลค่าเป็นของคุณ


0

หากคุณทำจริงเพียงเพราะต้องการได้เขตเวลาของผู้ใช้สิ่งที่คุณต้องทำคือเปลี่ยนเขตเวลาในตัวคุณ config/applications.rbหากคุณกำลังทำจริงมันเพียงเพราะคุณต้องการที่จะได้รับเขตเวลาของผู้ใช้แล้วสิ่งที่คุณต้องทำคือการเปลี่ยนเขตเวลาของคุณในตัวคุณ

แบบนี้:

ตามค่าเริ่มต้น Rails จะบันทึกบันทึกเวลาของคุณเป็น UTC แม้ว่าคุณจะระบุเขตเวลาปัจจุบันก็ตาม

config.time_zone = "Singapore"

นี่คือทั้งหมดที่คุณต้องทำและคุณก็พร้อมแล้ว

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.