Как преобразовать столбец отметки времени SQL Server в формат datetime


93

Поскольку SQL Server возвращает метку времени, например 'Nov 14 2011 03:12:12:947PM' , существует ли какой-нибудь простой способ преобразовать строку в формат даты, например 'Ymd H: i: s'.

Пока использую

date('Y-m-d H:i:s',strtotime('Nov 14 2011 03:12:12:947PM'))

Ответы:


256

Тип TIMESTAMPданных SQL Server не имеет ничего общего с датой и временем!

Это просто шестнадцатеричное представление последовательного 8-байтового целого числа - это полезно только для того, чтобы убедиться, что строка не изменилась с момента ее чтения.

Вы можете считать шестнадцатеричное целое число или, если хотите BIGINT. Например:

SELECT CAST (0x0000000017E30D64 AS BIGINT)

Результат

400756068

В более новых версиях SQL Server он называется RowVersion- поскольку это действительно то, что есть. См. Документы MSDN на ROWVERSION :

Тип данных, который предоставляет автоматически генерируемые уникальные двоичные числа в базе данных. rowversion обычно используется в качестве механизма для строк таблицы с отметками версий. Тип данных rowversion - это просто увеличивающееся число и не сохраняет дату или время . Чтобы записать дату или время, используйте тип данных datetime2.

Таким образом, вы не можете преобразовать SQL Server TIMESTAMPв дату / время - это просто не дата / время.

Но если вы говорите метку времени, но на самом деле вы имеете в виду DATETIMEстолбец, тогда вы можете использовать любой из этих допустимых форматов даты, описанных в разделе CAST и CONVERT в справке MSDN. Они определены и поддерживаются SQL Server «из коробки». Все остальное не поддерживается, например, вам нужно много вручную выполнять приведение и объединение (не рекомендуется).

Формат, который вы ищете, немного похож на канонический ODBC (style = 121):

DECLARE @today DATETIME = SYSDATETIME()

SELECT CONVERT(VARCHAR(50), @today, 121)

дает:

2011-11-14 10:29:00.470

В SQL Server 2012 наконец-то появится FORMATфункция настраиваемого форматирования ...


7
Наверное, больше всего меня раздражает SQL Server. Зачем называть это отметкой времени, если я не могу определить время с ее помощью?
BelgoCanadian

1
@BelgoCanadian: спросите Sybase - это функция , которая была в Sybase / SQL Server навсегда .....
marc_s

1
@BelgoCanadian Вы должны быть рады узнать, что теперь он называется rowversion docs.microsoft.com/en-us/sql/t-sql/data-types/…
Джейсон С.

1
есть TIMESTAMPстолбцы типа
Ghilteras

3

В этом мне помогли коллеги:

select CONVERT(VARCHAR(10), <tms_column>, 112), count(*)
from table where <tms_column> > '2012-09-10'
group by CONVERT(VARCHAR(10), <tms_column>, 112);

или же

select CONVERT(DATE, <tms_column>, 112), count(*)
from table where <tms_column> > '2012-09-10'
group by CONVERT(DATE, <tms_column>, 112);

3

Самый простой способ сделать это:

SELECT id,name,FROM_UNIXTIME(registration_date) FROM `tbl_registration`;

Это дает столбец даты по крайней мере в удобочитаемом формате. Далее, если вы хотите изменить формат te, нажмите здесь .


11
вопрос в SQLServer, а не в MySQL
Mike M

3

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

SELECT CAST(timestamp_field AS DATE) FROM tbl_name

18
Кажется, это не работает:Explicit conversion from data type timestamp to date is not allowed.
jocull

Плохая идея. Поле отметки времени - это просто последовательность. Возможно, вам повезет и вы получите свидание, но дата не будет иметь значения. Вы должны привести к BIGINT, если вы хотите десятичное число, а не шестнадцатеричное. Отметка времени теперь называется rowversion docs.microsoft.com/en-us/sql/t-sql/data-types/…
Джейсон С.

3

Работает нормально, кроме этого сообщения:

Неявное преобразование типа данных varchar в метку времени не допускается. Используйте функцию CONVERT для выполнения этого запроса

Так что да, TIMESTAMP( RowVersion) НЕ ДАТА :)

Честно говоря, я сам довольно долго возился, чтобы найти способ преобразовать его в свидание.

