Типы данных даты и времени в PL/SQL

Типы данных и времени языка программирования PL/SQLБольшинство приложений выполняют те или иные операции со значениями даты и времени. Работать с датами довольно сложно; кроме того что приходится иметь дело с жестким форматированием данных, существует множество правил определения их допустимых значений и проведения корректных вычислений (приходится учитывать високосные годы, национальные праздники и выходные, диапазоны дат и т. д.). К счастью, СУБД Oracle и PL/SQL предоставляют набор типов данных для хранения даты и времени в стандартном внутреннем формате.

Для любого значения даты или времени Oracle сохраняет некоторые (или все) из перечисленных составляющих: год, месяц, день, час, минуты, секунды, часовой пояс, смещение часового пояса в часах, смещение часового пояса в минутах.


Оглавление статьи[Показать]


Впрочем, поддержка типов даты и времени — только часть дела. Еще необходим язык, средства которого позволяют удобно и естественно работать с этими значениями. Oracle обеспечивает разработчиков исчерпывающим набором функций для выполнения все-возможных операций с датами и временем.

В течение долгого времени для работы с датой и временем в Oracle поддерживался только тип DATE. В Oracle9i ситуация немного изменилась: появились три новых типа TIMESTAMP и два новых типа INTERVAL. Они предоставляют много новых полезных возможностей, одновременно улучшая совместимость Oracle со стандартом ISO SQL. Типы данных INTERVAL подробно рассматриваются позднее в моем блоге, а пока остановимся на четырех основных типах даты/времени.

Разобраться во всех особенностях этих типов, особенно TIMESTAMP WITH LOCAL TIME ZONE, бывает непросто. Для примера рассмотрим использование типа TIMESTAMP WITH LOCAL TIME ZONE в календарном приложении для пользователей, работающих в разных часовых поясах. В качестве времени базы данных используется всеобщее скоординированное время UTC (Universal Coordinated Time — см. далее врезку «Всеобщее скоординированное время»). Пользователь Джонатан, живущий в Мичигане (Восточный часовой пояс, смещение от UTC составляет –4:00), запланировал проведение видеоконференции с 16:00 до 17:00 в четверг по своему местному времени. У Донны из Денвера (Горный часовой пояс, смещение составляет –6:00) конференция приходится на промежуток времени с 14:00 до 15:00 в четверг. У Селвы из Индии (смещение +5:30) конференция пройдет с 01:30 до 02:30 в пятницу. На рис. 1 показано, как время начала конференции изменяется при выборке из базы данных пользователями из разных часовых поясов.

Разные типы значений даты-времени

Рис. 1. Разные типы значений даты-времени

На рис. 1 пользователь Джонатан находится в Восточном часовом поясе с действием летнего времени, в котором время отстает от UTC на 4 часа (UTC-4:00). Джонатан вводит время начала собрания 16:00. Это значение преобразуется к часовому поясу базы данных (UTC) при вставке записи, и в базе данных сохраняется значение 20:00.

Донна находится в Денвере, где также действует летнее время; текущее время отстает от UTC (UTC-6:00). Когда Донна выбирает время начала встречи, значение преобразуется к сеансовому часовому поясу и отображается в формате 14:00. Селва находится в Индии, где летнее время не действует — индийское стандартное время смещено на 5,5 часа вперед от UTC (UTC+5:30). Когда Селва выбирает время начала встречи, значение преобразуется к сеансовому часовому поясу и выводится в формате 1:30.

Поручая преобразования часовых поясов типу данных TIMESTAMP WITH LOCAL TIME ZONE, вы избавляетесь от необходимости программирования сложных правил, связанных с часовыми поясами и летним временем (которое иногда изменяется, как это было в США в 2007 году), а заодно избавляете ваших пользователей от необходимости разбираться с преобразованиями. Правильное время будет предоставляться каждому пользователю просто и элегантно.

В одних случаях база данных должна автоматически изменять формат вывода времени, в других это не нужно. Если вы не хотите, чтобы формат значения времени изменялся в соответствии с сеансовыми настройками, используйте тип данных TIMESTAMP или TIMESTAMP WITH TIME ZONE.

 

Всеобщее скоординированное время

