2011-10-26 49 views
17

Tôi có một Chuỗi mà tôi phân tích cú pháp với DateTime.strptime. Múi giờ của ngày trong chuỗi là CET nhưng Ruby tạo ra một đối tượng UTC DateTime mà tất nhiên có một bù đắp của 2hrs.Thời gian chạy bằng múi giờ

Hiện tại tôi đang giải quyết vấn đề với DateTime.strptime().change(:offset => "+0020") nhưng tôi khá chắc chắn đây không phải là cách hoạt động.

Ai đó có thể khai sáng cho tôi đúng cách để thực hiện việc này không?

+0

nếu bạn ở quốc gia có múi giờ CEST/CET, khoản bù đắp cố định sẽ không hoạt động. Cũng quan tâm đến điều này, tôi không thấy làm thế nào làm cho phân tích strptime cho múi giờ hiện tại (nhưng không phải là giá trị ngay bây giờ, một trong những quyền tùy thuộc vào chuỗi phân tích cú pháp). – tokland

Trả lời

-1

tôi không thể xóa một câu trả lời chấp nhận

Như @LeeJarvis chỉ ra trong phần bình luận dưới đây, Chronic.parse không chấp nhận một lựa chọn :time_class. Vì vậy, câu trả lời này là lỗi và trong khi có vẻ như nó hoạt động, nó không (trừ trường hợp mãn tính cho phép đi qua một tùy chọn :time_class sớm.)


Các viên ngọc mãn tính là thật sự mạnh mẽ.

tôi sử dụng nó như thế này:

Chronic.parse("next 5:00 pm", 
:time_class => ActiveSupport::TimeZone.new(User.first.time_zone)).utc 

Trong ví dụ của tôi ở trên, User.first.time_zone là "Thái Bình Dương (Mỹ & Canada)".

mãn tính hỗ trợ rất nhiều định dạng để kiểm tra xem nó ra tại https://github.com/mojombo/chronic

Hãy chắc chắn để vượt qua các tùy chọn :time_class và chuyển đổi sang UTC (trong tài liệu, bộ Chronic :time_class trước khi gọi phân tích cú pháp. Tôi tránh phương pháp này vì nó có thể gây ra các bộ phận khác trên ứng dụng không làm việc)

tài liệu TimeZone là tại http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html

+0

Câu trả lời này không chính xác. 'parse()' không có tùy chọn 'time_class'. Nó được đặt trực tiếp trên lớp 'Chronic'. Điều này cuối cùng sẽ thay đổi trong các phiên bản tương lai của Chronic, mặc dù –

+0

Không tốt ... Tôi sẽ xóa cho đến khi tùy chọn này khả dụng =) – Abdo

+0

Erm ... Tôi không thể xóa câu trả lời được chấp nhận. Tôi sẽ bình luận ở trên. – Abdo

9

tôi sử dụng nó theo cách sau:

ruby-1.9.2-head :001 > require 'date' 
=> true 
ruby-1.9.2-head :002 > fmt = "%m-%d-%Y %H:%M:%S %Z" 
=> "%m-%d-%Y %H:%M:%S %Z" 
ruby-1.9.2-head :003 > DateTime.strptime "10-26-2011 10:16:29 CET", fmt 
=> #<DateTime: 2011-10-26T10:16:29+01:00 (212186380589/86400,1/24,2299161)> 
ruby-1.9.2-head :004 > DateTime.strptime "10-26-2011 10:16:29 UTC", fmt 
=> #<DateTime: 2011-10-26T10:16:29+00:00 (212186384189/86400,0/1,2299161)> 
ruby-1.9.2-head :005 > DateTime.strptime "10-26-2011 10:16:29 PST", fmt 
=> #<DateTime: 2011-10-26T10:16:29-08:00 (212186412989/86400,-1/3,2299161)> 

Có gì bạn nghĩa là gì?

+2

tôi không có một chuỗi xác định múi giờ trong chuỗi phân tích cú pháp của tôi. của nó 10-26-2011 10:16:29 thay vì "10-26-2011 10:16:29 CET" – Nicolas

+0

Bạn giải quyết vấn đề của tôi, tôi chỉ có thể "09-19-2012 11:08:44" + " CST "'. Tôi nghĩ rằng bạn là câu trả lời đúng. – mwoods79

+0

Điều gì sẽ xảy ra khi bạn di chuyển vào thời gian tiết kiệm ánh sáng ban ngày? Không nên + "CST" này được thông tin nhiều hơn? Theo nhận xét ở trên, sẽ rất tuyệt nếu chúng tôi có thể chọn dựa trên thời gian vừa được định dạng ... tôi đang học cách ghét múi giờ. –

0

Bạn có thể chuyển đổi ngày múi giờ với to_time_in_current_zone. Ví dụ:

Date.strptime('04/07/1988', '%m/%d/%Y').to_time_in_current_zone 
+3

