Chuyển đổi UTC sang giờ địa phương trong Rails 3


95

Tôi đang gặp sự cố khi chuyển đổi UTC Timehoặc giờ TimeWithZoneđịa phương trong Rails 3.

Giả sử momentlà một số Timebiến trong UTC (ví dụ moment = Time.now.utc:). Làm cách nào để chuyển đổi momentsang múi giờ của tôi, quan tâm đến DST (tức là sử dụng EST / EDT)?

Chính xác hơn, tôi muốn in ra "Thứ Hai ngày 14 tháng 3, 9 giờ sáng" nếu thời gian tương ứng với 9 giờ sáng nay theo giờ EDT và "Thứ Hai, ngày 7 tháng 3, 9 giờ sáng" nếu thời gian là 9 giờ sáng theo giờ EST vào thứ hai tuần trước.

Hy vọng rằng có một cách khác?

Chỉnh sửa : Đầu tiên, tôi nghĩ rằng "EDT" phải là múi giờ được công nhận, nhưng "EDT" không phải là múi giờ thực tế, giống như trạng thái của múi giờ hơn. Ví dụ, nó sẽ không có ý nghĩa gì khi yêu cầu Time.utc(2011,1,1).in_time_zone("EDT"). Có một chút khó hiểu, vì "EST" múi giờ thực tế, được sử dụng ở một số nơi không sử dụng giờ tiết kiệm Ánh sáng ban ngày và (UTC-5) kéo dài hàng năm.

Câu trả lời:


113

Rails có tên riêng của nó. Xem chúng với:

rake time:zones:us

Bạn cũng có thể chạy rake time:zones:allcho tất cả các múi giờ. Để xem thêm các nhiệm vụ cào liên quan đến vùng:rake -D time

Vì vậy, để chuyển đổi sang EST, tự động phục vụ cho DST:

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

21
Làm cách nào bạn có thể tự động sử dụng múi giờ cho người dùng truy cập ứng dụng web?
dmonopoly

Cách duy nhất tôi tìm thấy là sử dụng Javascript và sau đó chuyển nó trở lại máy chủ. (new Date()).getTimeZoneOffset(). Nhưng nó khá mâu thuẫn, vì vậy anh chàng này dường như đã viết của riêng mình: onlineaspect.com/2007/06/08/…
Duke

2
tự động thêm múi giờ vào tất cả các ngày giờ ActiveRecord - config.time_zone = 'Giờ miền Đông (Hoa Kỳ & Canada)' - trong config / application.rb
idrinkpabst

Cập nhật: chủ sở hữu của giải pháp JS được liên kết trỏ đến giải pháp mới hơn: pellepim.bitbucket.org/jstz
Miles

@dmonopoly, bạn có thể đặt múi giờ trong cấu hình ứng dụng config.time_zone = 'Wellington'và sau đó sử dụng Time.current (tương đương với time.now nhưng đã sử dụng Múi giờ mà bạn đã đặt)
Sean

114

Time#localtime sẽ cung cấp cho bạn thời gian ở múi giờ hiện tại của máy chạy mã:

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

Cập nhật: Nếu bạn muốn chuyển đổi sang múi giờ cụ thể thay vì múi giờ của riêng mình, bạn đang đi đúng hướng. Tuy nhiên, thay vì lo lắng về EST vs EDT, chỉ cần vượt qua múi giờ miền Đông chung - nó sẽ biết dựa trên ngày đó là EDT hay 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 

Đó là một sự khởi đầu. Làm cách nào để tôi có thể đặt múi giờ hiện tại (vì tôi thậm chí không chắc nơi ứng dụng sẽ được lưu trữ, máy chủ có thể ở múi giờ khác thì nên sử dụng múi giờ nào).
Marc-André La xui xẻo

6
Phương pháp "localtime" rất tuyệt, nhưng múi giờ của máy chạy mã không hữu ích bằng múi giờ của người dùng truy cập ứng dụng web. (Như đã đề cập ở đây: stackoverflow.com/questions/6003491/rails-3-user-timezones/… ) Làm cách nào để bạn có thể lấy múi giờ cho người dùng truy cập ứng dụng web?
dmonopoly

@daze Tôi tưởng tượng bạn có thể thiết lập một tùy chọn để người dùng của bạn chọn múi giờ của họ, sau đó sử dụng in_time_zonephương pháp với múi giờ của họ.
Dylan Markow

1
Cảm ơn, phương pháp localtime là chính xác những gì tôi cần.
Bob

Time.now.localtimehoạt động trên một phiên irb bình thường nhưng khi tôi cố gắng chạy nó trên một máy ở múi giờ UTC, nó không hoạt động.
Ava

15

Thật dễ dàng để cấu hình nó bằng cách sử dụng vùng cục bộ hệ thống của bạn, Chỉ cần trong ứng dụng của bạn. Rb thêm cái này

config.time_zone = Time.now.zone

Sau đó, đường ray sẽ hiển thị cho bạn dấu thời gian theo giờ địa phương của bạn hoặc bạn có thể sử dụng một cái gì đó như hướng dẫn này để lấy giờ địa phương

Post.created_at.localtime

15

Thực sự có một Gem tốt được gọi local_timebởi basecamp để làm tất cả những điều đó chỉ ở phía khách hàng, tôi tin rằng:

https://github.com/basecamp/local_time


Điều này hoạt động tốt nhất. Chúng tôi biết thời gian đã được lưu trữ, cách hiển thị nó ở định dạng cho người dùng tốt nhất được thực hiện ở phía khách hàng theo ý kiến ​​của tôi và điều này làm được.
Neeraj Shukla,

1

Không biết tại sao nhưng trong trường hợp của tôi, nó không hoạt động theo cách được đề xuất trước đó. Nhưng nó hoạt động như thế này:

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

Tất nhiên bạn cần phải thay đổi offsetgiá trị của bạn.


0

Nếu bạn thực sự làm điều đó chỉ vì bạn muốn lấy múi giờ của người dùng thì tất cả những gì bạn phải làm là thay đổi múi giờ của bạn config/applications.rb .

Như thế này:

Rails, theo mặc định, sẽ lưu bản ghi thời gian của bạn theo UTC ngay cả khi bạn chỉ định múi giờ hiện tại.

config.time_zone = "Singapore"

Vì vậy, đây là tất cả những gì bạn phải làm và bạn đã sẵn sàng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.