2012-04-07 13 views
21

Voglio creare un'istanza DateTime che si trova 20 minuti e 10 secondi in futuro. Ho provato con Time e DateTime in irb, ma non riesco a capire un modo davvero sensato. Posso solo aggiungere giorni agli oggetti DateTime e aggiungere solo secondi agli oggetti Tempo.Tempo di manipolazione in rubino

Non c'è un modo migliore di convertire sempre il tempo che voglio aggiungere in secondi?

risposta

46

un Time è un certo numero di secondi il peccato ce un epoca mentre un DateTime è un numero di giorni da un'epoca, motivo per cui aggiungere 1 a DateTime aggiunge un'intera giornata. tuttavia è possibile aggiungere le frazioni di un giorno, per esempio

d = DateTime.now 
d + Rational(10, 86400) 

Aggiungerà 10 secondi per d (dato che ci sono 86400 secondi in un giorno).

Se si utilizza Rails, ActiveSupport aggiunge alcuni metodi di supporto e si può fare

d + 20.minutes + 10.seconds 

che farà la cosa giusta è d è un DateTime o un Time. È possibile utilizzare ActiveSupport da solo e in questi giorni è possibile inserire solo i bit necessari. Mi sembra di ricordare che questa roba è in activesupport/duration. Credo ci siano altre gemme che offrono aiuto anche nel gestire il tempo.

+5

Personalmente preferisco scrivere '60 * 60 * 24' per rendere un po 'più ovvio il punto da cui viene il numero magico, anche se ovviamente sarà molto più lento in fase di esecuzione. –

+0

@AndrewMarshall È d'accordo, e a meno che uno stia eseguendo la manipolazione di 'DateTime' milioni su milioni di volte, altre due operazioni di moltiplicazione non valgono * micro-ottimizzazione *. Non pensarci nemmeno finché non ti imbatti in un problema di prestazioni.Ancora meglio, che ne dici di dichiarare una costante all'inizio del codice? 'SECONDS_PER_DAY = 60 * 60 * 24', e usalo. Lo stesso potrebbe essere fatto per 'MINUTERS_PER_DAY = 60 * 24' e' HOURS_PER_DAY = 24', anche se forse l'ultimo non è necessario, ma è bello essere coerenti e basta elencarli tutti. –

2

Ebbene, l'interfaccia è semplice e lineare:

t = Time.now 
t + (20 * 60 + 10) 

Se si vuole avere qualcosa di comodo, è possibile aggiungere metodi alla classe Time:

class Time 
    def add_minutes(m) 
    self + (60 * m) 
    end 
end 

Ma non credo che questo è più semplice:

t = Time.now 
t.add_minutes(20) + 10 
+4

OP desidera Data, non Ora. – steenslag

2

Supponendo di aver richiesto ActiveSupport o di lavorare in un progetto Rails. Un semplice modo leggibile per fare questo in rubino è:

DateTime + 5.minutes 
Time + 5.minutes 

funziona anche con .seconds, .hours, .days, .weeks, .month, .years

+16

Si prega di notare che questo presuppone che tu abbia ActiveSupport o Rails. –

+0

grazie per l'informazione - ho pensato che questo fosse un comportamento standard rubino – alex

2

Basta utilizzare le estensioni temporali sostegno attivo. Sono molto convenienti e meno inclini all'errore che provare a farlo a mano. È possibile importare solo il modulo è necessario:

# gem 'activesupport' 
require 'active_support/core_ext/numeric/time.rb' 
DateTime.now + 20.minutes 

NB: Sì, questo va contro la linea del partito StackOverflow di stare lontano da biblioteche 3rd party, ma non si dovrebbe evitare di utilizzare le librerie quando sono praticamente standard, ridurre significativamente il rischio e fornire una migliore chiarezza del codice.