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

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

Жанры

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

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

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

Империум. Антология к 400-летию Дома Романовых

Злотников Роман Валерьевич
Фантастика:
фэнтези
социально-философская фантастика
героическая фантастика
научная фантастика
боевая фантастика
альтернативная история
6.71
рейтинг книги
Империум. Антология к 400-летию Дома Романовых

Буря Жнеца

Эриксон Стивен
7. «Малазанская империя»
Фантастика:
фэнтези
6.60
рейтинг книги
Буря Жнеца

Философия Науки. Хрестоматия

Коллектив авторов
Научно-образовательная:
философия
5.00
рейтинг книги
Философия Науки. Хрестоматия

Противостояние. Том II

Кинг Стивен
Фантастика:
социально-философская фантастика
научная фантастика
ужасы и мистика
8.33
рейтинг книги
Противостояние. Том II

7 историй для девочек

Дюма-отец Александр
Детские:
детская проза
4.75
рейтинг книги
7 историй для девочек

Я уже князь. Книга XIX

Дрейк Сириус
19. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.50
рейтинг книги
Я уже князь. Книга XIX

Имаджика

Баркер Клайв
7. Книга-загадка, книга-мистика
Фантастика:
фэнтези
7.56
рейтинг книги
Имаджика

Кир Булычев. Собрание сочинений в 18 томах. Т.9

Булычев Кир
Собрания сочинений
Фантастика:
альтернативная история
6.00
рейтинг книги
Кир Булычев. Собрание сочинений в 18 томах. Т.9

Геймер. Тетралогия

Андреева Юлия Игоревна
Фантастика:
альтернативная история
6.80
рейтинг книги
Геймер. Тетралогия

Офицер

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

Сказки и истории

Андерсен Ганс Христиан
Проза:
классическая проза
6.60
рейтинг книги
Сказки и истории

Эрсус. Инферно

Павлов Вел
3. Стезя Эрсуса
Фантастика:
фэнтези
5.00
рейтинг книги
Эрсус. Инферно

Посланник

Иевлев Геннадий Васильевич
2. Страж
Фантастика:
научная фантастика
космическая фантастика
5.00
рейтинг книги
Посланник

Хаос и порядок. Прыжок в безумие

Дональдсон Стивен Ридер
4. Глубокий Космос
Фантастика:
научная фантастика
5.00
рейтинг книги
Хаос и порядок. Прыжок в безумие