Contare il numero di giorni tra due date


150

Come contare il numero di giorni tra queste due date?

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

Risposte:


208

Con le classi Date (e DateTime) puoi fare (end_date - start_date).to_iper ottenere la differenza del numero di giorni.


5
@MichaelDurrant Stai facendo un'ipotesi ingiustificata. L'utente non specifica se sono stringhe o meno. Infatti, poiché utilizzano Rails, è molto probabile che le date provengano da ActiveRecord, che le trasmetterà automaticamente agli oggetti della data. Il testo dato è identico anche alla rappresentazione dell'oggetto Date, il che rende molto probabile che provenga da una fonte nativa.
— Andrew France,

84
Questo mi dà la differenza in secondi NON in giorni con rotaie v3 / 4
— 2called-caos

6
Per quanto ne so, il comportamento rimane lo stesso in tutte le versioni recenti di Ruby e ActiveSupport, includendo rispettivamente 2.0 e 4.1.0. Timegli oggetti restituiscono però dei secondi.
— Andrew France,

5
per espandere la risposta @ 2called-caos, per ottenere giorni di cui avresti bisogno (end_date - start_date) /1.day, che ti darebbe un float. Se si desidera avere solo giorni interi, è possibile utilizzare ((end_date - start_date) /1.day) .ceil
— David K.

2
@David Salvo che il commento di @ 2called-caos si riferisce erroneamente agli Timeoggetti, non agli Dateoggetti. Forse potresti aggiornare la denominazione nel tuo commento per riflettere che non sono date?
— Andrew France,

109

Supponendo che end_datee start_datesono entrambi di classe ActiveSupport::TimeWithZonein Rails, allora si può usare:

(end_date.to_date - start_date.to_date).to_i

2
Se ha a che fare con i campi della tabella, questa risposta è la strada da percorrere; invece di quello più valutato proprio qui.
— Ben

Non funziona (Time.zone.now.to_date - 23.hours.ago.to_date).to_i, dà 1 e dovrebbe essere 0
— Yuri Ghensev

3
@YuriGhensev, dipende da quando si esegue il codice di esempio, ad esempio in questo momento Time.zone.now.to_daterestituisce "Mer, 15 nov 2017", mentre 23.hours.ago.to_daterestituisce "Mar, 14 nov 2017". La differenza nel numero di giorni è e dovrebbe essere 1 a meno che non sia stato eseguito il codice nell'ora prima di mezzanotte.
— sottovento il

35

Rails ha alcuni helper integrati che potrebbero risolverlo per te. Una cosa da tenere a mente è che questo fa parte degli Helpview di Actionview, quindi non saranno disponibili direttamente dalla console.

Prova questo

<% 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 non dovrebbe essere quando è necessario il numero effettivo per i calcoli.
— Fedcomp

Questa domanda è uno di quei casi in cui la domanda stessa è meglio posta in modo diverso. Se segui le altre risposte qui, ti imbatterai in casi in cui a volte vuoi che vengano mostrate settimane o anni anziché giorni. Questo dovrebbe davvero essere accettato come la risposta "giusta" di Rails.
— Dylan Pierce,

34

Continuavo a ottenere risultati in pochi secondi, quindi questo ha funzionato per me:

(Time.now - self.created_at) / 86400

1
@Epigene 1.daynon è rubycome richiesto dall'OP (nei tag). È Railso più specifico active supportanche se in created_atpratica è un Modelmetodo in Railstal modo ...
— Roko

26

per ottenere il numero di giorni in un intervallo di tempo (solo un conteggio di tutti i giorni)

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

per ottenere il numero di giorni tra 2 date

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

Grazie per questo @ a14m! Mi ha dato un modo per fare acquisizioni di date inclusive ed esclusive :)
— Kris Boyd il

18

Nessuna delle risposte precedenti (a questa data) fornisce la differenza corretta in giorni tra due date.

Quello che si avvicina di più è quello che è umido . Una risposta completa verrebbe convertita to_ie quindi divisa:

(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

Nell'esempio specifico della domanda, non si dovrebbe analizzare Datese il tempo trascorso è rilevante. Usa Time.parseinvece.


Questo potrebbe non funzionare come previsto quando i tempi attraversano una transizione DST andando avanti. In questo caso, la durata del giorno di transizione dell'ora legale è legittimamente inferiore a 24 ore, ma a causa dell'aritmetica intera quel giorno non si rifletterà affatto.
— PinnyM,

4

Per avere il numero di giorni interi tra due date ( DateTimeoggetti):

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

Stesso problema di ora legale della risposta che Yuri ha dato. L'aritmetica con il tempo non è mai così semplice come ti aspetteresti :)
— PinnyM

0

Per ottenere il numero di giorni di differenza di due date:

(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
molto più facile sottrarre gli oggetti data.
— OpenCoderX

L'OP non ha mai chiesto di adeguarsi ai giorni lavorativi. Questo è davvero contorto comunque.
— Nathan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.