7.17. Вычисление разности между двумя моментами времени
Можно вычислить интервал между двумя моментами времени. В результате вычитания одного объекта Timeиз другого получаем число секунд:
today = Time.local(2000,11,10)
yesterday = Time.local(2000,11,9)
cliff = today - yesterday # 86400 секунд.
И снова оказывается полезной функция sec2dhms, которая определена в разделе 7.6.
past = Time. Local(1998,9,13,4,15)
now = Time.local(2000,11,10,22,42)
diff = now - past unit = sec2dhms(diff)
puts "#{unit[0]} дней," # 789 дней,
puts "#{unit[1]} часов," # 18 часов,
puts "#{unit[2]} минут" # 27 минут
puts "и #{unit[3]} секунд." # и 0 секунд.
7.18. Работа с конкретными датами (до точки отсчета)
В стандартной библиотеке Dateесть одноименный класс для работы с датами, предшествующими полуночи 1 января 1970 года.
Несмотря на некоторое перекрытие с классом Time, между ними есть существенные различия. Самое главное состоит в том, что класс Dateвообще игнорирует время, то есть работает с точностью до одного дня. Кроме того, класс Dateстроже контролирует ошибки, чем класс Time: попытка обратиться к 31 июня (или к 29 февраля невисокосного года) приведет к исключению. Код даже «знает» о различных датах перехода на григорианский календарь в Италии и Англии (в 1582 и 1752 году соответственно) и может обнаружить «несуществующие» даты, появившиеся в результате такого перехода. Эта стандартная библиотека — паноптикум интересного и местами загадочного кода. К сожалению, у нас нет места для более подробного разговора о ней.
7.19. Взаимные преобразования объектов Date, Time и DateTime
В Ruby есть три основных класса для работы с датами и временем: Time, Dateи DateTime. Опишем их особенности:
• Класс Timeпреимущественно обертывает соответствующие функции из стандартной библиотеки языка С. Они, как правило, опираются на точку отсчета в UNIX и потому не способны представлять моменты времени раньше 1970 года.
• Класс Dateсоздан для преодоления недостатков класса Time. Он без труда справляется с датами в более отдаленном прошлом — например, позволяет представить день рождения Леонардо да Винчи (15 апреля 1452 года), и, кроме того, знает о реформе календаря. Но у него есть свои слабые места: он работает только с датами, игнорируя время.
• Класс DateTimeнаследует Dateи пытается компенсировать отсутствующие в нем возможности. Он может представлять даты не хуже Dateи время не хуже Time. Часто его способ представления даты и времени оказывается наилучшим.
Однако не думайте, что объект DateTime— это просто объект Date, к которому механически присоединен объект Time. На самом деле в классе DateTimeотсутствуют такие методы, как usec, dst?и некоторые другие.
Итак, у нас есть три класса. К сожалению, не существует стандартного способа преобразовать один из них в любой другой. По мере развития Ruby подобные шероховатости будут устраняться. А пока обойдемся методами, приведенными в листинге 7.2. Спасибо Кирку Хейнсу (Kirk Haines).
Листинг 7.2. Преобразования между классами, представляющими даты и время
class Time
def to_date
Date.new(year, month, day)
rescue NameError
nil
end
def to_datetime
DateTime.new(year, month, day, hour, min, sec)
rescue NameError
nil
end
end
class DateTime
def to_time
Time.local(year,month,day,hour,min,sec)
end
end
class Date
def to_time
Time.local(year,month,day)
end
end
Эти методы пропускают наверх все исключения, кроме NameError. Зачем нужно его перехватывать? Потому что могло случиться так, что программа не затребовала (с помощью директивы require) библиотеку date(напомним, что классы Dateи DateTimeвходят в эту стандартную библиотеку, а не являются системными). В таком случае методы to_datetimeи to_dateвозвращают nil.
7.20. Извлечение даты и времени из строки
Дата и время могут быть представлены в виде строки самыми разными способами: в полной или сокращенной форме, с разной пунктуацией, различным порядком компонентов и т.д. Из-за такого разнообразия очень сложно написать код, интерпретирующий символьную строку как дату. Рассмотрим несколько примеров:
s1 = "9/13/98 2:15am"
s2 = "1961-05-31"
s3 = "11 July 1924"
s4 = "April 17, 1929"
s5 = "20 July 1969 16:17 EDT"
Читать дальше
Конец ознакомительного отрывка
Купить книгу