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

ЖАНРЫ

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

if t3.between?(t1,t2)

 puts "t3 находится между t1 и t2"

end

# Все четыре предложения if возвращают true.

7.16 Прибавление интервала к моменту времени

Можно получить новый момент времени, прибавив к существующему интервал. Последний представляется целым числом, которое интерпретируется как число секунд.

t0 = Time.now

t1 = t0 + 60 # Ровно одна минута с момента t0.

t2 = t0 + 3600 # Ровно один час с
момента t0.

t3 = t0 + 86400 # Ровно один день с момента t0.

Может пригодиться функция

dhms2sec
(определена в разделе 7.6). Напомним, что по умолчанию параметры, соответствующие часам, минутам и секундам, равны 0.

t4 = t0 + dhms2sec(5,10) # 5 дней, 10 часов в будущем.

t5 = t0 + dhms2sec(22,18,15) # 22 дня, 18 часов, 15 минут в будущем.

t6 = t0 - dhms2sec(7) # Ровно неделю назад.

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

t6
в примере выше.

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"

Поделиться с друзьями: