2010-10-29 13 views
17

जब उपयोगकर्ता नि: शुल्क परीक्षण के लिए मेरी साइटों में से किसी एक पर साइन अप करते हैं, तो मैंने अपनी खाता समाप्ति "14.days.from_now" निर्धारित की है। तो मुख पृष्ठ पर मैं दिखाने के कितने दिन वे शेष है, जो मैं के साथ मिलती है:रेल समय की विषमता: "x दिन से अब"

(user.trial_expires - Time.now)/86400 

अजीब बात (क्योंकि वहाँ एक दिन में 86400 सेकंड, यानी 60 * 60 * 24 कर रहे हैं) है, यह 14 से अधिक के रूप में आता है, इसलिए 15 तक गोल हो जाता है। कंसोल में नज़दीकी जांच पर यह भविष्य में केवल दो दिनों के लिए होता है (यदि आप जानते हैं कि मेरा क्या मतलब है)। जैसे

>> Time.now 
=> Fri Oct 29 11:09:26 0100 2010 
>> future_1_day = 1.day.from_now 
=> Sat, 30 Oct 2010 11:09:27 BST 01:00 
#ten past eleven tomorrow 

>> (future_1_day - Time.now)/86400 
=> 0.999782301526931 
#less than 1, what you'd expect right? 

>> future_2_day = 2.day.from_now 
=> Sun, 31 Oct 2010 11:09:52 GMT 00:00 
>> (future_2_day - Time.now)/86400 
=> 2.04162248861183 
#greater than 2 - why? 

मैं शायद सोचा था कि यह समय-क्षेत्रों के साथ क्या करना था - मैं देखा है कि अब से 1.day-समय BST और समय अब ​​से 2 दिन जीएमटी में था में था। तो, मैंने लोकलटाइम का उपयोग करने की कोशिश की और एक ही परिणाम मिला!

>> future_2_day = 2.day.from_now.localtime 
=> Sun Oct 31 11:11:24 0000 2010 
>> (future_2_day - Time.now)/86400 
=> 2.04160829127315 
>> (future_2_day - Time.now.localtime)/86400 
=> 2.04058651585648 

मैं तो सोचा कि बड़ा अंतर है, और यह पता चला है कि यह वास्तव में एक घंटे के बाहर है। तो ऐसा लगता है कि कुछ समय क्षेत्र अजीबता, या कम से कम कुछ समय क्षेत्र के साथ करना है जो मुझे समझ में नहीं आता है। वर्तमान में मेरा समय क्षेत्र बीएसटी (ब्रिटिश ग्रीष्मकालीन समय) है जो इस समय यूटीसी की तुलना में एक घंटे बाद (इस रविवार तक यह यूटीसी के समान हो जाता है)।

अतिरिक्त समय लगता है जब मैं समय में दो दिन जोड़ता हूं। अब: इसे देखें। मैं Time.now से शुरू करता हूं, इसमें दो दिन जोड़ें, समय घटाएं। अब, परिणाम से दो दिन के सेकंड घटाएं, और एक घंटे के साथ छोड़ दिया गया है।

यह सिर्फ घटित हुआ, एक सिर पल थप्पड़ मारने में, कि इसका कारण यह है घड़ियों रविवार की सुबह वापस जाने के लिए हो रहा है: अब से रविवार की सुबह 11.20 पर यानी यह दो दिन और एक अतिरिक्त घंटे हो जाएगा। मैं इस पोस्ट को हटाने के बारे में था, लेकिन फिर मैंने यह देखा: मैंने सोचा 'आह, मैं इसे (24 * दिनम) का उपयोग करके ठीक कर सकता हूं। Daynum.days के बजाय hours, लेकिन मुझे अभी भी एक ही परिणाम मिलता है: यहां तक ​​कि जब भी मैं सेकंड का उपयोग करता हूँ!

>> (Time.now + (2*24).hours - Time.now) - 86400*2 
=> 3599.99969500001 
>> (Time.now + (2*24*3600).seconds - Time.now) - 86400*2 
=> 3599.999855 

तो अब मैं फिर से उलझन में हूं। अब प्लस दो दिन के लायक कैसे हो सकते हैं, अब कम से कम, दो दिन के बराबर सेकेंड सेकेंड सेकेंड सेकेंड हो सकते हैं? अतिरिक्त घंटे कहाँ घुसपैठ करता है?

