что такое timestamp sql

Datetime или timestamp

На днях я столкнулся с тем, что многие разработчики не знают в чём отличие типов данных DATETIME и TIMESTAMP в MySQLе, а так же как хранить дату и время, если необходимо учитывать разные часовые пояса для разных пользователей веб-приложения. Поэтому хочу дать ниже разъяснения с пояснениями.

DATETIME
Хранит время в виде целого числа вида YYYYMMDDHHMMSS, используя для этого 8 байтов. Это время не зависит от временной зоны. Оно всегда отображается при выборке точно так же, как было сохранено, независимо от того какой часовой пояс установлен в MySQL. Даю пример:

mysql> create table `dt1` ( col datetime NOT NULL );
mysql> SET @@session.time_zone=’+00:00′;
mysql> select now();
+———————+
| now() |
+———————+
| 2009-06-04 18:13:56 |
+———————+

mysql> insert into dt1 values(now());

mysql> insert into dt1 values(now());

TIMESTAMP
Хранит 4-байтное целое число, равное количеству секунд, прошедших с полуночи 1 января 1970 года по усреднённому времени Гринвича (т.е. нулевой часовой пояс, точка отсчёта часовых поясов). При получении из базы отображается с учётом часового пояса. Часовой пояс может быть задан в операционной системе, глобальных настройках MySQL или в конкретной сессии. Запомните, что сохраняется всегда количество секунд по UTC (универсальное координированное время, солнечное время на меридиане Гринвича), а не по локальному часовому поясу. Пример:

Ещё одно отличие! TIMESTAMP по умолчанию NOT NULL, а его значение по умолчанию равно NOW().

mysql> insert into dt1 values(null);
ERROR 1048 (23000): Column ‘col’ cannot be null
mysql> insert into tm1 values(null);
Query OK, 1 row affected (0.00 sec)
mysql> select * from tm1;
+———————+
| col |
+———————+
| 2009-06-04 18:25:08 |
| 2009-06-04 18:25:26 |
| 2009-06-04 18:32:50 |
+———————+

Дополнение. Для тех, кого смущает использование функции NOW().

Источник

CURRENT_TIMESTAMP (Transact-SQL)

Эта функция возвращает текущую системную метку времени базы данных в виде значения datetime без смещения часового пояса базы данных. CURRENT_TIMESTAMP наследует это значение от операционной системы компьютера, на котором работает экземпляр SQL Server.

Эта функция ANSI SQL эквивалентна функции GETDATE.

Обзор всех типов данных и функций даты и времени в языке Transact-SQL см. в статье Типы данных и функции даты и времени.

Синтаксические обозначения в Transact-SQL

Синтаксис

Ссылки на описание синтаксиса Transact-SQL для SQL Server 2014 и более ранних версий, см. в статье Документация по предыдущим версиям.

Аргументы

Эта функция не имеет аргументов.

Тип возвращаемых данных

datetime

Remarks

Функция CURRENT_TIMESTAMP может использоваться в инструкциях Transact-SQL везде, где допустимо использование выражения datetime.

CURRENT_TIMESTAMP является недетерминированной функцией. Невозможно проиндексировать представления и выражения, ссылающиеся на этот столбец.

Примеры

В приведенных ниже примерах с помощью шести системных функций SQL Server, которые возвращают текущую дату и время, возвращается дата, время или дата и время. Значения возвращаются последовательно, поэтому могут различаться на доли секунды. Обратите внимание на то, что возвращаемые значения будут соответствовать фактическим дню и времени выполнения.

Источник

Как работать с метками времени (timestamp) в PostgreSQL?

Тема работы с временными метками в PostgreSQL плохо раскрыта в русскоязычных профильных публикациях в Интернете и служит частым источником проблем в работе программистов. Предлагаю вашему вниманию перевод материала от Hubert Lubaczewski, автора популярного зарубежного блога depesz.com. Надеюсь, статья будет для вас полезна!

Время от времени в IRC или в почтовых рассылках кто-нибудь задает вопросы, которые показывают глубокое непонимание (или недостаток понимания) меток времени, особенно тех, которые учитывают часовые пояса. Так как я уже сталкивался с этим ранее, позвольте мне рассказать, что такое timestamps, как с ними работать и с какими наиболее распространенными загвоздками вы можете столкнуться.

