Ruby - получить время в начале следующей минуты - PullRequest
0 голосов
/ 31 декабря 2018

Я ищу краткий способ получить объект Ruby Time, представляющий вершину следующей минуты (и час / день / месяц / год, если это возможно).Я хочу, чтобы это работало в чистой среде Ruby, поэтому функция Rails Time.change или аналогичная не подходит.

Сначала это кажется простым - просто добавьте 1 к Time.now, но естьВ крайних случаях, когда, например, если вы пытаетесь создать экземпляр объекта Time с Time.now.min + 1, когда текущая минута равна 59, вы получите ArgumentError: min out of range.Это относится и к часам, дням и месяцам.

У меня есть длинный код, который выполняет эту работу.Это некрасиво, но я просто экспериментирую:

def add_minute

    now = Time.local
    year = now.year
    month = now.month
    day = now.day
    hour = now.hour
    min = now.min

    if now.min == 59
        if now.hour == 23
            if now.day == Date.civil(now.year, now.month, -1).day
                if month == 12
                    year = year + 1
                    month = 1
                    day = 1
                    hour = 0
                    min = 0
                else
                    month = now.month + 1
                    day = 1
                    hour = 0
                    min = 0
                end
            else
                day = now.day + 1
                hour = 0
                min = 0
            end
        else
            hour = now.hour + 1
            min = 0
        end
    else
        min = now.min + 1
    end

    Time.local year, month, day, hour, min, 0
end

Это кажется нелепо многословным для того, что кажется простым или встроенным заданием, но я не нашел нативного решения Ruby.Существует ли один?

Ответы [ 4 ]

0 голосов
/ 31 декабря 2018

Другой вариант, от одной секунды до полуночи:

require 'time'
now = Time.strptime('2018-12-31 23:59:59', '%Y-%m-%d %H:%M:%S')

В течение одной минуты:

Time.at(now + 60) #=> 2019-01-01 00:00:59 +0100
Time.at(now + 60 - now.sec) #=> 2019-01-01 00:00:00 +0100

Вы получаете: # HAPPY NEW YEAR!

0 голосов
/ 31 декабря 2018

Вы можете преобразовать объект Time в эпоху UNIX (секунды с 1970 года), используя #to_i, добавить 60 с, а затем преобразовать обратно в Time объект.

time_unix = Time.now.to_i
time_unix_one_min_later = time_unix + 60
time_one_min_later = t = Time.at(time_unix_one_min_later)
time_one_min_later_rounded_down = Time.new(t.year, t.month, t.day, t.hour, t.min)

РЕДАКТИРОВАТЬ: Еще короче - вы можете просто добавить целые секунды к Time.now напрямую:

time_one_min_later = t = Time.now + 60
time_one_min_later_rounded_down = Time.new(t.year, t.month, t.day, t.hour, t.min)

РЕДАКТИРОВАТЬ 2: Однострочный - просто вычтите Time.now.sec:

time_one_min_later_rounded_down = Time.now + 60 - Time.now.sec
0 голосов
/ 31 декабря 2018

В Ruby есть встроенные методы для добавления месяцев (>>) и дней (+).Год - 12 месяцев, а час - 1/24 дня.

require 'date'

def add_time(time, year: 0 ,month: 0, day: 0, hour: 0, minute: 0)
  time >>= 12*year
  time >>= month
  time +=  day
  time +=  Rational(hour,24)       # or (hour/24.0) if you dislike rationals
  time +=  Rational(minute, 24*60) # (minute/24.0*60) if you dislike rationals
end

p t = DateTime.now
p add_time(t, year: 1, minute: 30)
0 голосов
/ 31 декабря 2018

Не так чисто без ActiveSupport:

new_date = (DateTime.now + 1.to_f / (60*24))
DateTime.new(new_date.year, new_date.month, new_date.day, new_date.hour, new_date.minute)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...