Некоторые примеры нестандартных возможностей синтаксиса sql. Часть вторая: форматы дат
Данная статья посвящена форматам дат в Oracle и некоторым особенностям их обработки. В статье приведен обзор нескольких стандартных масок форматирования дат, явная и неявная конвертация строк в даты и дополнительные параметры, влияющие на этот процесс. Как и в первой части статьи, обсуждение материала происходит на основе примеров, демонстрирующих нестандартные возможности форматирования. Детально рассмотрены механизмы Oracle, участвующие в процессе неявного преобразования. Описание большинства возможностей сопровождается ссылками на соответствующие разделы документации.
Изначально я не планировал написание статьи о датах, а собирался остановиться на рассмотрении всего одного вопроса данной тематики. Однако в ходе работы возникла необходимость в освещении различных дополнительных возможностей Oracle, стали появляться новые примеры. Так рассмотрение одного вопроса разрослось в небольшую статью. Надеюсь, получилось нескучно, несмотря на не самую интересную тематику.
Первая часть статьи, посвященная особенностям оператора order by, функционированию not in и примеру неявного преобразования типов, находится здесь.
Функция to_date и форматы даты
Мало кто из программистов любит тематику форматирования. Например, на некоторых курсах темы форматирования дат и региональных стандартов специально ставят на последние часы последнего дня тренинга, т.к. слушателям нудно. Причина в большом количестве существующих форматов при относительно редком их использовании в стандартных задачах. Чаще всего маски используются в трех функциях: to_number, to_char и to_date. Во всех трех случаях маска идет вторым необязательным параметром. И если масок для форматирования чисел еще более-менее вменяемое количество, то масок для форматирования дат до неприличия много, плюс еще суффиксы и модификаторы.
Безусловно, доступность большого количества масок является позитивным моментом, поскольку расширяет возможности, например, проверить является ли 13 сентября 2011 днем программиста, можно с помощью маски ‘DDD’, которая возвращает номер дня в году:
Несмотря на явную пользу форматирования, я не планировал включать во вторую часть статьи обзор форматов дат и примеры использования экзотических масок. Во-первых, вряд ли это будет кому-то интересно, во-вторых, автор также не является большим почитателем сложного форматирования, поскольку редко его применяет в жизни. Единственная причина появления данного раздела – некоторые вопросы, возникшие у читателей по поводу использования формата RR.
Перед тем как перейти непосредственно к основной теме раздела, давайте рассмотрим несколько нестандартных примеров работы с датами.
Пример №1. Использование урезанных шаблонов
Начнем со стандартного форматирования. Пускай сегодняшняя дата 16.09.2011, выполнятся ли следующие запросы, и что они вернут?
Запрос №2 является типичным примером конвертации даты в строку с приведением ее к нужному формату. Единственное отличие – вместо более привычных масок вида ‘DD.MM.YY’ или ‘DD-MON-YYYY’ мы использовали маску, задающую только год. Запрос №2 выполнится успешно и вернет текущий год в четырехзначном формате, т.е. ‘2011’.
Запрос №3 немного интереснее, он представляет собой типичный пример явного преобразования строки в дату с урезанной маской формата, поэтому, с точки зрения синтаксиса, запрос верный и выполнится успешно. Более важным вопросом является результат его выполнения, т.е. какую дату он вернет, если задан только день? Перед ответом на данный вопрос давайте вспомним, как Oracle устанавливает время, если оно явно не задано:
В запросе №4 время не указано, в запросе №5 указано только количество минут, часы и секунды опущены. В Oracle существует правило, согласно которому, если в дате отсутствует временной компонент, то время автоматически устанавливается в значение 00:00:00 (т.е. полночь), если задана только часть элементов времени (как в запросе №5), то пропущенные элементы устанавливаются в 00. Поэтому, запрос №4 вернет строку ‘03.02.2011 00:00:00’, а запрос №5 — ‘03.02.2011 00:30:00’.
Вернемся к запросу №3, верно ли данное правило для дат, т.е. заменяются ли пропущенные при конвертации элементы даты на 00 или 01? Да заменяются, но не все, точнее, для пропущенных элементов даты используются значения из sysdate (первый день текущего месяца текущего года). Поэтому запрос №3 будет использовать 09 в качестве месяца и 2011 в качестве года, таким образом, результатом выполнения запроса будет дата 03.09.2011.
Пример №2. Порядок параметров форматирования
Выполнится ли следующий запрос, и если да, то какую дату он вернет?
На первый взгляд, отсутствие разделителей в строке с датой может показаться критическим фактором несовместимым с выполнением запроса, однако маска даты также задана без разделителей и строка для преобразования соответствует указанному шаблону. Поэтому запрос №6 выполнится успешно и вернет 20.11.2009 (формат результата может несколько отличаться в зависимости от настроек сессии). Детальнее вопросы, связанные с разделителями, мы рассмотрим в следующем примере.
Пример №3. Неявная конвертация
Пусть формат даты по умолчанию DD.MON.RR, а язык даты – русский, отработает ли следующий запрос:
В данном запросе указано два строковых параметра, которые должны быть преобразованы в даты с помощью неявной конвертации. Согласно документации, при использовании форматов по умолчанию, строка для неявного преобразования в дату должна удовлетворять шаблону: [D|DD] separator1 [MM|MON|MONTH] separator2 [R|RR|YY|YYYY]. В качестве separator1 и separator2 можно использовать большинство разделительных знаков и специальных символов, в том числе пробелы, табуляцию, а также » и удвоенную одинарную кавычку ». Более того, если в строке указано не менее двух цифр для задания дней, месяцев и лет, то separator вообще может быть опущен. Например:
Поскольку обе строки указанные в запросе №7 соответствуют приведенному шаблону, то запрос выполнится успешно и вернет число 11.
Пример №4. Параметры функции to_date
Пусть формат даты по умолчанию DD.MON.RR, а язык даты – русский, отработает ли следующий запрос:
Схожий запрос фигурировал в одном из обсуждений на странице ask Tom. Ловушка запроса в том, что мы пытаемся преобразовать дату (sysdate) в дату. Если бы запрос выглядел так:
То выполнение прошло бы успешно, и он вернул строку ’09/15/2011 23:00:11′. Однако функция to_date в качестве первого параметра ожидает строку поэтому, вначале происходит неявная конвертация даты в строку (что эквивалентно вызову to_char(sysdate) с маской по умолчанию). Результатом данной конвертации является строка ‘15.09.11’, далее происходит вызов to_date. Таким образом, запрос №11 эквивалентен следующему запросу:
Как не сложно убедиться, запрос №13 не может быть выполнен, поскольку строка ‘15.09.11’ не соответствует установленной маске, соответственно, запрос №11 так же не может быть выполнен.
Установка формата даты по умолчанию
Формат дат по умолчанию задается двумя параметрами: NLS_DATE_FORMAT (отвечает за сам формат как таковой) и NLS_DATE_LANGUAGE (отвечает за язык, который будет использован при написании названий дней, месяцев и т.д.). Если эти параметры не заданы явно, то их значения устанавливаются на основе параметра NLS_LANG.
- Уровень БД: Параметры этого уровня устанавливаются при создании БД и прописываются в файле init.ora.
- Уровень экземпляра: Параметры этого уровня устанавливаются при старте экземпляра и могут быть изменены с помощью команды ALTER SYSTEM.
- Уровень сессии: Параметры этого уровня могут быть изменены командой ALTER SESSION. Также значение данных параметров можно проверить с помощью запроса:
Логично предположить, что преобразование строки ‘11.09.11’ в дату пройдет успешно, а строки ’11.SEP.11′ – нет. Однако это не так, успешно выполнятся оба преобразования. Вначале я предполагал, что в случае невозможности преобразовать строку по маске сессии Oracle пытается задействовать маски других уровней (маска уровня БД у меня установлена в ‘DD-MON-RR’). Чтение документации показало, что это не так, и Oracle руководствуется принципами, описанными в предыдущем пункте.
Попробуем другой пример:
Если вы думаете, что результат будет идентичен предыдущему запросу, то вы ошибаетесь. Одно из преобразований не выполнится. В данном случае строка ‘11.09.11’ не удовлетворяет шаблону. Возможно, это мистика?
Увы, нет. Чтение документации показало, что существуют правила автозамены элементов форматирования даты. Ниже привожу таблицу замен.
| Original Format Element | Additional Format Elements to Try in Place of the Original |
|---|---|
| ‘MM’ | ‘MON’ and ‘MONTH’ |
| ‘MON | ‘MONTH’ |
| ‘MONTH’ | ‘MON’ |
| ‘YY’ | ‘YYYY’ |
| ‘RR’ | ‘RRRR’ |
Глядя на содержимое этой таблицы, становится понятно, что в формате ‘DD.MM.RR’ неявным образом присутствует формат ‘DD.MON.RR’ (а также ‘DD.MONTH.RR’ и другие), а вот в формате ‘DD.MON.RR’ формат ‘DD.MM.RR’ не присутствует, что и объясняет поведение запросов №14 и №15.
Пример №6. Формат RR vs YY
Большинству пользователей отличия масок RR и YY хорошо известны, однако есть и те, кому данная информация окажется полезной. Перейдем сразу к рассмотрению примера. Какие данные вернут следующие запросы:
Оба приведенных выше запроса выполнятся успешно и вернут даты в соответствии с правилами, описанными в примере №1 для запроса №3. Таким образом, значение дня во всех полученных датах будет равно 01, а значение месяца 09 (если вы выполняете запрос в сентябре). Главный вопрос, каким будет значение года?
Как несложно предположить, в запросе №16 под ’11’ я подразумевал 2011 год и обе маски мне его вернули, т.е. результат выполнения запроса №16 это 01.09.2011 и 01.09.2011.
В запросе №17 под ’99’ я подразумевал 1999 год и тут мнения масок разделились: маска RR вернула ожидаемый 1999 год, а маска YY – 2099, т.е. результат выполнения запроса №17 это 01.09.1999 и 01.09.2099.
Рассмотрим, как работают эти элементы форматирования более детально:
- If the last two digits of the current year are 00 to 49, then the returned year has the same first two digits as the current year.
- If the last two digits of the current year are 50 to 99, then the first 2 digits of the returned year are 1 greater than the first 2 digits of the current year.
- If the last two digits of the current year are 00 to 49, then the first 2 digits of the returned year are 1 less than the first 2 digits of the current year.
- If the last two digits of the current year are 50 to 99, then the returned year has the same first two digits as the current year.
Поэтому запрос №19 вернет 1950 год в обоих случаях.
Пример №7. Некоторые другие примеры
В завершение обзора рассмотрим немного экзотики. Будет ли ошибка в результате выполнения следующего запроса:
Если вы решили, что это бессмысленная запись, то вы ошибаетесь – это вполне корректное задание даты в соответствии со стандартом ANSI, запрос №20 выполнится успешно и вернет 25.12.1928.
Какой из запросов не выполнится?
Данный пример призван продемонстрировать наличие третьего параметра в функции to_date. Данный параметр позволяет установить значение одного из NLS (National Language Support) параметров только для этого вызова функции to_date. Установку NLS параметров для сессии мы рассматривали в примере №5. Ключевая разница запросов №20 и №21 состоит не в названии месяца (маска MON автоматически замещается маской MONTH, как это описано в примере №5), а в указании разных языков даты. Запрос №21 ожидает название месяца на английском и, соответственно, не выполнится, запрос №22 ожидает название месяца на русском и выполнится успешно.
В каком случае следующее объявление таблицы может приводить к возникновению ошибок при вставке данных?
Каждый раз, когда сессия с форматом даты по умолчанию ‘DD.MON.RR’ будет производить вставку с указанием только значения первого столбца будет возникать ошибка.
Особенности отображения дат в различных приложениях
Что влияет на отображение даты
Этот раздел добавлен после публикации статьи благодаря рекомендациям, указанным в комментариях. Описанное далее верно как для отображения дат, так и для отображения чисел. Возможно, при выполнении некоторых приведенных выше в статье примеров, вы получили даты в отличном от указанного в результатах формате. Если настройки вашей сессии соответствовали указанным в примерах, то это представляется, по меньшей мере, странным.
Правда заключается в том, что при выполнении запроса
вы получаете дату, но для отображения результата на экран конкретная утилита, с помощью которой вы обращаетесь к БД, должна провести конвертацию даты в строку. Таким образом, для отображения дат (и чисел) неявным образом вызывается to_char, т.е. имеем классический случай неявной конвертации (это конвертация только для вывода на экран, ее результаты не участвуют ни в каких вычислениях и ни на что кроме отображения данных не влияют). Если есть неявная конвертация, значит, существует и маска, по которой она выполняется. В классическом случае это должна быть маска, установленная для сессии, т.е. маска, указанная в параметре NLS_DATE_FORMAT таблицы nls_session_parameters, с которой мы активно работали на протяжении всей статьи.
Давайте проверим работу некоторых приложений. Проверять будем с помощью следующего скрипта:
Проверим, какие параметры для отображения дат использует sqlplus.
Рис. 1. Результат выполнения запроса №25 в sqlplus.
Как видно из рис.1, формат отображения даты меняется в зависимости от настроек сессии, т.е. sqlplus использует настройки сессии. Это упрощает понимание процесса преобразования дат в строки и обратно, поскольку и для преобразования и для отображения используются одинаковые маски.
Некоторые продвинутые средства разработки используют свои собственные NLS настройки, не имеющие отношения к настройкам Оракл. В качестве примера проверим, какие параметры для отображения дат использует PL/SQL Developer. Для этого выполним в нем запрос №25.
Рис. 2. Результат выполнения запроса №25 в PL/SQL Developer.
Как видно из рис.2, формат отображения даты не меняется при изменении настроек сессии. Более того, если посмотреть внимательно, то видно, что и первый и второй результаты вывода даты на экран не соответствовали параметрам сессии (в первом случае выведенная дата имела год в четырехзначном формате, а маска указывала год в двухзначном формате). Это означает, что утилита использует собственные NLS настройки, в случае PL/SQL Developer’а их расположение указано на рис. 3.
Рис. 3. Установка NLS параметров отображения дат в PL/SQL Developer.
Чем могут быть вредны NLS настройки утилит
Отображение даты в формате отличном от формата сессии вредно по одной причине – оно вводит пользователя в заблуждение и может привести к возникновению ошибок. Выполним в sqlplus и PL/SQL Developer следующий запрос:
В последнюю строку запроса вместо ХХХХХХХХ мы будем вставлять полученные из предыдущей строки данные.
Результаты выполнения запроса представлены на рисунках ниже.
Рис. 4. Результат выполнения запроса №26 в sqlplus.
Рис. 5. Результат выполнения запроса №26 в PL/SQL Developer.
Почему в sqlplus выведенные на экран данные были успешно конвертированы в дату, а данные выведенные на экран PL/SQL Developer’ом не смогли сконвертироваться? Потому что для конвертации Оракл использует формат данных указанный в сессии, а данные выведенные PL/SQL Developer’ом были приведены для отображения в свой формат, отличный от формата сессии.
Заключение
В качестве заключения хочу напомнить, что почти в каждом своем посте посвященном работе с датами, Том Кайт говорит о необходимости использования явных преобразований и обязательном указании маски. «При конвертации строки в дату никогда не полагайтесь на формат даты по умолчанию, всегда явно задавайте маску» — примерно так звучат его слова. Дополнительные примеры и возможные ошибки при работе с преобразованием дат вы можете найти, воспользовавшись страничкой ask Tom.
Поскольку работа с датами заняла всю статью, то «за бортом» осталось множество интересных вопросов, которые я хотел бы рассмотреть. Скорее всего, появится и третья часть статьи, как только у меня найдется свободное время.
Как пишутся датафикс на oracle
Oracle Database 12c, часть 2

