2016-05-14 5 views
5

Also, bei einem DateTime-Objekt und einer festen Zeit, möchte ich das nächste Vorkommen der festen Zeit nach dem angegebenen DateTime-Objekt erhalten.Ruby DateTime: Get ne 5:15 pm (oder ähnlich)

  • Zum Beispiel gegeben das Datum des 14. März 2016, 16.00 Uhr, und die Zeit von 17.15, ich möchte 14. März zurück, 2016 05.15.

  • jedoch angesichts der Tag des 14. März 2016, 18.00 Uhr, und die Zeit von 05.15, möchte ich 15. März, zurück 2016, 5.15, denn das ist die nächste Vorkommen ist.

Bisher habe ich diesen Code geschrieben:

# Given fixed_time and date_time 

new_time = date_time 
if fixed_time.utc.strftime("%H%M%S%N") >= date_time.utc.strftime("%H%M%S%N") 
    new_time = DateTime.new(
    date_time.year, 
    date_time.month, 
    date_time.day, 
    fixed_time.hour, 
    fixed_time.min, 
    fixed_time.sec 
) 
else 
    next_day = date_time.beginning_of_day + 1.day 
    new_time = DateTime.new(
    next_day.year, 
    next_day.month, 
    next_day.day, 
    fixed_time.hour, 
    fixed_time.min, 
    fixed_time.sec 
) 
end 

# Return new_time 

Es funktioniert, aber es gibt einen besseren Weg?

Antwort

6

würde ich das neue Datum Zeit nur einmal bauen und 1 Tag wenn nötig:

# Given fixed_time and date_time 
new_date_time = DateTime.new(
    date_time.year, 
    date_time.month, 
    date_time.day, 
    fixed_time.hour, 
    fixed_time.min, 
    fixed_time.sec 
) 

# add 1 day if new date prior to the given date 
new_date_time += 1.day if new_date_time < date_time 
1

Hier ist ein kleiner Stich es Refactoring einige der Redundanz zu entfernen:

# Given fixed_time and date_time 

base_date = date_time.to_date 
if fixed_time.to_time.utc.strftime("%T%N") <= date_time.to_time.utc.strftime("%T%N") 
    base_date = base_date.next_day 
end 

new_time = DateTime.new(
    base_date.year, 
    base_date.month, 
    base_date.day, 
    fixed_time.hour, 
    fixed_time.min, 
    fixed_time.sec 
) 

# Return new_time 

Die größte Änderungen sind, dass das base_date vor der Erstellung der new_time ermittelt wird, damit es dort verwendet werden kann.

habe ich auch die next_day Methode auf Datetime am nächsten Tag zu bekommen, und verwendet, um die „% T“ Formatbezeichner als Abkürzung für „% H:% M:% S“

Hier ist ein kleines Programm-Test dass zeigen, dass es funktioniert:

require "date" 

def next_schedule(fixed_time, date_time) 
    # Given fixed_time and date_time 

    base_date = date_time.to_date 
    if fixed_time.to_time.utc.strftime("%T%N") <= date_time.to_time.utc.strftime("%T%N") 
    base_date = base_date.next_day 
    end 

    new_time = DateTime.new(
    base_date.year, 
    base_date.month, 
    base_date.day, 
    fixed_time.hour, 
    fixed_time.min, 
    fixed_time.sec 
) 

    # Return new_time 
end 

StartTime = DateTime.strptime("2016-02-14 17:15:00", "%F %T") 
Dates = [ 
    "2016-03-14 16:00:00", 
    "2016-03-14 18:00:00" 
] 

Dates.each do |current_date| 
    scheduled = next_schedule(StartTime, DateTime.strptime(current_date, "%F %T")) 
    puts "Scheduled: #{scheduled.strftime('%F %T')}" 
end 

der Ausgang dieses ist:

Scheduled: 2016-03-14 17:15:00 
Scheduled: 2016-03-15 17:15:00 

es ist die Testfälle in der Frage beschriebenen, und es wird die erwarteten Antworten.

+0

Danke! Dies macht die Funktion besser und kleiner, obwohl der Ansatz derselbe ist. Wenn ich keine Antwort mit einem besseren Ansatz bekomme, werde ich Ihre als die akzeptierte Antwort markieren. – shashwat

+0

@shashwat Wenn du einfach zurückschaust, um zu sehen, ob du einen besseren Ansatz finden kannst oder mit dem du fährst? –