Phương thức http://apidock.com/rails/Date/to_time_in_current_zone được khấu hao xin lỗi: ( – Brandt

1

tôi đã "strptiming" chuỗi này:

19/05/2014 8:13:26 a.m. 

Một dấu thời gian địa phương, đó là trong trường hợp của tôi là Auckland New Zealand không có con dấu múi giờ trong chuỗi như có thể được nhìn thấy.

Tốt nhất tôi có thể yêu cầu Time.strptime sử dụng múi giờ máy chủ làm cơ sở.

Trong trường hợp của tôi, và thực hành tốt nói chung, các máy chủ của tôi chạy trong múi giờ UTC như vậy mỗi phân tích cú pháp của chuỗi kết thúc việc tạo một đối tượng thời gian, thời gian để 0000 (UTC):

2014-05-19 08:13:26 +0000 

Sau đó chuyển đổi đến cho:

Mon, 19 May 2014 20:13:26 NZST +12:00 

Có thể xem 12 giờ (chênh lệch UTC) sau thời gian thực tế tôi muốn.

Tôi đã cố gắng sử dụng thủ thuật +' Auckland', '...%Z' như trên mà không có bất kỳ thay đổi nào. Sau đó tôi đã sử dụng thủ thuật + '+1200', '...%Z' như trên mà đã hoạt động chính xác.

Tuy nhiên tôi rất lo lắng về thời gian mùa hè, sau đó các phân tích cú pháp sẽ được ra bởi một tiếng đồng hồ, vì vậy đây là những gì tôi đã finshed với:

Time.strptime(call_data[:datetime].gsub(/\./, "").gsub(/am/, "AM").gsub(/pm/, "PM") + (Time.zone.now.time_zone.utc_offset/3600).to_s.ljust(4,'0').rjust(6,' +'), '%d/%m/%Y %I:%M:%S %p %Z').in_time_zone(Time.zone) 

Kết quả:

Mon, 19 May 2014 08:13:26 NZST +12:00 

Nó không đặc biệt thanh lịch nhưng nó hoạt động.

0

Tôi đã chiến đấu cùng một vấn đề này đang cố phân tích chuỗi ngày tháng khỏi biểu mẫu và lưu nó độc lập với thời gian của máy chủ. Quá trình tôi đã theo sau là như vậy. Tôi đảm bảo rằng các múi giờ RoR và Ruby được đặt thành UTC. Nó làm cho nó dễ dàng hơn nếu máy chủ là trên UTC thời gian là tốt.

Tôi đang lưu trữ cho người dùng miền địa phương bằng cách sử dụng ActiveSupport: Định dạng TimeZone như US/Eastern Tôi có một chức năng ngày giải thích mà có thể giải thích cho một chuỗi ngày mà không natively chứa một múi giờ hoặc bù đắp

# date_str looks something like this `12/31/2014 6:22 PM` 
# tz is a string containing an ActiveSupport::TimeZone name like `US/Eastern` 
def interpret_date(date_str, tz) 
    Time.use_zone tz do 
    parsed_dt = DateTime.strptime(date_str, '%m/%d/%Y %H:%M %p') 
    offset = parsed_dt.in_time_zone(tz).utc_offset 
    parsed_dt.advance(seconds: -(offset)).in_time_zone(tz) 
    end 
end 

này tất nhiên không cảm thấy như một giải pháp hoàn hảo nhưng nó hoạt động. Các bước để đảm bảo các múi giờ đúng là:

  1. Phân tích chuỗi ngày theo định dạng của chúng tôi
  2. Giải nén utc hiện bù đắp dựa trên thời gian trong múi giờ đó (Chúng ta phải làm điều này nếu ngày bạn phân tích cú pháp xảy ra ở dst trong khi giờ địa phương của bạn không phải là dst cho thời gian phía đông, điều này sẽ đảm bảo rằng dst là cục bộ trong thời gian được phân tích)
  3. Chuyển đổi thời gian sang ngôn ngữ mục tiêu của chúng tôi và cho phép thời gian thay đổi
1

Ít nhất một s của Rails 4.2 (có thể trước đó, đã không kiểm tra) miễn là bạn sử dụng Time#strptime thay vì DateTime.strptime, múi giờ hiện tại được tự động áp dụng:

> DateTime.strptime('12/28/2016 5:00 PM', '%m/%d/%Y %H:%M %p') 
=> Wed, 28 Dec 2016 17:00:00 +0000 

> Time.strptime('12/28/2016 5:00 PM', '%m/%d/%Y %H:%M %p') 
=> 2016-12-28 17:00:00 -0800 
3

này hoạt động trong Rails 5:

Time.zone.strptime("2017-05-20 18:20:10", "%Y-%m-%d %H:%M:%S") 

Trả về thời gian trong múi giờ đã chỉ định.

Các vấn đề liên quan