Лучший способ - преобразовать его в INT и сравнить. Вот каким должен быть этот тип.

Если хочешь свидания - просто добавь Datetimeколонку и живи долго и счастливо :)

ура Mac


1
Или BIGINT, так как это 8 байт
Jason S

2

«Вы продолжаете использовать это слово. Я не думаю, что оно означает то, что вы думаете». - Иниго Монтойя

Отметка времени не имеет абсолютно никакого отношения ко времени, как первоначально сказал marc_s.

declare @Test table (
     TestId int identity(1,1) primary key clustered
    ,Ts     timestamp
    ,CurrentDt datetime default getdate()
    ,Something varchar(max)
)

insert into @Test (Something)
    select name from sys.tables
waitfor delay '00:00:10'

insert into @Test (Something)
    select name from sys.tables

select * from @Test

Обратите внимание на вывод, что Ts (шестнадцатеричный) увеличивается на единицу для каждой записи, но фактическое время имеет промежуток в 10 секунд. Если бы это было связано со временем, тогда во временной метке был бы пробел, соответствующий разнице во времени.


0

После выполнения преобразования в целое число CONVERT (BIGINT, [timestamp]) as Timestamp я получил результат вроде

446701117 446701118 446701119 446701120 446701121 446701122 446701123 446701124 446701125 446701126

Да, это не дата и время, это серийные номера



0

У меня была такая же проблема с меткой времени, например: '29 -JUL-20 04.46.42.000000000 PM '. Я хотел преобразовать его в формат «гггг-мм-дд». Решение, которое наконец-то работает для меня, это

ВЫБЕРИТЕ TO_CHAR (mytimestamp, 'ГГГГ-ММ-ДД') ИЗ mytable;


0

Я предполагаю, что вы выполнили дамп данных в виде операторов вставки, и вы (или кто-то другой, кто это погуглит) пытаетесь выяснить дату и время или перевести их для использования в другом месте (например, для преобразования в вставки MySQL). На самом деле это просто на любом языке программирования.

Давайте работать с этим:

CAST(0x0000A61300B1F1EB AS DateTime)

Это шестнадцатеричное представление фактически представляет собой два отдельных элемента данных ... Дата и время. Первые четыре байта - это дата, вторые четыре байта - это время.

  • Дата 0x0000A613
  • Время 0x00B1F1EB

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

  • Дата 0x0000A613 становится 42515
  • Время 0x00B1F1EB становится 11661803

Теперь, что делать с этими целыми числами:

Свидание

Дата с 01.01.1900 и представлена ​​в днях. Итак, прибавьте 42 515 дней к 01.01.1900, и ваш результат будет 27.05.2016.

Время

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

TimeINT=Hex2Int(HexTime)
MicrosecondsTime = TimeINT*10000/3

Оттуда используйте вызовы любимых функций вашего языка для перевода микросекунд (38872676666,7 мкс в приведенном выше примере) во время.

Результат будет 10: 47: 52.677.


-1

Некоторые из них действительно скрыты от даты и времени из SQL Server 2008. .

Попробуйте выполнить следующий SQL-запрос, и вы убедитесь в этом сами:

SELECT CAST (0x00009CEF00A25634 AS datetime)

Вышеупомянутое приведет к тому, 2009-12-30 09:51:03:000но я столкнулся с такими, которые на самом деле не соответствуют дате и времени.


1
Не делай этого. Возможно, вам повезет и вы получите конверсию, но дата и время будут бессмысленными и вводящими в заблуждение. Отметка времени - это просто порядковый номер и теперь называется версией строки docs.microsoft.com/en-us/sql/t-sql/data-types/… . Если вы хотите, чтобы десятичное число было просто преобразовано в BIGINT
Джейсон С.


-3

Не уверен, что мне что-то здесь не хватает, но нельзя ли просто преобразовать метку времени следующим образом:

CONVERT(VARCHAR,CAST(ZEIT AS DATETIME), 110)

Вы пробовали это? TIMESTAMP не имеет отношения к DATE.
Шон Пирс

Я использую его на SQL Server 2008
Даниэль

Опять же, не пытайтесь привести к datetime. Это просто целочисленная последовательность в шестнадцатеричной форме. Просто введите BIGINT.
Jason S
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.