2010-11-30 19 views
2

J'ai actuellement cette instruction if:Existe-t-il une façon plus concise de combiner de nombreuses comparaisons dans Ruby?

if Time.now.day == 1 and Time.now.hour == 0 and Time.now.minute == 0 and Time.now.second == 0 

Y at-il une façon plus concise de le faire?

+2

btw, ne ferait pas le temps.maintenant vous donner une nouvelle heure chaque fois que vous l'appelez? Ne vaudrait-il pas mieux définir Time.now à une variable locale, puis l'utiliser dans if? Je suppose que cela dépend de ce que vous voulez vraiment ... –

+0

Il retournera différentes valeurs, seulement elles seront différentes d'une petite tranche de seconde. Théoriquement, il est possible que le temps passe de 00:00:00 à 00:00:01. Essayez ceci dans IRB: '5times {met Time.now.to_f}' pour avoir une idée de la vitesse à laquelle les conditions seront testées. –

Répondre

3

La bibliothèque standard Temps Ruby est assez libre, donc je voudrais simplement ajouter ma propre méthode pour vous faciliter la tâche:

class Time 
    def beginning_of_month 
    Time.local(self.year, self.month, 1) 
    end 

    def beginning_of_month? 
    self == beginning_of_month 
    end 
end 

vous pouvez donc alors écrire:

if Time.now.beginning_of_month? 
+0

Je ne vois pas la méthode de changement sur le document standard soit http://www.ruby-doc.org/core/classes/Time.html –

+0

Désolé, j'ai supprimé accidentellement mon précédent commentaire. Le commentaire original était (quelque peu similaire à): je ne le vois pas fonctionner quand je le lance. Quelle version de ruby ​​utilisez-vous? Le mien 1.8.7. Lorsqu'il est exécuté, il crache cette erreur: méthode non définie 'change 'pour mar 30 nov 16:07:18 +1100 2010: Time (NoMethodError) –

+0

@tim_wonil vous avez raison, je pense que mon IRB a été activewort à mon insu . –

1

Vous pouvez comparer à la fois que vous avez créé:

if Time.now == Time.at(0) 

ou

if Time.now == Time.utc(2000,"jan",1,20,15,1) 
4
[:day,:hour,:minute,:second].map{|s|Time.now.send s}==[1,0,0,0] 
+0

Upvote pour essayer de faire de Ruby en Perl. – jergason

+0

@Jergason: Que voulez-vous dire? C'est idiomatique Ruby. –

+0

Le bit qui m'embête est le '{| s | Time.now.send s}'. Il semble que vous devriez être capable d'éliminer les points 's'. –

1

Je suppose que vous essayez de faire quelque chose de similaire à cron, à savoir que vous êtes dans une boucle sans fin et vérifier si le temps est venu d'effectuer certaines actions.

Si tel est le cas, je ne pense pas que vous devriez compter sur le fait que votre vérification d'horodatage tombera exactement sur la première seconde de la journée. Que se passerait-il si est retardé (pour une raison quelconque), et d'abord il se déclenche sur 23:59:59, et le prochain cycle se passe sur 00:00:01 au lieu de :00? Vous ne réussirez pas à accomplir l'action désirée.

Aussi, vous voudriez inclure quelques sleep, de sorte que votre boucle vide ne consommerait pas toutes vos ressources en attendant. Au lieu de cela, vous pouvez conserver l'horodatage de la dernière action et comparer now avec l'horodatage d'action suivant, en effectuant l'action si now >= next_timestamp. Quelque chose comme:

last_action_on = Time.at(0) 
loop do 
    now = Time.now 
    next_action_on = Time.local(now.year, now.month, 1) # beginning of the current day 
    if last_action_on < next_action_on && now >= next_action_on 
    last_action_on = now 
    do_action 
    end 
    sleep 1 
end 
5

Vous pouvez utiliser Time#to_a pour convertir votre temps à un tableau (sec, min, heure, jour, mois, année, wday, yday, isdst, zone):

Time.now.to_a # => [20, 57, 16, 30, 11, 2010, 2, 334, false, "CET"] 

puis la découper juste la partie que vous voulez correspondre:

Time.now.to_a[0,4] # => [20, 57, 16, 30] 

Votre chèque particulier peut alors être fait aussi concis que ceci:

if Time.now.to_a[0,4] == [0,0,0,1] 
0
%w(day==1 hour==0 minute==0 second==0).all? { |e| eval "Time.now.#{e}" } 
2

Pourquoi?

Time.now.strftime('%d %H:%M:%S') == '01 00:00:00' 

J'aime ça parce que c'est très auto-documenté; Il est évident que vous comparez à un certain jour à minuit. Explication: La méthode strftime() facilite la sortie d'une chaîne de date et/ou d'heure personnalisée. Ce format produit le jour du mois, heure, minute et seconde.

Time.now.strftime('%d %H:%M:%S') #=> "01 16:54:24"