นับจำนวนวันระหว่างสองวัน


149

ฉันจะนับจำนวนวันระหว่างวันที่ทั้งสองนี้ได้อย่างไร

start_date = Date.parse "2012-03-02 14:46:21 +0100"
end_date =  Date.parse "2012-04-02 14:46:21 +0200"

คำตอบ:


207

ด้วยคลาส Date (และ DateTime) คุณสามารถทำได้(end_date - start_date).to_iเพื่อให้ได้จำนวนวันที่แตกต่างกัน


5
@MichaelDurrant คุณกำลังทำข้อสมมติฐานที่ไม่มีเหตุผล ผู้ใช้ไม่ได้ระบุว่าเป็นสตริงหรือไม่ ในความเป็นจริงเนื่องจากพวกเขากำลังใช้ Rails เป็นไปได้มากที่สุดว่าวันที่มาจาก ActiveRecord ซึ่งจะส่งพวกเขาไปยังวัตถุวันที่โดยอัตโนมัติ ข้อความที่ให้นั้นเหมือนกับการแสดงวัตถุวันที่เช่นกันทำให้มีโอกาสสูงที่จะมาจากแหล่งดั้งเดิม
Andrew France

84
ที่ให้ฉันแตกต่างในไม่กี่วินาทีไม่กี่วันกับทางรถไฟ v3 / 4
2called-chaos

6
เท่าที่ฉันสามารถบอกได้ว่าพฤติกรรมยังคงเหมือนเดิมใน Ruby และ ActiveSupport เวอร์ชันล่าสุดทั้งหมดให้รวม 2.0 และ 4.1.0 ตามลำดับ Timeวัตถุส่งคืนวินาทีแม้ว่า
Andrew France

5
เพื่อขยายคำตอบ @called-chaos เพื่อให้ได้วันที่คุณต้องการ (end_date - start_date) /1.day ซึ่งจะทำให้คุณได้รับข้อมูล หากคุณต้องการมีวันเต็มเพียงคุณอาจใช้ ((end_date - start_date) /1.day) .ceil
David K.

2
@ David ยกเว้นว่าความคิดเห็นโดย @ 2called-chaos เป็นการอ้างถึงTimeวัตถุอย่างผิดพลาดไม่ใช่Dateวัตถุ บางทีคุณสามารถอัปเดตการตั้งชื่อในความคิดเห็นของคุณเพื่อแสดงว่าพวกเขาไม่ใช่วันที่?
Andrew France

109

สมมติว่าend_dateและstart_dateมีทั้งของชั้นActiveSupport::TimeWithZoneใน Rails แล้วคุณสามารถใช้:

(end_date.to_date - start_date.to_date).to_i

2
ถ้าเกี่ยวข้องกับเขตข้อมูลตารางคำตอบนี้เป็นวิธีไป แทนที่จะเป็นหนึ่งในอันดับสูงสุดที่นี่
Ben

ไม่ได้ผล(Time.zone.now.to_date - 23.hours.ago.to_date).to_iมันให้ 1 และควรเป็น 0
Yuri Ghensev

3
@YuriGhensev ขึ้นอยู่กับว่าคุณใช้งานโค้ดตัวอย่างเช่นตอนนี้Time.zone.now.to_dateส่งคืน "Wed, 15 Nov 2017" ในขณะที่23.hours.ago.to_dateส่งคืน "Tue, 14 Nov 2017" ความแตกต่างของจำนวนวันคือและควรเป็น 1 ยกเว้นว่าคุณใช้รหัสในชั่วโมงก่อนเที่ยงคืน
lee

35

Rails มีผู้ช่วยในตัวที่อาจช่วยคุณได้ สิ่งหนึ่งที่ต้องจำไว้คือนี่เป็นส่วนหนึ่งของ Helpview ของ Actionview ดังนั้นจึงไม่สามารถใช้งานได้โดยตรงจากคอนโซล

ลองสิ่งนี้

<% start_time =  "2012-03-02 14:46:21 +0100" %>
<% end_time   =  "2012-04-02 14:46:21 +0200" %>
<%= distance_of_time_in_words(start_time, end_time)  %>

 "about 1 month"