У нас есть два типа данных, которые мы можем использовать:

Давайте представим, что у вас есть временная метка “2014-04-04 20:00:00″. О чем она вам говорит? К сожалению, не о многом. Всё зависит от того, о какой точке планеты идет речь. Восемь вечера 4-го апреля – это разный момент времени в Лос Анджелесе, Чикаго, Лондоне, Варшаве или Москве. В этом проблема часовых поясов.

Конечно, вы можете подумать: «Я всегда буду в одном часовом поясе, мне не нужно заморочек с поддержкой разных временных зон. В моем часовом поясе даты и времени будет вполне достаточно, чтобы отметить какой-либо момент времени, ведь именно так мы делаем в «реальной жизни».

Но так ли это на самом деле?

Представим, что у вас есть метка ‘2013-10-27 02:00:00′, и вы знаете, что ваше приложение привязано к польскому времени. В этом случае, вам уже не повезло, потому что это может быть 2 часа ночи по центрально-европейскому летнему времени (CEST) или на час больше, по обычному центрально-европейскому времени. Всё из-за сезонного перевода часов.

Я считаю, что использование временных меток без часового пояса почти всегда является багом, и его нужно исправлять. Проблем становится еще больше, если, записи в вашем приложении поступают из разных часовых поясов (например, приложение-планировщик).

Так что самое очевидное решение – использовать метки времени с часовыми поясами (timestamptz).

Во-первых, это не займет больше места на диске:

Как же это работает? Метка должна знать часовой пояс, так почему же для этого не требуется больше места?

Дело в том, что она не знает часовой пояс. Внутри, все значения в колонках timestamptz указаны в формате UTC (всемирное координированное время).

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

Читайте также:  что делать если упал в стекловату

Но если всё время указывать по UTC, то как я узнаю время в нужном мне часовом поясе?

Каждый раз, когда речь идет о значениях timestamptz, если часовой пояс не указан, то PostgreSQL использует заранее сконфигурированное время. И вы можете конфигурировать его разными способами:

Следующие два способа меняют значение по-умолчанию для выбранной базы данных и пользователя.

Последний способ можно использовать, если вы хотите, чтобы ваше соединение с базой данных работало с иными настройками.

Примите во внимание, как при этом меняется вывод now():

Так что каждый раз, когда вы просматриваете или меняете значения timestamptz, PostgreSQL конвертирует их в/из UTC.

Это значит, что значения можно легко сравнивать (все они в одном часовом поясе, нет сдвигов на летнее или зимнее время, так что сравнение всегда возможно).

Что произошло? Почему не показывается 8 вечера?

Причина проста – в запрос я вставил timestamp в каком-то часовом поясе. Внутри, метка была сконвертирована в UTC, а затем, снова сконвертирована (возможно, даже без UTC, я не уверен) в мой обычный часовой пояс, которым является:

Если бы у меня был установлен часовой пояс Лос Анджелеса, то результат запроса был бы таким:

Важно понимать, что выводимое значение всегда принимает во внимание настройку часового пояса.

Есть еще один способ получить 20:00 в Лос Анджелесе:

Очень важно добавлять “::timestamp» после значения, иначе мы получим что-то странное:

Что здесь произошло? Откуда взялось 11:00?

Значение в кавычках (2014-04-04 20:00:00) воспринимается как timestamptz, что значит 8 вечера в моём часовом поясе:

И только после перевода значения в мой часовой пояс PG считывает “at time zone …», которая используется для отображения времени в выбранном часовом поясе.

Таким образом, timestamp at time zone выдаёт значение timestamptz, которое показывает момент, когда местное время в выбранном часовом поясе было таким, как указано в команде.

А timestamptz at time zone выдаёт значение timestamp, которое показывает, каким было время в выбранном часовом поясе в указанный момент времени.

Это звучит немного путанно, поэтому давайте я приведу примеры:

Интересно то, что мы можем использовать это для перевода времени из одного часового пояса в другой, даже если Pg не находится ни в одном из них.

