Чтение онлайн

на главную - закладки

Жанры

Программирование на языке Ruby
Шрифт:

Я бы с удовольствием объяснил вам этот алгоритм, только вот сам его не понимаю… Что-то надо принимать на веру, а в данном случае это особенно уместно!

7.5. Вычисление n-ого дня недели в месяце

Иногда, зная год и месяц, хочется вычислить дату, скажем, третьего понедельника или второго вторника в этом месяце. Такую задачу решает код в листинге 7.1.

Чтобы найти n-ое вхождение данного дня недели, мы передаем n в качестве первого параметра. Второй параметр — номер дня недели (0 — воскресенье, 1 — понедельник и т.д.). Третий и четвертый параметры — месяц и год соответственно.

Листинг 7.1.
Вычисление n-ого дня недели в месяце

def nth_wday(n, wday, month, year)

 if (!n.between? 1,5) or

(!wday.between? 0,6) or

(!month.between? 1,12) raise ArgumentError

 end

 t = Time.local year, month, 1

 first = t.wday

 if first == wday

fwd = 1

 elsif first < wday

fwd = wday - first + 1

 elsif first > wday

fwd = (wday+7) - first + 1

 end

 target = fwd + (n-1)*7

 begin

t2 = Time.local year, month, target

 rescue ArgumentError

return nil

 end

 if t2.mday == target

t2

 else

nil

 end

end

Странный код в конце текста метода призван скорректировать давнюю традицию, принятую в функциях работы с датами. Если вы думаете, что попытка создать объект для представления 31 ноября приведет к ошибке, то разочарую вас. Почти все системы молчаливо преобразуют эту дату в 1 декабря. Если вы давным-давно программируете в UNIX, то, наверное, полагаете, что так и должно быть. Другие сочтут это ошибкой.

Не станем спорить о том, что должна делать системная библиотека и должен ли Ruby изменить это поведение. Но мы не хотим, чтобы наша процедура продолжала эту традицию. Если вы ищете, к примеру, пятую пятницу в ноябре 2000 года, то она вернет

nil
(а не 1 декабря 2000 года).

7.6. Преобразование из секунд в более крупные единицы

Иногда нужно преобразовать заданное число секунд в дни, часы, минуты и секунды. Это можно сделать следующим образом:

def sec2dhms(seсs)

 time = seсs.round # Отбрасываем микросекунды.

 sec = time % 60 # Извлекаем секунды.

 time /= 60 # Отбрасываем секунды.

 mins = time % 60 # Извлекаем минуты.

 time /= 60 # Отбрасываем минуты.

 hrs = time % 24 # Извлекаем часы.

 time /= 24 # Отбрасываем часы.

 days = time # Дни (последний остаток).

 [days, hrs, mins, sec] #
Возвращаем массив [d,h,m,s].

end

t = sec2dhms(1000000) # Миллион секунд равно...

puts "#{t[0]} days," # 11 дней,

puts "#{t[1]} hours," # 13 часов,

puts "#{t[2]} minutes," # 46 минут

puts " and #{t[3]} seconds." # и 40 секунд.

Можно было пойти и дальше. Но неделю вряд ли назовешь полезной единицей, месяц не слишком точно определен, а год не всегда содержит одно и то же число дней.

Ниже приведена также обратная функция:

def dhms2sec(days,hrs=0,min=0,sec=0)

days*86400 + hrs*3600 + min*60 + sec

end

7.7. Вычисление промежутка времени, прошедшего от точки отсчета

По разным причинам может понадобиться перейти от внутреннего (традиционного) представления времени к стандартному. В системе время хранится как число секунд, прошедших с точки отсчета.

Метод класса

Time.at
создает новый объект
Time
, зная, сколько секунд прошло с точки отсчета:

epoch = Time.at(0) # Найти точку отсчета (1 января 1970 GMT)

newmil = Time.at(978307200) # Счастливого миллениума! (1 января 2001)

Обратная функция — это метод экземпляра

to_i
, который преобразует дату в целое число.

now = Time.now # 16 Nov 2000 17:24:28

sec = now.to_i # 974424268

Если нужны микросекунды, и система поддерживает такую точность, то можно воспользоваться методом

to_f
для преобразования в число с плавающей точкой.

7.8. Високосные секунды

Вот снова день исчез, как ветра легкий стон, Из нашей жизни, друг, навеки выпал он. Но я, покуда жив, тревожиться не стану О дне, что отошел, и дне, что не рожден. [10] Омар Хайям, «Рубаи»

Хотите иметь дело с «високосными» секундами? Мой совет: не делайте этого.

Високосные секунды — это не миф. Одна была добавлена в 2005 году; его последняя минута состояла из 61 секунды, а не из 60. Библиотечные функции уже много лет учитывают возможность появления минут, состоящих из 61 секунды. Но наш опыт показывает, что большинство операционных систем високосные секунды игнорирует. Говоря «большинство», мы имеем в виду все, с которыми когда-либо сталкивались.

10

Пер. О. Румер. — Прим. ред.

Поделиться:
Популярные книги

Сердце Дракона. Том 9

Клеванский Кирилл Сергеевич
9. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.69
рейтинг книги
Сердце Дракона. Том 9

Первый среди равных. Книга III

Бор Жорж
3. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
6.00
рейтинг книги
Первый среди равных. Книга III

Эпоха Опустошителя. Том I

Павлов Вел
1. Вечное Ристалище
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Эпоха Опустошителя. Том I

Кодекс Крови. Книга ХVIII

Борзых М.
18. РОС: Кодекс Крови
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга ХVIII

Гезат

Чернобровкин Александр Васильевич
22. Вечный капитан
Фантастика:
альтернативная история
5.25
рейтинг книги
Гезат

Ну привет, заучка...

Зайцева Мария
Любовные романы:
эро литература
короткие любовные романы
8.30
рейтинг книги
Ну привет, заучка...

Бродяга

Первухин Андрей Евгеньевич
1. Бродяга
Фантастика:
попаданцы
5.40
рейтинг книги
Бродяга

На границе империй. Том 7

INDIGO
7. Фортуна дама переменчивая
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
6.75
рейтинг книги
На границе империй. Том 7

Моров. Том 1 и Том 2

Кощеев Владимир
1. Моров
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Моров. Том 1 и Том 2

Школа пластунов

Трофимов Ерофей
Одиночка
Фантастика:
боевая фантастика
5.00
рейтинг книги
Школа пластунов

Лекарь Империи 4

Карелин Сергей Витальевич
4. Лекарь Империи
Фантастика:
городское фэнтези
аниме
попаданцы
5.00
рейтинг книги
Лекарь Империи 4

Лекарь Империи

Карелин Сергей Витальевич
1. Лекарь Империи
Фантастика:
городское фэнтези
аниме
дорама
фэнтези
попаданцы
5.00
рейтинг книги
Лекарь Империи

Кодекс Крови. Книга VI

Борзых М.
6. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга VI

Распутье

Басаргин Иван Ульянович
Сибириада
Проза:
военная проза
историческая проза
5.00
рейтинг книги
Распутье