2013-01-01 17 views
25

में डेटटाइम का मिलीसेकंद रिज़ॉल्यूशन मेरे पास 2012-01-01T01:02:03.456 जैसी स्ट्रिंग है जो मैं ActiveRecord का उपयोग कर पोस्टग्रेस डेटाबेस TIMESTAMP में संग्रहीत कर रहा हूं।रूबी

दुर्भाग्य से, रूबी मिलीसेकेंड बंद काटना लगता है:

ruby-1.9.3-rc1 :078 > '2012-12-31T01:01:01.232323+3'.to_datetime 
=> Mon, 31 Dec 2012 01:01:01 +0300 

Postgrs माइक्रोसेकंड संकल्प का समर्थन करता है। मैं अपना टाइमस्टैम्प तदनुसार सहेजने के लिए कैसे प्राप्त कर सकता हूं? मुझे कम से कम मिलीसेकंद संकल्प की आवश्यकता है।

(पी एस हाँ मैं postgres में एक मिलीसेकेंड पूर्णांक स्तंभ में हैक कर सकता है; हार ActiveRecord का पूरा उद्देश्य उस तरह।)

अद्यतन:
बहुत मददगार प्रतिक्रियाओं से पता चला है रूबी के DateTimeनहीं है कि मिलीसेकंड बंद करना; #to_f का उपयोग करके यह दिखाता है। लेकिन, कर रहा है:

m.happened_at = '2012-01-01T00:00:00.32323'.to_datetime 
m.save! 
m.reload 
m.happened_at.to_f 

मिलीसेकंड छोड़ देता है।

अब दिलचस्प बात यह है कि created_at रेल और पोस्टग्रेस दोनों में मिलीसेकंड दिखाता है। लेकिन अन्य टाइमस्टैम्प फ़ील्ड (जैसे happened_at ऊपर) नहीं। (संभवतः created_at के लिए रेल्स NOW() फ़ंक्शन का उपयोग करता है क्योंकि डेटटाइम में गुजरने के विपरीत)।

जो मेरे अंतिम प्रश्न की ओर जाता है:
टाइमस्टैम्प फ़ील्ड पर मिलीसेकंद रिज़ॉल्यूशन को संरक्षित करने के लिए मैं ActiveRecord कैसे प्राप्त कर सकता हूं?

उत्तर

7

m.happened_at = '2012-01-01T00:00:00.32323'.to_datetimem.happened_at = '2012-01-01T00:00:00.32323' से ऊपर दिए गए कोड में समस्या हल करती है, हालांकि मुझे कोई जानकारी नहीं है।

+1

पुष्टि की, इसे डेटाटाइम के बजाए स्ट्रिंग के रूप में सहेजना आंशिक सेकंड को संरक्षित करता है। –

+7

ध्यान दें कि 'DateTime.now.to_s' आंशिक सेकंड वापस नहीं करता है। मैंने 'DateTime.now.iso8601 (6) 'का उपयोग किया। –

+2

यह मुद्दा पागल है, मैंने अभी इस पर दो घंटे खो दिए हैं। उत्तर के लिए Thx। – sidney

1

to_datetime डेटा की मिलीसेकंड संकल्प को नष्ट नहीं करता है - यह बस क्योंकि DateTime#to_s यह प्रदर्शित नहीं करता है छिपा हुआ है।

[1] pry(main)> '2012-12-31T01:01:01.232323+3'.to_datetime 
=> Mon, 31 Dec 2012 01:01:01 +0300 
[2] pry(main)> '2012-12-31T01:01:01.232323+3'.to_datetime.to_f 
=> 1356904861.232323 

