रूबी ऑन रेल्स में दो तिथियों के बीच महीनों की संख्या का पता लगाएं


95

मैं रेल्स डेटाइम ऑब्जेक्ट्स पर दो रूबी है। उनके बीच महीनों की संख्या का पता कैसे लगाएं? (ध्यान में रखते हुए वे अलग-अलग वर्षों के हो सकते हैं)


5
यहाँ सवाल किया गया था और इसका जवाब दिया गया था: stackoverflow.com/questions/5887756/…
टिम बाश

इस पर ध्यान दिलाने के लिए धन्यवाद। मैंने खोजा लेकिन उस पर कोई ठोकर नहीं लगी।
फीनिक्सविल्ड

इस लिंक का उल्लेख करें stackoverflow.com/questions/1065320/…
संगेठकुमार

मैं संख्याओं में लिंक चाहता हूं। मैंने इसे मैसिमिलियानो पेलुसो द्वारा बताई गई विधि द्वारा किया
फीनिक्सविद

बस मैंने इसे आपके संदर्भ के लिए दिया .. धन्यवाद वैसे भी ..
संगीथकुमार

जवाबों:


179
(date2.year * 12 + date2.month) - (date1.year * 12 + date1.month)

http://www.ruby-forum.com/topic/72120 पर अधिक जानकारी


25
यह समाधान दिनों पर विचार नहीं करता है। 28/4/2000 और 1/5/2000 के बीच महीनों की संख्या 1 महीने नहीं है, लेकिन 0.
dgilperez

15
मुझे दिनों पर विचार किए बिना एक की आवश्यकता है इसलिए यह मेरे लिए काम करता है। +1
वाट्सएपबॉक्स

1
: इस महान जवाब के लिए बस एक और संस्करण(12 * (date2.year - date1.year) + date2.month - date1.month).abs if date1 && date2
Stepan ज़ाराखोव

अगर हम 2 साल यानी 2017-05-20 से 2018-05-20 के बीच महीने लाने की कोशिश करते हैं तो इसका गलत # महीनों का प्रदर्शन हो रहा है। आउटपुट 1 महीने दिखाता है।
उत्सुक डेवलपर

1
@CuriousDeveloper यह सही महीने दिखा रहा है यानी 12
ts

40

अधिक सटीक उत्तर दूरी में दिनों पर विचार करेगा।

उदाहरण के लिए, यदि आप इस बात पर विचार करते हैं कि महीने की दूरी कितनी है 28/4/2000और 1/5/2000क्या 0है 1, तो आप इसका उपयोग कर सकते हैं:

(date2.year - date1.year) * 12 + date2.month - date1.month - (date2.day >= date1.day ? 0 : 1)

1
उदाहरण के लिए किसी की संख्या की गणना करने के लिए किसी को उसका वेतन हमेशा 22 वें महीने में मिलता है
मथायस

15

के लिए एक कोशिश दे

((date2.to_time - date1.to_time)/1.month.second).to_i

irb>Time.at("2014-10-01".to_time - "2014-12-01".to_time).month => 10 (मैं प्रारूपण पर छोड़ देता हूं ... इसका पता नहीं लगा सकता)
टोबी जॉइनर

