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

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

Жанры

Программирование на языке 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

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

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

Неучтенный элемент. Том 1

NikL
1. Антимаг. Вне системы
Фантастика:
городское фэнтези
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 1

Медиум

Злобин Михаил
1. О чем молчат могилы
Фантастика:
фэнтези
7.90
рейтинг книги
Медиум

Мастер 3

Чащин Валерий
3. Мастер
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Мастер 3

Возвращение Безумного Бога 3

Тесленок Кирилл Геннадьевич
3. Возвращение Безумного Бога
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Возвращение Безумного Бога 3

Офицер

Земляной Андрей Борисович
1. Офицер
Фантастика:
боевая фантастика
7.21
рейтинг книги
Офицер

Чужак

Листратов Валерий
1. Ушедший Род
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Чужак

Кодекс Охотника. Книга XXXIX

Сапфир Олег
39. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
боевая фантастика
5.00
рейтинг книги
Кодекс Охотника. Книга XXXIX

Третий

INDIGO
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий

Правильный лекарь. Том 7

Измайлов Сергей
7. Неправильный лекарь
Фантастика:
городское фэнтези
аниме
попаданцы
5.00
рейтинг книги
Правильный лекарь. Том 7

Рассвет русского царства

Грехов Тимофей
1. Новая Русь
Документальная литература:
историческая литература
5.00
рейтинг книги
Рассвет русского царства

Леди Малиновой пустоши

Шах Ольга
Любовные романы:
любовно-фантастические романы
6.20
рейтинг книги
Леди Малиновой пустоши

Кодекс Охотника. Книга XIV

Винокуров Юрий
14. Кодекс Охотника
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XIV

Я все еще граф. Книга IX

Дрейк Сириус
9. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я все еще граф. Книга IX

Я уже барон

Дрейк Сириус
2. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я уже барон