@ MaayanNaveh มันไม่ควรจะเป็นเมื่อคุณต้องการจำนวนจริงสำหรับการคำนวณ
Fedcomp

คำถามนี้เป็นหนึ่งในกรณีที่คำถามตัวเองดีกว่าถามที่แตกต่างกัน หากคุณทำตามคำตอบอื่น ๆ ที่นี่คุณจะพบกรณีที่บางครั้งคุณต้องการแสดงสัปดาห์หรือปีแทนวัน สิ่งนี้ควรได้รับการยอมรับว่าเป็นคำตอบที่ "เหมาะสม"
Dylan Pierce

34

ฉันได้รับผลลัพธ์ในไม่กี่วินาทีดังนั้นนี่จึงใช้ได้สำหรับฉัน:

(Time.now - self.created_at) / 86400

1
@Epigene 1.dayไม่rubyเป็นที่ต้องการ OP (ในแท็ก) มันมีRailsความเฉพาะเจาะจงมากกว่าหรือactive supportว่าcreated_atเป็นModelวิธีในการRails..
Roko

26

เพื่อรับจำนวนวันในช่วงเวลา (เพียงนับจำนวนวันทั้งหมด)

(start_date..end_date).count
(start_date..end_date).to_a.size
#=> 32

เพื่อรับจำนวนวันระหว่าง 2 วัน

(start_date...end_date).count
(start_date...end_date).to_a.size
#=> 31

ขอบคุณสำหรับสิ่งนี้ @ a14m! ให้ฉันมีวิธีที่จะทำแบบครบวงจรและพิเศษจับวัน :)
คริสบอยด์

18

ไม่มีคำตอบก่อนหน้า (จนถึงวันนี้) ที่ให้ความแตกต่างที่ถูกต้องเป็นวันระหว่างวันที่สองวัน

หนึ่งที่อยู่ใกล้ที่สุดคือมาโดยthatdankent คำตอบแบบเต็มจะแปลงto_iแล้วหาร:

(Time.now.to_i - 23.hours.ago.to_i) / 86400
>> 0

(Time.now.to_i - 25.hours.ago.to_i) / 86400
>> 1

(Time.now.to_i - 1.day.ago.to_i) / 86400
>> 1

ในตัวอย่างที่เฉพาะเจาะจงของคำถามเราไม่ควรแยกวิเคราะห์Dateว่าเวลาที่ผ่านไปนั้นเกี่ยวข้องกันหรือไม่ ใช้Time.parseแทน


สิ่งนี้อาจไม่ทำงานอย่างที่คาดไว้เมื่อเวลาผ่านไปช่วงเปลี่ยนผ่าน DST ในกรณีนี้ความยาววันเปลี่ยนผ่านของ DST นั้นถูกต้องตามกฎหมายน้อยกว่า 24 ชั่วโมง แต่เนื่องจากตัวเลขทางคณิตศาสตร์ที่เป็นจำนวนเต็มในวันนั้นจะไม่ปรากฏเลย
PinnyM

4

วิธีมีจำนวนวันทั้งวันระหว่างสองวัน ( DateTimeวัตถุ):

((end_at - start_at).to_f / 1.day).floor

ปัญหา DST เช่นเดียวกับคำตอบที่ยูริให้ เลขคณิตที่มีเวลาไม่ตรงไปตรงมาอย่างที่คุณคาดหวัง :)
23419

0

วิธีรับจำนวนวันแตกต่างกันตามวันที่สองวัน:

(start.to_date...end.to_date).count - 1
or 
(end.to_date - start.to_date).to_i

-8
def business_days_between(date1, date2)
  business_days = 0
  date = date2
  while date > date1
   business_days = business_days + 1 unless date.saturday? or date.sunday?
   date = date - 1.day
  end
  business_days
end

3
ง่ายกว่ามากในการลบวัตถุวันที่
OpenCoderX

OP ไม่เคยถามเกี่ยวกับการปรับสำหรับวันทำการ นี่มันซับซ้อนจริง ๆ อยู่ดี
นาธาน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.