Допустим, мы хотим узнать, который час в Лос Анджелесе, когда в Москве — 8 утра. Моё местное время следующее:

Пользы от него мало.

Для начала нам нужно определить точку во времени (в формате timestamptz), которая показывает 8 утра в Москве:

Это говорит мне о том, что она соответствует 6 утра в моём часовом поясе. Но мы хотим узнать время в Лос Анджелесе. Я мог бы написать ‘2014-04-04 06:00:00+02′ в часовом поясе ‘LA’, но можно сделать по-другому:

Надеюсь, теперь вам всё ясно. Я сам довольно долго пытался разобраться в этом вопросе, и наконец-то всё понял 🙂

У всего этого есть один интересный побочный эффект: не так-то просто добавить индексы к функциям, работающим с timestamptz. Например, вы не можете создать индекс, который будет использоваться для получения дня недели:

Как показано в примере выше, причина очень проста – одна и та же точка во времени может относиться к разным дням недели в зависимости от часового пояса. А поскольку to_char() использует текущий часовой пояс, он может выдавать разные значения для одних и тех же исходных данных в зависимости от настроек часового пояса в системе:

Одна и та же точка во времени, но разные дни. Это могут быть разные месяцы или даже разные года, в зависимости от того, где это было.

Временная метка (без часового пояса) здесь “проявляет” сильную сторону – так как в ней не указан часовой пояс, её можно спокойно использовать для извлечения информации.

Но мы же знаем, как переводить timestamptz в timestamp. Нужно просто указать ей часовой пояс. Поэтому мы можем попробовать сделать так:

Но, к сожалению, ничего не выходит. Дело в том, что to_char слишком разносторонний. Вы можете использовать to_char вот так:

На этот раз мы получаем другие результаты не из-за часового пояса, а из-за локали.

Правильным решением проблемы индексирования будет написать свою собственную функцию, которая будет вызывать to_char в абсолютно постоянной «среде», а затем ее уже индексировать. Вот так:

А теперь мы можем использовать ее для индексирования:

Это безопасно, потому что сама функция заставляет часовой пояс принимать значение «Poland», и она вызывает to_char таким образом, чтобы игнорировать значение локали (другими словами, в формате to_char нет префикса TM).

Естественно, чтобы воспользоваться этим индексом, все запросы должны также использовать эту функцию:

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

Интересно то, что оно не зависит от часового пояса:

Причина, известная не всем, кроется в том, что время Unix всегда принимается в часовом поясе UTC. Это значит, что, когда вы извлекаете эпоху из временной метки timestamp, PG предполагает, что она находится в UTC. Из чего вытекают следующие потенциальные проблемы:

В первом случае Pg получает «точку во времени», которая внутренне конвертируется в UTC (а когда отображается – преобразовывается в мой часовой пояс, +2).

Во втором случае временная метка находится в моём часовом поясе, но предполагается, что это UTC (без конвертации!), и эпоха берется от значения ‘2014-04-04 21:19:01.456205 UTC’, а не ‘2014-04-04 21:19:01.456205+02′.

Короче говоря, старайтесь избегать timestamp и используйте timestamptz.

Последнее, о чём я хотел бы сказать – это не баг или потенциальная проблема, а скорее функциональность, о которой многие не знают.

Читайте также:  что делать если чугунная сковорода покрылась ржавчиной

Как вы видели, PostgreSQL использует timestamp (и timestamptz) с точностью до микросекунд. Многие люди настаивают на том, чтобы точность была только до секунды, хотя лично мне это не нравится.

И timestamp, и timestamptz (и другие виды данных, относящиеся ко времени) могут иметь дополнительную точность (“precision”).

Давайте я приведу простой пример:

Конечно, вы можете использовать это и в таблицах:

Отлично! Вам не нужно менять “now()» или что-либо еще, просто добавьте точность к типу данных, и она всё скорректирует.

Я упомянул, что мне это не нравится. Причина проста – в любой достаточно нагруженной системе секунда – слишком низкий уровень точности. Тем более, что хранение данных с точностью до микросекунды ничего мне не стоит, но может быть полезным. С другой стороны, если данные до микросекунд, то как мне сделать, чтобы значения отображались без долей секунды?