भले ही आप दिनांक ऑब्जेक्ट का उपयोग करते हैं, @ toby-joiner की टिप्पणी अभी भी सही होगी। इसका कारण यह है कि <अक्टूबर> - <दिसंबर> -2 महीने है, लेकिन Time.at (-2 महीने) (। महीने) -2 के बराबर महीने देता है (यानी -2% 12 # => 10)। यदि आप सुझाए गए तरीके से काम करेंगे, अगर दो महीने एक-दूसरे का अनुसरण करते हैं और एक वर्ष से कम हैं, लेकिन यह विफल हो जाएगा, यदि दो महीने रिवर्स ऑर्डर (जैसे अक्टूबर - दिसंबर) में हैं या यदि दो महीने एक साल से अधिक अलग हैं।
एलरीमुंडो

2
मुझे इसके पीछे का विचार पसंद है, लेकिन यह गलत है अगर डेटस्पैन वास्तव में लंबा हो रहा है। मेरे उदाहरण में Date.new(2014, 10, 31), Date.new(1997, 4, 30)मुझे 210 महीनों के बजाय 213 मिले। इसका कारण यह है कि 1.month.seconds30 दिनों में सेकंड की संख्या है और एक महीने में औसत सेकंड नहीं है। डाउनवोटिंग ताकि दूसरों को बग-मुक्त रहें।
जो एफर्ट

1
यदि आप 30 दिन नहीं
dima

2
यह तरीका बहुत सटीक नहीं है।
आवाराबन्द

9

आप इस प्रश्न को फिर से लिख सकते हैं कि "तारीखों के महीनों की शुरुआत के बीच कितने 1 दिन हैं", और फिर कार्यात्मक-शैली डेटा परिवर्तनों का उपयोग करें:

(date1.beginning_of_month...date2.beginning_of_month).select { |date| date.day == 1 }.size

और मूल प्रश्न पर वापस जाने के लिए, आप दिनों (जैसे आप पहले के साथ कर रहे हैं) को जोड़ सकते हैं और रकम का औसत निकाल सकते हैं।
जो एफर्ट

9

यह मानते हुए कि दोनों तिथियां हैं: ((date2 - date1).to_f / 365 * 12).round सरल।


बहुत अच्छा समाधान! स्वच्छ, सरल और यहां तक ​​कि साल भर काम करता है - यानी फरवरी 2018 और दिसंबर 2017 के बीच के महीनों की सीमा।
jeffdill2

1
घंटे, मिनट और सेकंड को ध्यान में रखने की आवश्यकता है ((date2 - date1).to_f / 60 / 60 / 24 / 365 * 12).round
scarver2

1
@ scarver2 आपको अपनी गणना से मिलने वाला नंबर बंद है। हम जो कुछ भी कर रहे हैं वह दिन ले रहा है और उन्हें महीनों में परिवर्तित कर रहा है, यह सुपर सटीक नहीं है क्योंकि यह प्रति माह 30.4167 दिन मानता है, लेकिन यह बहुत करीब है और फिर यह किसी भी तरह से गोल हो जाता है।
एंड्रेकुल


2

एक और समाधान जो मुझे मिला (एक समाधान पहले से ही यहां पोस्ट किया गया है) यदि आप चाहते हैं कि परिणाम एक महीने के अंशों को शामिल करें। उदाहरण के लिए दूरी है 1.2 months

((date2.to_time - date1.to_time)/1.month.second).round(1) #Tenth of a month Ex: 1.2
((date2.to_time - date1.to_time)/1.month.second).round(2) #Hundreth, ex: 1.23 months
etc...

1
यदि आप केवल महीनों को वास्तव में व्यतीत करने के लिए दिखावा करते हैं, तो फर्श के साथ गोल-गोल घूमने का प्रयास करें
Matthias

2
def difference_in_months(date1, date2)
  month_count = (date2.year == date1.year) ? (date2.month - date1.month) : (12 - date1.month + date2.month)
  month_count = (date2.year == date1.year) ? (month_count + 1) : (((date2.year - date1.year - 1 ) * 12) + (month_count + 1))
  month_count
end

1
यह उपयोगी होगा यदि आप इस पर विस्तार से बता सकते हैं? आम तौर पर एसओ के जवाबों में एक स्पष्टीकरण शामिल होता है कि कोड क्या करता है और यह समाधान के रूप में क्यों काम करता है
सिंगल एंटिटी

1

मुझे दो तिथियों के बीच महीनों की सटीक संख्या (दशमलव सहित) की आवश्यकता थी और इसके लिए निम्न विधि लिखी।

def months_difference(period_start, period_end)
  period_end = period_end + 1.day
  months = (period_end.year - period_start.year) * 12 + period_end.month - period_start.month - (period_end.day >= period_start.day ? 0 : 1)
  remains = period_end - (period_start + months.month)

  (months + remains/period_end.end_of_month.day).to_f.round(2)
end

यदि तुलना करते हैं कि 26 सितंबर से 26 सितंबर (उसी दिन) मैं इसे 1 दिन के रूप में गणना करता हूं। अगर आपको इसकी आवश्यकता नहीं है कि आप विधि में पहली पंक्ति को हटा सकते हैं:period_end = period_end + 1.day

यह निम्नलिखित चश्मा पास करता है:

expect(months_difference(Date.new(2017, 8, 1), Date.new(2017, 8, 31))).to eq 1.0
expect(months_difference(Date.new(2017, 8, 1), Date.new(2017, 8, 30))).to eq 0.97
expect(months_difference(Date.new(2017, 8, 1), Date.new(2017, 10, 31))).to eq 3.0
# Overlapping february (28 days) still counts Feb as a full month
expect(months_difference(Date.new(2017, 1, 1), Date.new(2017, 3, 31))).to eq 3.0
expect(months_difference(Date.new(2017, 2, 10), Date.new(2017, 3, 9))).to eq 1.0
# Leap year
expect(months_difference(Date.new(2016, 2, 1), Date.new(2016, 2, 29))).to eq 1.0

btw यह रेल के ActiveSupport पर निर्भर करता है
mtrolle

1

यहाँ एक जबरदस्ती संस्करण है:

date1 = '2016-01-05'.to_date
date2 = '2017-02-27'.to_date
months = 0

months += 1 while (date2 << (count+1)) >= date1
puts months # => 13

date2 हमेशा से बड़ा होना चाहिए date1


0

यहाँ एक और तरीका है। यह दो तिथियों के बीच पूरे महीनों की संख्या की गणना करने में मदद करेगा

def months_difference(date_time_start, date_time_end)
  curr_months = 0
  while (date_time_start + curr_months.months) < date_time_end
    curr_months += 1
  end
  curr_months -= 1 if (date_time_start + curr_months.months) > date_time_end
  curr_months.negative? ? 0 : curr_months
end
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.