2010-03-25 7 views
5

में परिवर्तित करने के लिए मुझे किसी दिनांक वस्तु को उस समय की शुरुआत का प्रतिनिधित्व करने वाले टाइमविथज़ोन ऑब्जेक्ट में कनवर्ट करना होगा।दिनांक ऑब्जेक्ट को टाइमविथज़ोन

निम्नलिखित दृष्टिकोण काम करता है, लेकिन बहुत जटिल लगता है के रूप में यह मेरे की आवश्यकता है एक स्ट्रिंग के लिए तिथि परिवर्तित करने के लिए:

?> date = Date.parse("2010-02-17") 
=> Wed, 17 Feb 2010 
>> ActiveSupport::TimeZone['Eastern Time (US & Canada)'].parse(date.to_s) 
=> Wed, 17 Feb 2010 00:00:00 EST -05:00 
>> ActiveSupport::TimeZone['UTC'].parse(date.to_s) 
=> Wed, 17 Feb 2010 00:00:00 UTC 00:00 

वहाँ एक बेहतर तरीका है मैं याद कर रहा हूँ है?

संपादित करें: के लोग सुझाव दे रहे हैं विविधताओं:

?> date.to_datetime.in_time_zone('Eastern Time (US & Canada)').beginning_of_day 
=> Tue, 16 Feb 2010 00:00:00 EST -05:00 

आप देख सकते हैं, इस एक बराबर रूपांतरण के बाद से यह मेरे फ़रवरी 16 वीं ईएसटी के शुरू में छोड़ देता है, की शुरुआत के बजाय नहीं है फरवरी 17 वीं ईएसटी।

+0

ऐसा लगता है कि अपने समाधान की तरह जाने के लिए सही तरीका हो सकता है। –

+0

मैंने इस मुद्दे को दूर करने के लिए अपनी प्रतिक्रिया संपादित की है। –

+0

अपने आप को समाधान दें! =) समय क्षेत्र के साथ समय हमेशा गन्दा है। – John

उत्तर

0

क्या आपके लिए यह काम अच्छा लगेगा?

'2010-04-01'.to_time.in_time_zone('Eastern Time (US & Canada)').beginning_of_day 
+0

इस प्रश्न में मेरा संपादन देखें कि यह क्यों काम नहीं करता – avaynshtok

0

घटाना utc_offset:

d = Date.today 
Time.zone.class.all.map(&:name).map { |tz| dt = d.to_datetime.in_time_zone(tz); dt -= dt.utc_offset } 

ActiveSupport :: समय क्षेत्र [TZ] का उपयोग करते हुए खाते में डेलाइट बचत समय ले नहीं करता है।

Time.zone.class.all.map(&:name).map { |tz| o = d.to_datetime.in_time_zone(tz).utc_offset - ActiveSupport::TimeZone[tz].utc_offset } 
4

आप रेल में Time.zone सेट है तो आप Date#at_beginning_of_day कॉल कर सकते हैं (http://api.rubyonrails.org/classes/Date.html#method-i-at_beginning_of_day देखें)। Date#to_datetime के साथ इस कंट्रास्ट:

Time.zone 
=> #<ActiveSupport::TimeZone:0x10cf10858 @tzinfo=#<TZInfo::TimezoneProxy: Etc/UTC>, @utc_offset=nil, @current_period=nil, @name="UTC"> 

date = Date.today 
=> Thu, 31 May 2012 

date.to_datetime 
=> Thu, 31 May 2012 00:00:00 +0000 

date.at_beginning_of_day 
=> Thu, 31 May 2012 00:00:00 UTC +00:00 

Time.zone = 'America/Chicago' 
=> "America/Chicago" 

date.to_datetime 
=> Thu, 31 May 2012 00:00:00 +0000 

date.at_beginning_of_day 
=> Thu, 31 May 2012 00:00:00 CDT -05:00 
+2

