Интервал состоит из одного или нескольких элементов даты/времени. Например, интервал можно выразить в годах и месяцах, часах и минутах и т. д. В табл. 1 перечислены стандартные имена всех этих элементов. Они используются в функциях преобразования типов данных и в выражениях, о чем подробно рассказывается в следующих разделах. При использовании в функциях преобразования типов имена элементов интервала не чувствительны к регистру. Например, обозначения YEAR
, Year
и year
эквивалентны.
Имя | Описание |
YEAR | Количество лет в диапазоне от 1 до 999 999 999 |
MONTH | Количество месяцев в диапазоне от 0 до 11 |
DAY | Количество дней в диапазоне от 0 до 999 999 999 |
HOUR | Количество часов в диапазоне от 0 до 23 |
MINUTE | Количество минут в диапазоне от 0 до 59 |
SECOND | Количество секунд в диапазоне от 0 до 59,999 999 999 |
Таблица 1. Стандартные имена элементов даты / времени
Преобразование чисел в интервалы
Функции NUMTOYMINTERVAL
и NUMTODSINTERVAL
предназначены для преобразования отдельных числовых значений в значения типа INTERVAL
. При вызове функции задаются числовое значение и один из элементов интервала, перечисленных в табл. 1.
Функция NUMTOYMINTERVAL
преобразует числовое значение в интервал типа INTERVAL YEAR TO MONTH
, а функция NUMTODSINTERVAL
— в интервал типа INTERVAL DAY TO SECOND
.
В следующем примере функция NUMTOYMINTERVAL
используется для преобразования значения 10.5 в значение типа INTERVAL YEAR TO
MONTH
. Второй аргумент — строка Year
— указывает, что заданное в первом аргументе число представляет количество лет:
DECLARE
y2m INTERVAL YEAR TO MONTH;
BEGIN
y2m := NUMTOYMINTERVAL (10.5,'Year');
DBMS_OUTPUT.PUT_LINE(y2m);
END;
Результат выполнения:
+10-06
Как видите, исходное значение 10.5 преобразовано в значение, соответствующее 10 годам и 6 месяцам. Любое дробное количество лет преобразуется в эквивалентное количество месяцев, и результат округляется до целого. Например, если исходное значение равно 10,9 года, оно будет преобразовано в 10 лет и 10 месяцев. В следующем примере числовое значение преобразуется в интервал типа INTERVAL DAY TO
SECOND
:
DECLARE
an_interval INTERVAL DAY TO SECOND;
BEGIN
an_interval := NUMTODSINTERVAL (1440,'Minute');
DBMS_OUTPUT.PUT_LINE(an_interval);
END;
Результат:
+01 00:00:00.000000 PL/SQL procedure successfully completed.
Oracle автоматически преобразует входное значение 1400 минут в интервал, равный одному дню. Это удобно, потому что вам не придется заниматься этой работой самостоятельно. С помощью функций NUMTO
вы сможете легко вывести любое количество минут (секунд, дней или часов) в нормализованном формате, понятном для читателя.
До появления интервальных типов вам пришлось бы самостоятельно программировать преобразование минут в правильное количество дней, часов и минут.
Преобразование строк в интервалы
Если функции NUMTO
предназначены для преобразования в интервалы числовых значений, то для преобразования символьных строк можно использовать функции TO_YMINTERVAL
и TO_DSINTERVAL
. Выбор функции зависит от того, значение какого типа вы хотите получить — INTERVAL YEAR TO MONTH
или INTERVAL DAY TO SECOND.
Функция TO_YMINTERVAL
преобразует символьную строку в значение типа INTERVAL YEAR TO MONTH
. Вызывается она так:
TO_YMINTERVAL('Y-M')
Здесь аргумент Y
представляет количество лет, а M
— количество месяцев. Обязательно должны быть заданы оба значения, разделенные дефисом.
Аналогичным образом функция TO_DSINTERVAL
преобразует символьную строку в значение типа INTERVAL DAY TO SECOND
. А вот как она вызывается:
TO_DSINTERVAL('D HH:MI:SS.FF')
Здесь D
— количество дней, а аргумент HH:MM:SS.FF
представляет часы, минуты, секунды и доли секунды.
Следующий пример демонстрирует использование обеих функций:
DECLARE
y2m INTERVAL YEAR TO MONTH;
d2s1 INTERVAL DAY TO SECOND;
d2s2 INTERVAL DAY TO SECOND;
BEGIN
y2m := TO_YMINTERVAL('40-3'); --мой возраст
d2s1 := TO_DSINTERVAL('10 1:02:10');
d2s2 := TO_DSINTERVAL('10 1:02:10.123'); --доли секунды
END;
При вызове любой из них необходимо задавать полный набор значений. Например, нельзя вызвать функцию TO_YMINTERVAL
, указав только год, или вызвать функцию TO_DSINTERVAL
без секунд. Можно опустить только доли секунды.
Форматирование интервалов для вывода
До сих пор речь шла о преобразовании интервалов и выводе данных с использованием механизма неявного преобразования значений. К сожалению, этим все и ограничивается. Интервал можно передать при вызове TO_CHAR
, но функция игнорирует маску форматирования. Например, выполнение кода
DECLARE
y2m INTERVAL YEAR TO MONTH;
BEGIN
y2m := INTERVAL '40-3' YEAR TO MONTH;
DBMS_OUTPUT.PUT_LINE(TO_CHAR(y2m,'YY "Years" and MM "Months"'));
END;
приведет к такому результату, как если бы маска отсутствовала:
+000040-03
Если вас не устраивает то, как выполняется неявное преобразование значения интервала в символьную строку, воспользуйтесь функцией EXTRACT
:
DECLARE
y2m INTERVAL YEAR TO MONTH;
BEGIN
y2m := INTERVAL '40-3' YEAR TO MONTH;
DBMS_OUTPUT.PUT_LINE(
EXTRACT(YEAR FROM y2m) || ' лет и '
|| EXTRACT(MONTH FROM y2m) || ' месяца'
);
END;
Теперь результат будет таким:
40 лет и 3 месяца
Функция EXTRACT
более подробно описана далее в разделе «CAST
и EXTRACT
».