Технолог сформировал шаблон соответствия для своего SQL и сделал свои данные undo временными
Временные дынные undo (Temporary Undo)
the redo is either trivial or nonexistent.
Как пишутся датафикс на oracle
Im having trouble inserting a row in my table. Here is the insert statement and table creation. This is part of a uni assignment hence the simplicity, what am i doing wrong? Im using oracle SQL developer Version 3.0.04.’
The problem i am having is that it is only inserting the dd/mon/yy but not the time. How do i get it to insert the time as well?
Thanks for the help.
EDIT: This is making no sense, i enter just a time in the field to test if time is working and it outputs a date WTF? This is really weird i may not use a date field and just enter the time in, i realise this will result in issues manipulating the data but this is making no sense.
how to insert date and time in oracle?
Im having trouble inserting a row in my table. Here is the insert statement and table creation. This is part of a uni assignment hence the simplicity, what am i doing wrong? Im using oracle SQL developer Version 3.0.04.’
The problem i am having is that it is only inserting the dd/mon/yy but not the time. How do i get it to insert the time as well?
Thanks for the help.
EDIT: This is making no sense, i enter just a time in the field to test if time is working and it outputs a date WTF? This is really weird i may not use a date field and just enter the time in, i realise this will result in issues manipulating the data but this is making no sense.
Using Data Fix
This chapter describes the actions that you can take on Data fix files using Oracle Managed Cloud Self-Service Platform:
Before Uploading Data Fix Files
This section covers some considerations before uploading Data fix files.
File Format and Object Type Considerations
All Data fix files that you upload must use the Oracle standard format and consists of only SQL, PLSQL, text, and PLS file extensions.
Attributes which are part of the Data fix file are as shown in the following list:
File Header: Specifies the file header for SQL, PLSQL, text, and PLS files.
Description: Provides a free-text description of the Data fix file. Also useful in identifying different versions of the same Data fix file.
Version: Specifies the file version, in numeric form, as identified in the header. For example, 123.1.3.
NLS Language: The supported NLS language is USA by default and no other languages are supported.
Additionally, if the Allow Auto Header check box is not selected in your Packager customer preferences, file headers are not inserted into Data fix files. Before upload, you must insert headers into all Data fix files that require them, ensuring that headers use the correct format, as described in CEMLI and Data Fix File Header Format.
If you have not created your Data Fix files, configure this setting as explained in Setting Packager Customer Preferences. Otherwise, add headers manually, using the format described in CEMLI and Data Fix File Header Format.
Uploading Data Fix Files
This section describes how to upload Data fix files to Oracle Managed Cloud Self-Service Platform.
To upload Data fix files:
- In the dashboard, click the hamburger menu ( three horizontal lines) at the top-left corner.
- In the navigation pane, under Data Fix , click Files .
All the uploaded Data Fix files are displayed.
You can search by entering a few letters of the description, Data fix file name, product, file type, or upload details.
Oracle Dates, Timestamps and Intervals
The way the Oracle database handles datetime values is pretty straightforward, but it seems to confuse many client-side and PL/SQL developers alike. The vast majority of problems people encounter are because of a misunderstanding about how dates are stored in the database. What you see on screen from a query is what’s in the database right? Well actually, that is often not the case.
Client tools, like SQL*Plus, convert datetime column values into something much nicer to look at. In the process, they often miss out very important information that can confuse you if you are not careful. The following examples use the DATE type, but the issues apply equally to the TIMESTAMP type.
So both columns contain the same value right?
Both DATE and TIMESTAMP columns contain a time component, which does not match in this case. SQL*Plus has converted the internal representation of the date into a nice string for us, but it has left out the time component. Why has it done this? Because it has used the format mask specified by the NLS_DATE_FORMAT parameter to decide how to implicitly convert the date to a string. You can display the current database, instance and session NLS parameter values using this script. To get the full data we have to either explicitly ask for it using the TO_CHAR function with a format mask.
Or set the NLS_DATE_FORMAT to the desired format mask.
Another common mistake is when you specify a date as a string.
That string looks perfectly acceptable to me, because I understand the variations in date formats and that looks like a UK representation of «27th April 2013» to me, but the database doesn’t know that. To remedy this, we must either explicitly use the TO_DATE function with a format mask, set the NLS_DATE_FORMAT appropriately, or use an ANSI DATE literal.
When using Oracle DATE or TIMESTAMP values, remember the following simple rules and you will probably avoid most of the common pitfalls.
- Both DATE and TIMESTAMP types *always* contain a date and time component. At exactly midnight the time is 00:00:00.
- Never rely on implicit conversions of strings to dates, or dates to strings. Always explicitly perform the conversions with the TO_CHAR , TO_DATE and TO_TIMESTAMP functions, or use ASNI DATE or TIMESTAMP literals.
- When doing date or timestamp comparisons, always consider the impact of the time component. If you want to discount the time component from the comparison, use the TRUNC or ROUND functions to remove it from both sides of the comparison.
The remainder of this article will discuss the DATE , TIMESTAMP and INTERVAL types in more detail.
The DATE datatype is used by Oracle to store all datetime information where a precision greater than 1 second is not needed. Oracle uses a 7 byte binary date format which allows Julian dates to be stored within the range of 01-Jan-4712 BC to 31-Dec-9999 AD. The following table shows how each of the 7 bytes is used to store the date information.
| Byte | Meaning | Notation | Example (10-JUL-2004 17:21:30) |
|---|---|---|---|
| 1 | Century | Divided by 100, excess-100 | 120 |
| 2 | Year | Modulo 100, excess-100 | 104 |
| 3 | Month | 0 base | 7 |
| 4 | Day | 0 base | 10 |
| 5 | Hour | excess-1 | 18 |
| 6 | Minute | excess-1 | 22 |
| 7 | Second | excess-1 | 31 |
The following example uses the dump function to show the contents of a stored date.
Comparing the date and dump values we see that subtracting 100 from the century component then multiplying the resulting value by 100 gives a value of 2000. Subtracting the 100 from the year component gives a value of 4. The month and day components need no modification, while subtracting 1 from the hour, minute and second components (18, 22 and 31) give values of 17, 21 and 30.
Since dates are actually numbers, certain simple mathematical operations to can be performed on them. Adding a whole number to a date is like adding the equivalent number of days, while adding a fraction to a date is like adding that fraction of a day to the date. The same is true in reverse for subtraction. The following table shows how each specific time periods can be calculated. All three expressions equate to the same value, so pick the one you prefer.
| Period | Expression 1 | Expression 2 | Expression 3 | Value |
|---|---|---|---|---|
| 1 Day | 1 | 1 | 1 | 1 |
| 1 Hour | 1/24 | 1/24 | 1/24 | .041666667 |
| 1 Minute | 1/24/60 | 1/(24*60) | 1/1440 | .000694444 |
| 1 Second | 1/24/60/60 | 1/(24*60*60) | 1/86400 | .000011574 |
The following query shows how we might use these expressions to modify the value of the current operating system date.
Oracle provides several date functions to make date manipulation simpler. The following table lists a selection of them and examples of their usage.
Returns the current date-time from the operating system of the database server.
Similar to the sysdate function, but returns the current date-time within the sessions time zone.
Adds or subtracts the specified number of months from the specified date.
Returns the last day of the month that contains the specified date.
Returns the number of months between two dates. If the first date is prior to the second, the result is negative, otherwise it is positive. If both dates are on the same day of the month, or both the last day of the month the returned value is an integer, otherwise the return value includes a fraction of the month difference.
Returns the date of the first day that matches the specified day that occurs after the specified date.
Converts a date from timezone1 into the appropriate date for timeszone2.
Converts a specified date to a string using the specified format mask. If the format mask is omitted the NLS_DATE_FORMAT value is used. There is also an overload of this function to deal with timestamps where the default format mask is take from the NLS_TIMESTAMP_FORMAT or NLS_TIMESTAMP_TZ_FORMAT value.
Converts a specified string to a date using the specified format mask. If the format mask is omitted the NLS_DATE_FORMAT value is used.
Returns a date rounded to the level specified by the format. The default value for the format is DD, returning the date without the fractional (time) component, making it represent midnight on the specified date, or the following date depending on the rounding.
Returns a date truncated to the level specified by the format. The default value for the format is DD, truncating the fractional (time) component, making it represent midnight on the specified date. Using the TRUNC function allows comparison of dates without the time components distracting from the true meaning of the comparison. It is similar to the round function, except that it always rounds down.
The ROUND and TRUNC functions can be especially useful, so we will discuss their format models in more detail. The table below lists some of the available format models, their meanings and examples of their usage. The dates have been adjusted where necessary to show the difference between the return values of the functions.
To the first year of the century (1901, 2001, 2101 etc.)
To the year. Rounds up on January 1st.
To the ISO Year.
To the quarter, rounding up on the 16th day of the second month.
To the month, rounding up on the 16th day.
To the same day of the week as the first day of the year.
To the same day of the week as the first day of the ISO year.
To the same day of the week as the first day of the month.
To the starting day of the week.
Next we will discuss the TIMESTAMP datatype, which has many similarities with the DATE datatype.
TIMESTAMP
The TIMESTAMP datatype is an extension on the DATE datatype. In addition to the datetime elements of the DATE datatype, the TIMESTAMP datatype holds fractions of a second to a precision between 0 and 9 decimal places, the default being 6. There are also two variants called TIMESTAMP WITH TIME ZONE and TIMESTAMP WITH LOCAL TIME ZONE . As their names imply, these timestamps also store time zone offset information.
Like dates, timestamps are stored using a binary date format. In the case of a TIMESTAMP this is 11 bytes long, while those with timezone information require 13 bytes. The following table shows how each of the 11-13 bytes is used to store the timestamp information.
| Byte | Meaning | Notation | Example (10-JUL-2004 17:21:30.662509 +01:00) |
|---|---|---|---|
| 1 | Century | Divided by 100, excess-100 | 120 |
| 2 | Year | Modulo 100, excess-100 | 104 |
| 3 | Month | 0 base | 7 |
| 4 | Day | 0 base | 10 |
| 5 | Hour | excess-1 (-offset) | 17 |
| 6 | Minute | excess-1 | 22 |
| 7 | Second | excess-1 | 31 |
| 8 | Fraction of a second | 9 digit integer stored in 4 bytes | 39,125,21,200 |
| 9 | |||
| 10 | |||
| 11 | |||
| 12 | Timezone Hour | excess-20 | 21 |
| 13 | Timezone Min | excess-60 | 60 |
The following example uses the dump function to show the contents of a stored timestamp.
The first 7 components match those of the DATE datatype, although they can look confusing due to the action of the offset. In this example the offset of +01:00 makes the hour component appear to be in 0 base notation rather than excess-1, but when we add the offset we can clearly see it is not. The offset component represents the number of minutes the time is offset due to the timezone.
The mathematical operations and most of the date functions mentioned previously are also valid for timestamps. In addition to the date functions Oracle provides several timestamp specific functions listed in the table below.
Returns the current TIMESTAMP from the operating system of the database server to the specified precision. If no precision is specified the default is 6.
Similar to the SYSTIMESTAMP function, but returns the current TIMESTAMP WITH TIME ZONE within the sessions time zone to the specified precision. If no precision is specified the default is 6.
Similar to the current_timestamp function, but returns the current TIMESTAMP with time zone within the sessions time zone to the specified precision. If no precision is specified the default is 6.
Converts a specified string to a TIMESTAMP using the specified format mask. If the format mask is omitted the NLS_TIMESTAMP_FORMAT or NLS_TIMESTAMP_TZ_FORMAT value is used depending on the context.
Converts a specified string to a TIMESTAMP WITH TIME ZONE using the specified format mask. If the format mask is omitted the NLS_TIMESTAMP_FORMAT or NLS_TIMESTAMP_TZ_FORMAT value is used depending on the context.
Converts a TIMESTAMP and a string representing the time zone to a TIMESTAMP WITH TIME ZONE .
Returns the database time zone.
Returns the current sessions time zone.
Returns the UTC, or GMT timestamp from a specified TIMESTAMP WITH TIME ZONE .
Extracts the specified datepart from the specified timestamp.
Next we will see how to convert between timestamps and dates.
Converting Between Timestamps and Dates
The CAST function can be used to convert a TIMESTAMP to a DATE and vice versa. First let’s convert a TIMESTAMP to a DATE .
To convert a DATE to a TIMESTAMP do the following.
Next we will see how intervals can be stored in the database and defined using the interval literal syntax.
INTERVAL
Intervals provide a way of storing a specific period of time that separates two datetime values. There are currently two supported types of interval, one specifying intervals in years and months, the other specifying intervals in days, hours, minutes and seconds. The syntax of these datatypes is shown below.
The precision elements are defined as follows.
- year_precision – The maximum number of digits in the year component of the interval, such that a precision of 3 limits the interval to a maximum of 999 years. The default value is 2.
- day_precision – The maximum number of digits in the day component of the interval, such that a precision of 4 limits the interval to a maximum of 9999 days. The day precision can accept a value from 0 to 9, with the default value being 2.
- fraction_second_precision – The number of digits in the fractional component of the interval. Values between 0 and 9 are allowed, with the default value being 6.
The following table is created to show how intervals can be used as column definitions.
Interval literals are used to define intervals in an easy to understand manner. There are two separate syntax definitions, one for each type of interval. The full syntax definitions can be a little confusing so we will skip those in favor of examples that should make their usage clear.
First we will start with the YEAR TO MONTH interval literal syntax. The default precision for the fields is listed below, along with the allowable values if specified as a trailing field.
- YEAR — Number of years with a default precision of 2 digits.
- MONTH — Number of months with a default precision of 4 digits. If specified as a trailing field it has allowable values of 0 to 11.
| Interval Literal | Meaning |
|---|---|
| INTERVAL ’21-2′ YEAR TO MONTH | An interval of 21 years and 2 months. |
| INTERVAL ‘100-5’ YEAR(3) TO MONTH | An interval of 100 years and 5 months. The leading precision is specified, as it is greater than the default of 2. |
| INTERVAL ‘1’ YEAR | An interval of 1 year. |
| INTERVAL ’20’ MONTH | An interval of 20 months. |
| INTERVAL ‘100’ YEAR(3) | An interval of 100 years. The precision must be specified as this value is beyond the default precision. |
| INTERVAL ‘10000’ MONTH(5) | An interval of 10,000 months. The precision must be specified as this value is beyond the default precision. |
| INTERVAL ‘1-13’ YEAR TO MONTH | Error produced. When the leading field is YEAR the allowable values for MONTH are 0 to 11. |
These intervals can be tested by substituting them into the following query. Notice how month syntax is converted into a years and months value.
A YEAR TO MONTH interval can be added to, or subtracted from, another with the result being another YEAR TO MONTH interval.
The following examples relate to the DAY TO SECOND interval literal syntax. As with the previous example, if a trailing field is specified it must be less significant than the previous field.
- DAY — Number of days with a default precision of 2 digits.
- HOUR — Number of hours with a default precision of 3 digits. If specified as a trailing field it has allowable values of 0 to 23.
- MINUTE — Number of minutes with a default precision of 5 digits. If specified as a trailing field it has allowable values of 0 to 59.
- SECOND — Number of seconds with a default precision of 7 digits before the decimal point and 6 digits after. If specified as a trailing field is has allowable values of 0 to 59.999999999.
| Interval Literal | Meaning |
|---|---|
| INTERVAL ‘2 3:04:11.333’ DAY TO SECOND(3) | 2 days, 3 hours, 4 minutes, 11 seconds and 333 thousandths of a second. |
| INTERVAL ‘2 3:04’ DAY TO MINUTE | 2 days, 3 hours, 4 minutes. |
| INTERVAL ‘2 3’ DAY TO HOUR | 2 days, 3 hours. |
| INTERVAL ‘2’ DAY | 2 days. |
| INTERVAL ’03:04:11.333′ HOUR TO SECOND | 3 hours, 4 minutes, 11 seconds and 333 thousandths of a second. |
| INTERVAL ’03:04′ HOUR TO MINUTE | 3 hours, 4 minutes. |
| INTERVAL ’40’ HOUR | 40 hours. |
| INTERVAL ’04:11.333′ MINUTE TO SECOND | 4 minutes, 11 seconds and 333 thousandths of a second. |
| INTERVAL ’70’ MINUTE | 70 minutes. |
| INTERVAL ’70’ SECOND | 70 seconds. |
| INTERVAL ’03:70′ HOUR TO MINUTE | Error produced. When the leading field is specified the allowable values for the trailing field must be within normal range. |
Substituting the above intervals into the following query will allow you to test them. Notice how the default precision for seconds is used because we have not limited it to 3 decimal places.
A DAY TO SECOND interval can be added to, or subtracted from, another with the result being another DAY TO SECOND interval.
Intervals can also be combined with dates to manipulate date values. The following query shows how.
Oracle provides several interval specific functions, which are listed in the table below.
Converts the specified integer to a YEAR TO MONTH interval where the integer represents the number of units.
Converts the specified integer to DAY TO SECOND interval where the integer represents the number of units.
Converts a string representing an interval into a YEAR TO MONTH interval.
Converts a string representing an interval into a DAY TO SECOND interval.
how to insert date and time in oracle?
Im having trouble inserting a row in my table. Here is the insert statement and table creation. This is part of a uni assignment hence the simplicity, what am i doing wrong? Im using oracle SQL developer Version 3.0.04.’
The problem i am having is that it is only inserting the dd/mon/yy but not the time. How do i get it to insert the time as well?
Thanks for the help.
EDIT: This is making no sense, i enter just a time in the field to test if time is working and it outputs a date WTF? This is really weird i may not use a date field and just enter the time in, i realise this will result in issues manipulating the data but this is making no sense.