Все просто: я использую (в запросах SELECT) фунуции to_char(), или date_trunc, или даже приведение к типу timestamptz(0):

Более подробно о том, как работать с timestamps, мы собираемся рассказать на конференции PG Day’16 Russia в июле 2016 года! Готовьте свои вопросы, мы постараемся на них ответить.

Источник

Типы данных и функции даты и времени (Transact-SQL)

В разделах этой статьи представлен обзор всех типов данных и функций даты и времени Transact-SQL.

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

Типы данных даты и времени Transact-SQL перечислены в следующей таблице:

Тип данных Формат Диапазон Точность Объем памяти (в байтах) Определяемая пользователем точность в долях секунды Смещение часового пояса
time чч:мм:сс[.ннннннн] От 00:00:00.0000000 до 23:59:59.9999999 100 наносекунд от 3 до 5 Да Нет
date ГГГГ-ММ-ДД От 0001-01-01 до 31.12.99 1 день 3 Нет Нет
smalldatetime ГГГГ-ММ-ДД чч:мм:сс От 01.01.1900 до 06.06.2079 1 минута 4 нет Нет
datetime ГГГГ-ММ-ДД чч:мм:сс[.ннн] От 01.01.1753 до 31.12.9999 0,00333 секунды 8 Нет Нет
datetime2 ГГГГ-ММ-ДД чч:мм:сс[.ннннннн] От 0001-01-01 00:00:00.0000000 до 9999-12-31 23:59:59.9999999 100 наносекунд От 6 до 8 Да Нет
datetimeoffset ГГГГ-ММ-ДД чч:мм:сс[.ннннннн] [+|-]чч:мм От 0001-01-01 00:00:00.0000000 до 9999-12-31 23:59:59.9999999 (время в формате UTC) 100 наносекунд От 8 до 10 Да Да

Тип данных Transact-SQL rowversion не относится к типам данных даты и времени. Тип данных timestamp является устаревшим синонимом rowversion.

Функции даты и времени

В следующих таблицах приводятся функции даты и времени Transact-SQL. Дополнительные сведения о детерминизме см. в статье Детерминированные и недетерминированные функции.

Функции, возвращающие значения системной даты и времени

Transact-SQL наследует все значения системной даты и времени от операционной системы компьютера, на котором работает экземпляр SQL Server.

Высокоточные функции системной даты и времени

SQL Server 2019 (15.x) получает значения даты и времени с помощью функции GetSystemTimeAsFileTime() Windows API. Точность зависит от физического оборудования и версии Windows, в которой запущен экземпляр SQL Server. Точность возвращаемых значений этого API-интерфейса задана равной 100 нс. Точность может быть определена с помощью метода GetSystemTimeAdjustment() API-интерфейса Windows.

Источник

Что такое timestamp sql

Таблица 8.9. Типы даты/времени

Имя Размер Описание Наименьшее значение Наибольшее значение Точность
timestamp [ ( p ) ] [ without time zone ] 8 байт дата и время (без часового пояса) 4713 до н. э. 294276 н. э. 1 микросекунда
timestamp [ ( p ) ] with time zone 8 байт дата и время (с часовым поясом) 4713 до н. э. 294276 н. э. 1 микросекунда
date 4 байта дата (без времени суток) 4713 до н. э. 5874897 н. э. 1 день
time [ ( p ) ] [ without time zone ] 8 байт время суток (без даты) 00:00:00 24:00:00 1 микросекунда
time [ ( p ) ] with time zone 12 байт время дня (без даты), с часовым поясом 00:00:00+1559 24:00:00-1559 1 микросекунда
interval [ поля ] [ ( p ) ] 16 байт временной интервал -178000000 лет 178000000 лет 1 микросекунда

Примечание

Тип interval дополнительно позволяет ограничить набор сохраняемых полей следующими фразами:

Типы abstime и reltime имеют меньшую точность и предназначены для внутреннего использования. Эти типы не рекомендуется использовать в обычных приложениях; их может не быть в будущих версиях.

8.5.1. Ввод даты/времени

Помните, что любые вводимые значения даты и времени нужно заключать в апострофы, как текстовые строки. За дополнительной информацией обратитесь к Подразделу 4.1.2.7. SQL предусматривает следующий синтаксис:

8.5.1.1. Даты

Таблица 8.10. Вводимые даты

Пример Описание
1999-01-08 ISO 8601; 8 января в любом режиме (рекомендуемый формат)
January 8, 1999 воспринимается однозначно в любом режиме datestyle
1/8/1999 8 января в режиме MDY и 1 августа в режиме DMY
1/18/1999 18 января в режиме MDY ; недопустимая дата в других режимах
01/02/03 2 января 2003 г. в режиме MDY ; 1 февраля 2003 г. в режиме DMY и 3 февраля 2001 г. в режиме YMD
1999-Jan-08 8 января в любом режиме
Jan-08-1999 8 января в любом режиме
08-Jan-1999 8 января в любом режиме
99-Jan-08 8 января в режиме YMD ; ошибка в других режимах
08-Jan-99 8 января; ошибка в режиме YMD
Jan-08-99 8 января; ошибка в режиме YMD
19990108 ISO 8601; 8 января 1999 в любом режиме
990108 ISO 8601; 8 января 1999 в любом режиме
1999.008 год и день года
J2451187 Юлианский день
January 8, 99 BC 99 до н. э.

8.5.1.2. Время

Таблица 8.11. Вводимое время

Пример Описание
04:05:06.789 ISO 8601
04:05:06 ISO 8601
04:05 ISO 8601
040506 ISO 8601
04:05 AM то же, что и 04:05; AM не меняет значение времени
04:05 PM то же, что и 16:05; часы должны быть 04:05:06.789-8 ISO 8601, с часовым поясом в виде смещения от UTC
04:05:06-08:00 ISO 8601, с часовым поясом в виде смещения от UTC
04:05-08:00 ISO 8601, с часовым поясом в виде смещения от UTC
040506-08 ISO 8601, с часовым поясом в виде смещения от UTC
040506+0730 ISO 8601, с часовым поясом, задаваемым нецелочисленным смещением от UTC
040506+07:30:00 Смещение от UTC, заданное до секунд (не допускается в ISO 8601)
04:05:06 PST часовой пояс задаётся аббревиатурой
2003-04-12 04:05:06 America/New_York часовой пояс задаётся полным названием

Таблица 8.12. Вводимый часовой пояс

Пример Описание
PST аббревиатура (Pacific Standard Time, Стандартное тихоокеанское время)
America/New_York полное название часового пояса
PST8PDT указание часового пояса в стиле POSIX
-8:00:00 смещение часового пояса PST от UTC
-8:00 смещение часового пояса PST от UTC (расширенный формат ISO 8601)
-800 смещение часового пояса PST от UTC (стандартный формат ISO 8601)
-8 смещение часового пояса PST от UTC (стандартный формат ISO 8601)
zulu принятое у военных сокращение UTC
z Краткая форма zulu (также определена в ISO 8601)

Подробнее узнать о том, как указывается часовой пояс, можно в Подразделе 8.5.3.

8.5.1.3. Даты и время

В константе типа timestamp without time zone Postgres Pro просто игнорирует часовой пояс. То есть результирующее значение вычисляется только из полей даты/времени и не подстраивается под указанный часовой пояс.

8.5.1.4. Специальные значения

Таблица 8.13. Специальные значения даты/времени

Внимание

8.5.2. Вывод даты/времени

Таблица 8.14. Стили вывода даты/время

Стиль Описание Пример
ISO ISO 8601, стандарт SQL 1997-12-17 07:37:16-08
SQL традиционный стиль 12/17/1997 07:37:16.00 PST
Postgres изначальный стиль Wed Dec 17 07:37:16 1997 PST
German региональный стиль 17.12.1997 07:37:16.00 PST

Примечание

ISO 8601 указывает, что дата должна отделяться от времени буквой T в верхнем регистре. Postgres Pro принимает этот формат при вводе, но при выводе вставляет вместо T пробел, как показано выше. Это сделано для улучшения читаемости и для совместимости с RFC 3339 и другими СУБД.

Таблица 8.15. Соглашения о порядке компонентов даты

