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

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

Жанры

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

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

Вагант

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

Антимаг его величества. Том II

Петров Максим Николаевич
2. Модификант
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Антимаг его величества. Том II

Я не князь. Книга XIII

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

Инквизитор Тьмы

Шмаков Алексей Семенович
1. Инквизитор Тьмы
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Инквизитор Тьмы

Газлайтер. Том 21

Володин Григорий Григорьевич
21. История Телепата
Фантастика:
боевая фантастика
аниме
попаданцы
5.00
рейтинг книги
Газлайтер. Том 21

Наследие Маозари

Панежин Евгений
1. Наследие Маозари
Фантастика:
рпг
попаданцы
аниме
5.80
рейтинг книги
Наследие Маозари

Вперед в прошлое 2

Ратманов Денис
2. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 2

Наследник

Кулаков Алексей Иванович
1. Рюрикова кровь
Фантастика:
научная фантастика
попаданцы
альтернативная история
8.69
рейтинг книги
Наследник

Египтолог

Филлипс Артур
136. Книга-загадка, книга-бестселлер
Детективы:
исторические детективы
6.88
рейтинг книги
Египтолог

Ларь

Билик Дмитрий Александрович
10. Бедовый
Фантастика:
городское фэнтези
мистика
5.75
рейтинг книги
Ларь

Наследник старого рода

Шелег Дмитрий Витальевич
1. Живой лёд
Фантастика:
фэнтези
8.19
рейтинг книги
Наследник старого рода

Адвокат Империи 7

Карелин Сергей Витальевич
7. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
фантастика: прочее
5.00
рейтинг книги
Адвокат Империи 7

Наследие Маозари 8

Панежин Евгений
8. Наследие Маозари
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
постапокалипсис
рпг
фэнтези
эпическая фантастика
5.00
рейтинг книги
Наследие Маозари 8

Адвокат Империи 14

Карелин Сергей Витальевич
14. Адвокат империи
Фантастика:
городское фэнтези
аниме
попаданцы
5.00
рейтинг книги
Адвокат Империи 14