'Time.zone' ** ** थ्रेडसेफ है, यह ज़ोन को 'थ्रेड.current [: time_zone]' में सेट करता है। [स्रोत] (https://github.com/rails/rails/blob/08754f12e65a9ec79633a605e986d0f1ffa4b251/activesupport/lib/active_support/core_ext/time/zones.rb#L39) –

+1

सुधार के लिए धन्यवाद, मैंने उस टिप्पणी को हटा दिया, लेकिन इसे छोड़ दिया एक तो लोग नहीं सोचते कि आप पागल हैं;) – gtd

2

मैं दृढ़ता से किसी भी समाधान है कि एक समय के लिए तारीख धर्मान्तरित to_datetime या to_time का उपयोग कर, क्योंकि उन तरीकों क्षेत्र से अनजान हैं के खिलाफ सलाह देते हैं, और in_time_zone परिणाम पर टैकिंग, जैसा कि कुछ जवाब सुझाव देते हैं, गलती को पीछे हटाना नहीं होगा। साथ ही, यूटीसी ऑफ़सेट का उपयोग करके अपना खुद का डेलाइट सेविंग टाइम गणित बनाने की कोशिश न करें। आप इसे गलत समझने के लिए बाध्य हैं, और आप अनावश्यक रूप से काम कर रहे हैं। ।

उपयोग समयक्षेत्र ही जो इस तर्क है में बनाया

एक क्षेत्र और एक तिथि को देखते हुए, आप इस तरह दिन की शुरुआत के लिए एक TimeWithZone प्राप्त कर सकते हैं:

time = zone.local(date.year, date.month, date.day) 

हैं आप शुरुआत के अलावा किसी अन्य दिन का विशिष्ट समय चाहते हैं, आप 4, 5 वें और 6 वें तर्क #local पर घंटे, मिनट और दूसरा पास कर सकते हैं।

तो zone वास्तव में आपके सिस्टम के स्थानीय समय क्षेत्र (Time.zone) है, तो ActiveSupport आप इस के लिए ऊपर छोटा करने देगा:

time = date.to_time_in_current_zone 

ऊपर संभाल डेलाइट समय सही ढंग से बचत के सभी। के दो बार, एक डीएसटी के बाहर के किसी और एक डीएसटी के भीतर है कि के लिए यूटीसी ऑफसेट को देखकर कि सत्यापित करें:

irb(main):009:0> zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)'] 
=> (GMT-05:00) Eastern Time (US & Canada) 
irb(main):010:0> t1 = zone.local(2013, 1, 1) 
=> Tue, 01 Jan 2013 00:00:00 EST -05:00 
irb(main):011:0> t2 = zone.local(2013, 5, 1) 
=> Wed, 01 May 2013 00:00:00 EDT -04:00 
irb(main):012:0> t1.utc_offset 
=> -18000 
irb(main):013:0> t2.utc_offset 
=> -14400 
+0

मेरा जवाब हटा दिया और अपना ऊपर उठाया। –

5

मैं पार्टी के लिए देर हो रही है, लेकिन यह अभी भी एक बड़ा सवाल है। ActiveSupport की in_time_zone ओ.पी. के बाद पेश की गई थी, लेकिन यह एक स्ट्रिंग (धीमी) या सेटिंग समय को पार्स किए बिना बिल्कुल वही करता है।क्षेत्र (जोखिम भरा):

>> date = Date.parse("2010-02-17") 
=> Wed, 17 Feb 2010 
>> date.in_time_zone('Eastern Time (US & Canada)') 
=> Wed, 17 Feb 2010 00:00:00 EST -05:00 
बेशक

आप यूटीसी पर व्यक्त दिन की शुरुआत करना चाहते हैं, आप ऐसा कर सकते हैं:

>> date.in_time_zone('Eastern Time (US & Canada)').utc 
=> 2010-02-17 05:00:00 UTC 
संबंधित मुद्दे