Como converter a coluna de carimbo de data / hora do SQL Server para o formato datetime


93

Como o SQL Server retorna timestamp como 'Nov 14 2011 03:12:12:947PM', há alguma maneira fácil de converter string em formato de data como 'Ymd H: i: s'.

Até agora eu uso

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

Respostas:


256

O TIMESTAMPtipo de dados do SQL Server não tem nada a ver com data e hora!

É apenas uma representação hexadecimal de um número inteiro consecutivo de 8 bytes - é bom apenas para garantir que uma linha não mudou desde que foi lida.

Você pode ler o número inteiro hexadecimal ou, se quiser, um BIGINT. Como um exemplo:

SELECT CAST (0x0000000017E30D64 AS BIGINT)

O resultado é

400756068

Nas versões mais recentes do SQL Server, ele é chamado RowVersion- já que é realmente o que é. Veja os documentos do MSDN em ROWVERSION :

É um tipo de dados que expõe números binários exclusivos gerados automaticamente em um banco de dados. rowversion é geralmente usado como um mecanismo para linhas de tabela de carimbo de versão. O tipo de dados rowversion é apenas um número crescente e não preserva uma data ou hora . Para registrar uma data ou hora, use um tipo de dados datetime2.

Portanto, você não pode converter um SQL Server TIMESTAMPem uma data / hora - simplesmente não é uma data / hora.

Mas se você está dizendo timestamp, mas na verdade quer dizer uma DATETIMEcoluna - então você pode usar qualquer um desses formatos de data válidos descritos em CAST e CONVERT tópico na ajuda do MSDN. Esses são definidos e suportados "fora da caixa" pelo SQL Server. Qualquer outra coisa não é suportada, por exemplo, você tem que fazer muita conversão manual e concatenação (não recomendado).

O formato que você está procurando se parece um pouco com o ODBC canônico (estilo = 121):

DECLARE @today DATETIME = SYSDATETIME()

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

dá:

2011-11-14 10:29:00.470

O SQL Server 2012 finalmente terá uma FORMATfunção para fazer a formatação personalizada ......


7
Provavelmente minha maior implicância com o SQL Server. Por que chamá-lo de carimbo de data / hora se não posso dizer a hora com ele?
BelgoCanadian

1
@BelgoCanadian: pergunte ao Sybase - esse é um recurso que está no Sybase / SQL Server desde sempre ...
marc_s

1
@BelgoCanadian Você deve ficar feliz em saber que agora se chama rowversion docs.microsoft.com/en-us/sql/t-sql/data-types/…
Jason S

1
existem TIMESTAMPcolunas de tipo
Ghilteras

3

Meus colegas de trabalho me ajudaram com isso:

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

ou

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

3

A maneira mais simples de fazer isso é:

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

Isso dá a coluna de data pelo menos em um formato legível. Além disso, se você deseja alterar o formato clique aqui .


11
a questão é SQLServer, não MySQL
Mike M

3

Usando o elenco, você pode obter a data de um campo de carimbo de data / hora:

SELECT CAST(timestamp_field AS DATE) FROM tbl_name

18
Isso não parece funcionar:Explicit conversion from data type timestamp to date is not allowed.
jocull

Péssima ideia. O campo timestamp é apenas uma sequência. Você pode ter sorte e conseguir um encontro, mas a data não terá nenhum significado. Você deve lançar para BIGINT se quiser um número decimal, em vez de hexadecimal. O carimbo de data / hora agora é denominado rowversion docs.microsoft.com/en-us/sql/t-sql/data-types/…
Jason S

3

Funciona bem, exceto esta mensagem:

A conversão implícita do tipo de dados varchar em timestamp não é permitida. Use a função CONVERTER para executar esta consulta

Então, sim, TIMESTAMP( RowVersion) NÃO é uma DATA :)

Para ser honesto, eu mesmo fiquei mexendo por um bom tempo para encontrar uma maneira de convertê-lo em um encontro.

A melhor maneira é convertê-lo INTe compará-lo. É isso que esse tipo deve ser.

Se você quiser um encontro - basta adicionar uma Datetimecoluna e viver feliz para sempre :)