+0

एक घंटे अतिरिक्त शायद बचत दिन के प्रकाश हो सकता है? – willcodejavaforfood

+0

मैं आपके परिणामों को दोहराना नहीं कर सकता। मुझे '(future_2_day - time.now)/86400 # => 1.99977137731481' मिलता है। मैं ईएसटी (यूएस) में हूं, और हमारे घड़ियों इस समय के दौरान वापस नहीं जाते हैं। तो यह एक डीएसटी मुद्दा होना चाहिए। –

+0

डीएसटी सालाना दो बार गधे पर मुझे काटता है, हर साल। आपको लगता है कि मैं सीखूंगा। – DanSingerman

उत्तर

19

willcodejavaforfood ने टिप्पणी की है, यह डेलाइट सेविंग टाइम के कारण है जो इस सप्ताह के अंत में समाप्त होता है।

एक अवधि जोड़ते समय ActiveSupport में कुछ कोड होता है ताकि प्रारंभिक समय डीएसटी में हो और परिणामी समय (या इसके विपरीत) न हो।

def since(seconds) 
    f = seconds.since(self) 
    if ActiveSupport::Duration === seconds 
    f 
    else 
    initial_dst = self.dst? ? 1 : 0 
    final_dst = f.dst? ? 1 : 0 
    (seconds.abs >= 86400 && initial_dst != final_dst) ? f + (initial_dst - final_dst).hours : f 
    end 
rescue 
    self.to_datetime.since(seconds) 
end 

आप 11:09:27 है और आप अभी भी जिसके परिणामस्वरूप दिन भले ही डीएसटी बदल गया है पर 11:09:27 मिल जाएगा दिनों की संख्या जोड़ दें। जब आप सेकंड में गणना करने के लिए आते हैं तो इसका परिणाम अतिरिक्त घंटे में होता है।

विचारों के एक जोड़े:

  • उपयोगकर्ता कब तक अपने परीक्षण में छोड़ दिया है का एक संकेत देने के लिए distance_of_time_in_words सहायक विधि का उपयोग करें।
  • 14.days.from_now का उपयोग करने के बजाय Time.now + (14 * 86400) के रूप में समाप्ति की गणना करें - लेकिन कुछ उपयोगकर्ता दावा कर सकते हैं कि उन्होंने अपने परीक्षण का एक घंटे खो दिया है।
  • वास्तविक साइनअप समय के बावजूद समाप्ति दिन पर 23:59:59 बजे समाप्त होने के परीक्षणों को सेट करें।
+1

आह, यह बहुत अच्छा है, धन्यवाद माइक। मुझे पता था कि ऐसा कुछ होना था। मैंने सेकंड का उपयोग करके समाप्ति समय निर्धारित करने का प्रयास किया (मेरी पोस्ट का अंत देखें) लेकिन एक ही परिणाम मिला। साथ ही, जब मैं distance_of_time_in_words को आज़माता हूं तो मुझे एक त्रुटि मिलती है: "TypeError: ActiveSupport :: TimeWithZone को Fixnum में शामिल नहीं किया जा सकता है"। time_ago_in_words ठीक काम करता है। –

+0

आप 'distance_of_time_in_words' पर कौन से पैरामीटर पास कर रहे थे? 'time_ago_in_words'' time_now_time_in_words' के आस-पास एक पैरामीटर है जो दूसरे पैरामीटर को 'टाइम.now' पर सेट किया गया है यानी यह 'distance_of_time_in_words (from_time, Time.now, include_seconds)' – mikej

+1

यह एक बग नहीं है, यह एक सुविधा है। सुविधा की अपनी परिभाषा के आधार पर। – Kelvin

8

आप Date कक्षा का उपयोग आज और समाप्ति तिथि के बीच की दिनों की गणना करने के लिए कर सकते हैं।

expire_date = Date.new(user.trial_expires.year, user.trial_expires.month, user.trial_expires.day) 
days_until_expiration = (expire_date - Date.today).to_i 
+0

अच्छा विचार, धन्यवाद जोनास –

+3

'आज = दिनांक। नया (अब.यायर, अब। सोमवार, अब। दिन)' को आज 'दिनांक = दिनांक' के लिए सरल बनाया जा सकता है। –

5

उपयोग since, उदाहरण: 14.days.since.to_date

संबंधित मुद्दे