उस ने कहा, मुझे संदेह है कि डेटा को बनाए रखने पर ActiveRecord गलती से उस जानकारी को छुपा रहा है; याद रखें कि यह डेटाबेस-अज्ञेयवादी है, इसलिए यह उन दृष्टिकोणों को लेता है जो अपने सभी डेटाबेस लक्ष्यों में काम करने की गारंटी देते हैं। जबकि पोस्टग्रेस को टाइमस्टैम्प में माइक्रोसॉन्ड की जानकारी माना जाता है, MySQL नहीं करता है, इसलिए मुझे लगता है कि एआर सबसे कम आम denominator के लिए चयन करता है। मैं एआर की हिम्मत के बिना सुनिश्चित नहीं हो सका। इस व्यवहार को सक्षम करने के लिए आपको पोस्टग्रेस-विशिष्ट बंदरगाह की आवश्यकता हो सकती है।

17

ActiveRecord डेटाबेस से पूर्ण परिशुद्धता को संरक्षित रखना चाहिए, आप इसे ठीक से नहीं देख रहे हैं। आंशिक सेकंड देखने के लिए strftime और %N प्रारूप का उपयोग करें। उदाहरण के लिए, psql इस कहते हैं:

=> select created_at from models where id = 1; 
     created_at   
---------------------------- 
2012-02-07 07:36:20.949641 
(1 row) 

और ActiveRecord यह कहते हैं:

> Model.find(1).created_at.strftime('%Y-%m-%d %H:%M:%S.%N') 
=> "2012-02-07 07:36:20.949641000" 

तो सब कुछ है, तो आप सिर्फ जानना चाहता है कि यह कैसे को देखने के लिए की जरूरत है।

भी ध्यान रखें कि ActiveRecord शायद आप DateTime वस्तुओं के बजाय ActiveSupport::TimeWithZone वस्तुओं लेकिन DateTime भी सब कुछ को बरकरार रखता है दे देंगे:

> '2012-12-31T01:01:01.232323+3'.to_datetime.strftime('%Y-%m-%d %H:%M:%S.%N') 
=> "2012-12-31 01:01:01.232323000" 

ActiveRecord स्रोत में connection_adapters/column.rb पर एक नज़र डालें और देखें कि string_to_time विधि करता है । आपकी स्ट्रिंग fallback_string_to_time पथ नीचे जायेगी और जो कि मैं बता सकता हूं कि आंशिक सेकंड को संरक्षित करता है। कहीं और अजीब कुछ और चल रहा था, मैं आश्चर्यचकित नहीं होगा कि मैंने रेल स्रोत में विशेष रूप से डेटाबेस की तरफ देखा है। मैं तारों को तारों से हाथों में बदलने की कोशिश करता हूं ताकि ActiveRecord उनके हाथों को बंद रखे।

+0

दिलचस्प, हालांकि बनाया गया_एस एमएस रिज़ॉल्यूशन दिखाता है, जब मेरे मॉडल में डेटाटाइम फ़ील्ड होता है, इसे सहेजता है, और इसे पुनः लोड करता है, तो यह एमएस रिज़ॉल्यूशन खो देता है। – SRobertJames

+0

यह है: समस्या create_at में नहीं है, लेकिन अन्य क्षेत्रों में है। – SRobertJames

+1

मैंने केवल 'create_at' का उपयोग किया जैसा कि मैंने आसान था। आप सटीक कहां खो रहे हैं? डेटाबेस में जाने से पहले? डेटाबेस में? इसे खींचने के बाद? –

3

मैं यहां समाप्त हुआ जब मैं ओएस एक्स (मैवरिक्स) पर बाइनरी रूबी 2.0.0-पी 247 प्रदान किए गए आरवीएम का उपयोग करने से पीड़ित था, जो पोस्टग्रेस से समय प्राप्त करने के दौरान सेकेंड के पूरे मूल्यों को गोल कर रहा था। रूबी को पुनर्निर्माण (rvm reinstall 2.0.0 --disable-binary) ने मेरे लिए इस मुद्दे को हल किया।

https://github.com/wayneeseguin/rvm/issues/2189 देखें जो मुझे https://github.com/rails/rails/issues/12422 के माध्यम से मिला।

मुझे पता है कि यह इस मुद्दे का उत्तर नहीं है, लेकिन मुझे उम्मीद है कि यह नोट किसी के साथ संघर्ष करने में मदद कर सकता है।