saúde mac


1
Ou BIGINT, pois tem 8 bytes
Jason S

2

"Você continua usando essa palavra. Não acho que signifique o que você pensa que significa." - Inigo Montoya

O carimbo de data / hora não tem absolutamente nenhuma relação com o tempo, como marc_s disse originalmente.

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

Observe na saída que Ts (hex) é incrementado em um para cada registro, mas o tempo real tem um intervalo de 10 segundos. Se fosse relacionado ao tempo, haveria uma lacuna no carimbo de data / hora para corresponder à diferença no tempo.


0

Após a implementação da conversão para inteiro CONVERT (BIGINT, [timestamp]) como Timestamp, obtive o resultado como

446701117 446701118 446701119 446701120 446701121 446701122 446701123 446701124 446701125 446701126

Sim, esta não é uma data e hora, são números de série


0

para mim funciona: TO_DATE ('19700101', 'aaaammdd') + (TIME / 24/60/60) (oracle DB)


0

Eu tive o mesmo problema com o carimbo de data / hora, por exemplo: '29 -JUL-20 04.46.42.000000000 PM '. Eu queria transformá-lo no formato 'aaaa-MM-dd'. A solução que finalmente funciona para mim é

SELECT TO_CHAR (mytimestamp, 'YYYY-MM-DD') FROM mytable;


0

Vou supor que você fez um despejo de dados como instruções de inserção e você (ou quem quer que faça isso no Google) está tentando descobrir a data e hora, ou traduzi-lo para uso em outro lugar (por exemplo: para converter para inserções do MySQL). Na verdade, isso é fácil em qualquer linguagem de programação.

Vamos trabalhar com isso:

CAST(0x0000A61300B1F1EB AS DateTime)

Esta representação hexadecimal é, na verdade, dois elementos de dados separados ... Data e hora. Os primeiros quatro bytes são de data, os segundos quatro bytes são de tempo.

  • A data é 0x0000A613
  • A hora é 0x00B1F1EB

Converta ambos os segmentos em inteiros usando a linguagem de programação de sua escolha (é uma conversão direta de hex para inteiros, que é suportada em todas as linguagens de programação modernas, portanto, não vou perder espaço com código que pode ou não ser a linguagem de programação você está trabalhando).

  • A data de 0x0000A613 se torna 42515
  • O tempo de 0x00B1F1EB torna-se 11661803

Agora, o que fazer com esses inteiros:

Encontro

A data é desde 01/01/1900 e é representada como dias. Portanto, adicione 42.515 dias a 01/01/1900 e seu resultado será 27/05/2016.

Tempo

O tempo é um pouco mais complexo. Pegue esse INT e faça o seguinte para obter o seu tempo em microssegundos desde a meia-noite (pseudocódigo):

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

A partir daí, use as chamadas de função favoritas do seu idioma para traduzir microssegundos (38872676666,7 µs no exemplo acima) em tempo.

O resultado seria 10: 47: 52.677


-1

Alguns deles realmente se convertem em uma data e hora do SQL Server 2008 em diante.

Experimente a seguinte consulta SQL e você verá por si mesmo:

SELECT CAST (0x00009CEF00A25634 AS datetime)

O resultado acima resultará em, 2009-12-30 09:51:03:000mas eu encontrei alguns que, na verdade, não são mapeados para uma data e hora.


1
Não faça isso. Você pode ter sorte e obter uma conversão, mas a data e hora não fará sentido e será enganosa. O carimbo de data / hora é apenas um número de sequência e agora é chamado de versão da linha docs.microsoft.com/en-us/sql/t-sql/data-types/… . Se você quiser um número decimal, lance apenas para BIGINT
Jason S


-3

Não tenho certeza se estou faltando alguma coisa aqui, mas você não pode simplesmente converter o carimbo de data / hora assim:

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

Você tentou isso? TIMESTAMP não tem relação com DATE.
Sean Pearce

Estou usando no SQL Server 2008
Daniel,

Novamente, não tente lançar para data e hora. É simplesmente uma sequência inteira em forma hexadecimal. Basta lançar para BIGINT.
Jason S
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.