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

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

Жанры

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

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"

s6 = "Mon Nov 13 2000"

s7 = "August 24, 79" # День разрушения Помпеи.

s8 = "8/24/79"

К счастью, большую часть работы за нас уже проделали. В модуле

ParseDate
есть единственный класс с таким же именем, а в нем — единственный метод
parsedate
. Он возвращает массив компонентов даты в следующем порядке: год, месяц, день, час, минута, секунда, часовой пояс, день недели. Вместо полей, которые не удалось распознать, возвращается
nil
.

require "parsedate.rb"

include ParseDate

p parsedate(s1) # [98, 9, 13, 2, 15, nil, nil, nil]

p parsedate(s2) # [1961, 5, 31, nil, nil, nil, nil, nil]

p parsedate(s3) # [1924, 7, 11, nil, nil, nil, nil, nil]

p parsedate(s4) # [1929, 4, 17, nil, nil, nil, nil, nil]

p parsedate(s5) # [1969, 7, 20, 16, 17, nil, "EDT", nil]

p parsedate(s6) # [2000, 11, 13, nil, nil, nil, nil, 1]

p parsedate(s7) # [79, 8, 24, nil, nil, nil, nil, nil]

p parsedate(s8,true) # [1979, 8, 24, nil, nil, nil, nil, nil]

Последние две строки иллюстрируют назначение второго параметра

parsedate
, который называется
guess_year
. Из-за привычки записывать год двумя цифрами может возникнуть неоднозначность. Последние две строки интерпретируются по-разному; при разборе
s8
мы установили значение
guess_year
равным
true
, вследствие чего программа сочла, что имеется в виду четырехзначный год. С другой стороны,
s7
— это дата извержения Везувия в 79 году, так что двузначный год был употреблен сознательно.

Правило применения параметра

guess_year
таково: если год меньше 100 и
guess_year
равно
true
, преобразовать в четырехзначный год. Преобразование выполняется так: если год больше либо равен 70, прибавить к нему 1900, в противном случае прибавить 2000. Таким образом, 75 преобразуется в 1975, а 65 — в 2065. Такое правило применяется программистами повсеместно.

А что сказать о строке

s1
, в которой, вероятно, имелся в виду 1998 год? Не все потеряно, если полученное число передается другому фрагменту программы, который интерпретирует его как 1998.

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

Идеальный мир для Лекаря 24

Сапфир Олег
24. Лекарь
Фантастика:
городское фэнтези
попаданцы
5.00
рейтинг книги
Идеальный мир для Лекаря 24

Я до сих пор не царь. Книга XXVII

Дрейк Сириус
27. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я до сих пор не царь. Книга XXVII

Вернуть невесту. Ловушка для попаданки 2

Ардова Алиса
2. Вернуть невесту
Любовные романы:
любовно-фантастические романы
7.88
рейтинг книги
Вернуть невесту. Ловушка для попаданки 2

Вторая жизнь майора. Цикл

Сухинин Владимир Александрович
Вторая жизнь майора
Фантастика:
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Вторая жизнь майора. Цикл

Петля, Кадетский корпус. Книга восьмая

Алексеев Евгений Артемович
8. Петля
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Петля, Кадетский корпус. Книга восьмая

Эволюционер из трущоб. Том 8

Панарин Антон
8. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб. Том 8

Возмутитель спокойствия

Владимиров Денис
1. Глэрд
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Возмутитель спокойствия

Одинаковые. Том 3. Индокитай

Алмазный Петр
3. Братья Горские
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Одинаковые. Том 3. Индокитай

Мастер 8

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

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

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

Ученик

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

Барон не признает правила

Ренгач Евгений
12. Закон сильного
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Барон не признает правила

Двойник короля 11

Скабер Артемий
11. Двойник Короля
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Двойник короля 11

Неудержимый. Книга XV

Боярский Андрей
15. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга XV