Всеобщее скоординированное время, обозначаемое сокращением UTC (Coordinated Universal Time), измеряется с применением высокоточных атомных часов и закладывает основу для мировой системы гражданского времени. Например, все часовые пояса определяются их смещением от UTC. Время UTC измеряется по атомному эталону и периодически регулируется через механизм корректировочных секунд для поддержания синхронизации с временем, определяемым по вращению Земли.

Возможно, вы также знакомы с временем по Гринвичскому меридиану, или GMT (Greenwich Mean Time). Как правило, в практическом контексте это обозначение эквивалентно UTC.

Почему выбрано сокращение UTC, а не CUT? Комитет по стандартизации не мог решить, стоит ли использовать английское сокращение CUT или французское TUC, поэтому сошлись на сокращении UTC, которое не соответствует ни одному языку.

За дополнительной информацией о UTC обращайтесь к документации Национального института стандартов и технологий (http://www.nist.gov/pml/general/time/world.cfm) и списку FAQ (http://www.nist.gov/pml/div688/faq.cfm).

 

Объявление переменных даты и времени в PL/SQL

Синтаксис объявления переменной, представляющей дату и время, выглядит так:

имя_переменной [CONSTANT] тип [{:= | DEFAULT} исходное_значение] 

Поле тип заменяется одним из следующих типов:

DATE
TIMESTAMP [(точность)]
TIMESTAMP [(точность)] WITH TIME ZONE
TIMESTAMP [(точность)] WITH LOCAL TIME ZONE 

Значение параметра точность определяет количество десятичных цифр, выделяемое для хранения долей секунды. По умолчанию оно равно 6, то есть время может отслеживаться с точностью до 0,000001 секунды. Допускаются значения от 0 до 9, позволяющие сохранять время суток с высокой точностью.

Функции, возвращающие значения типа TIMESTAMP (например, SYSTIMESTAMP), всегда возвращают данные с шестью цифрами точности.

Несколько примеров объявлений: 

DECLARE
hire_date TIMESTAMP (0) WITH TIME ZONE;
todays_date CONSTANT DATE := SYSDATE;
pay_date TIMESTAMP DEFAULT TO_TIMESTAMP('20050204','YYYYMMDD');
BEGIN
NULL;
END;
/

Исходное_значение задается либо при помощи функции преобразования (например, TO_TIMESTAMP), либо с использованием литерала даты/времени. Оба варианта описаны далее в разделе «Преобразования даты и времени».

Поведение переменной типа TIMESTAMP(0) идентично поведению переменной типа DATE.

 

Выбор типа данных

Естественно, при таком богатстве выбора хочется понять, из каких соображений следует выбирать тип данных для представления даты/времени в той или иной ситуации. В значительной степени выбор типа данных зависит от требуемой детализации:

Также могут действовать и другие факторы:

Будьте осторожны при совместном использовании типов данных DATE и TIMESTAMP. Правила арифметических операций для этих типов сильно различаются. Будьте внимательны при использовании традиционных встроенных функций даты Oracle (таких, как ADD_MONTHS или MONTHS_BETWEEN) к значениям типов TIMESTAMP. См. далее раздел «Арифметические операции над значениями даты/времени».

 

Вас заинтересует / Intresting for you:

Управление приложениями PL/SQL...
Управление приложениями PL/SQL... 4646 просмотров Stas Belkov Thu, 16 Jul 2020, 06:20:48
Встроенные методы коллекций PL...
Встроенные методы коллекций PL... 14829 просмотров sepia Tue, 29 Oct 2019, 09:54:01
Тип данных RAW в PL/SQL
Тип данных RAW в PL/SQL 12322 просмотров Doctor Thu, 12 Jul 2018, 08:41:33
Символьные функции и аргументы...
Символьные функции и аргументы... 18582 просмотров Анатолий Wed, 23 May 2018, 18:54:01
Печать
Войдите чтобы комментировать

Pesok аватар
Pesok ответил в теме #9093 5 года 9 мес. назад
Спасибо за понятные примере по работе с переменными и константами даты и времени PL/SQL!!!
Doc аватар
Doc ответил в теме #9083 5 года 10 мес. назад
Спасибо за инфу. Искал примеры работы с TIMESTAMP WITH LOCAL TIME ZONE. Спасибо!