Параметр datestyle Порядок при вводе Пример вывода
SQL, DMY день / месяц / год 17/12/1997 15:37:16.00 CET
SQL, MDY месяц / день / год 12/17/1997 07:37:16.00 PST
Postgres, DMY день / месяц / год Wed 17 Dec 07:37:16 1997 PST

Для большей гибкости при форматировании выводимой даты/времени можно использовать функцию to_char (см. Раздел 9.8).

8.5.3. Часовые пояса

Часовые пояса и правила их применения определяются, как вы знаете, не только по географическим, но и по политическим соображениям. Часовые пояса во всём мире были более-менее стандартизированы в начале прошлого века, но они продолжают претерпевать изменения, в частности это касается перехода на летнее время. Для расчёта времени в прошлом Postgres Pro получает исторические сведения о правилах часовых поясов из распространённой базы данных IANA (Olson). Для будущего времени предполагается, что в заданном часовом поясе будут продолжать действовать последние принятые правила.

Поэтому мы советуем использовать часовой пояс с типами, включающими и время, и дату. Мы не рекомендуем использовать тип time with time zone (хотя Postgres Pro поддерживает его для старых приложений и совместимости со стандартом SQL ). Для типов, включающих только дату или только время, в Postgres Pro предполагается местный часовой пояс.

Postgres Pro позволяет задать часовой пояс тремя способами:

Помимо аббревиатур и названий часовых поясов Postgres Pro принимает указания часовых поясов в стиле POSIX, как описано в Разделе B.5. Этот вариант обычно менее предпочтителен, чем использование именованного часового пояса, но он может быть единственным возможным, если для нужного часового пояса нет записи в базе данных IANA.

Вкратце, различие между аббревиатурами и полными названиями заключаются в следующем: аббревиатуры представляют определённый сдвиг от UTC, а полное название подразумевает ещё и местное правило по переходу на летнее время, то есть, возможно, два сдвига от UTC. Например, 2014-06-04 12:00 America/New_York представляет полдень по местному времени в Нью-Йорк, что для данного дня было бы летним восточным временем (EDT или UTC-4). Так что 2014-06-04 12:00 EDT обозначает тот же момент времени. Но 2014-06-04 12:00 EST задаёт стандартное восточное время (UTC-5), не зависящее о того, действовало ли летнее время в этот день.

Независимо от формы, регистр в названиях и аббревиатурах часовых поясов не важен. (В PostgreSQL до версии 8.2 он где-то имел значение, а где-то нет.)

Параметр конфигурации TimeZone можно установить в postgresql.conf или любым другим стандартным способом, описанным в Главе 18. Часовой пояс может быть также определён следующими специальными способами:

8.5.4. Ввод интервалов

Значения типа interval могут быть записаны в следующей расширенной форме:

Таблица 8.16. Коды единиц временных интервалов ISO 8601

Код Значение
Y годы
M месяцы (в дате)
W недели
D дни
H часы
M минуты (во времени)
S секунды

В альтернативном формате:

Таблица 8.17. Ввод интервалов

Пример Описание
1-2 Стандартный формат SQL: 1 год и 2 месяца
3 4:05:06 Стандартный формат SQL: 3 дня 4 часа 5 минут 6 секунд
1 year 2 months 3 days 4 hours 5 minutes 6 seconds Традиционный формат Postgres: 1 год 2 месяца 3 дня 4 часа 5 минут 6 секунд
P1Y2M3DT4H5M6S « Формат с кодами » ISO 8601: то же значение, что и выше
P0001-02-03T04:05:06 « Альтернативный формат » ISO 8601: то же значение, что и выше

8.5.5. Вывод интервалов

Стиль sql_standard выдаёт результат, соответствующий стандарту SQL, если значение интервала удовлетворяет ограничениям стандарта (и содержит либо только год и месяц, либо только день и время, и при этом все его компоненты одного знака). В противном случае выводится год-месяц, за которым идёт дата-время, а в компоненты для однозначности явно добавляются знаки.

Вывод в стиле iso_8601 соответствует « формату с кодами » описанному в разделе 4.4.3.2 формата ISO 8601.

Таблица 8.18. Примеры стилей вывода интервалов

Источник

Читайте также:  что значит тонизирующий эффект
Строительный портал