Comment convertir la colonne d'horodatage de SQL Server au format datetime


90

Comme SQL Server renvoie un horodatage comme 'Nov 14 2011 03:12:12:947PM', existe-t-il un moyen simple de convertir une chaîne en un format de date comme «Ymd H: i: s».

Jusqu'ici j'utilise

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

Réponses:


252

Le TIMESTAMPtype de données de SQL Server n'a rien à voir avec une date et une heure!

C'est juste une représentation hexadécimale d'un entier consécutif de 8 octets - c'est seulement bon pour s'assurer qu'une ligne n'a pas changé depuis qu'elle a été lue.

Vous pouvez lire l'entier hexadécimal ou si vous voulez un fichier BIGINT. Par exemple:

SELECT CAST (0x0000000017E30D64 AS BIGINT)

Le résultat est

400756068

Dans les nouvelles versions de SQL Server, il est appelé RowVersion- car c'est vraiment ce que c'est. Consultez la documentation MSDN sur ROWVERSION :

Est un type de données qui expose des nombres binaires uniques générés automatiquement dans une base de données. rowversion est généralement utilisé comme mécanisme pour les lignes de table d'estampillage de version. Le type de données rowversion est simplement un nombre incrémentiel et ne conserve pas une date ou une heure . Pour enregistrer une date ou une heure, utilisez un type de données datetime2.

Vous ne pouvez donc pas convertir un serveur SQL TIMESTAMPen une date / heure - ce n'est tout simplement pas une date / heure.

Mais si vous dites horodatage mais que vous voulez vraiment parler d'une DATETIMEcolonne, vous pouvez utiliser l'un de ces formats de date valides décrits dans la rubrique CAST et CONVERT de l'aide MSDN. Ceux-ci sont définis et pris en charge «prêts à l'emploi» par SQL Server. Tout le reste n'est pas pris en charge, par exemple, vous devez faire beaucoup de casting et de concaténation manuels (non recommandé).

Le format que vous recherchez ressemble un peu au canonique ODBC (style = 121):

DECLARE @today DATETIME = SYSDATETIME()

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

donne:

2011-11-14 10:29:00.470

SQL Server 2012 aura enfin une FORMATfonction pour faire un formatage personnalisé ......


5
Probablement ma plus grosse bête noire avec SQL Server. Pourquoi appeler cela un horodatage si je ne peux pas dire l'heure avec lui?
BelgoCanadian

1
@BelgoCanadian: demandez à Sybase - c'est une fonctionnalité qui existe depuis toujours dans Sybase / SQL Server .....
marc_s

1
@BelgoCanadian Vous devriez être heureux de savoir qu'il s'appelle maintenant rowversion docs.microsoft.com/en-us/sql/t-sql/data-types
Jason S

il y a TIMESTAMPdes colonnes de type
Ghilteras

4

La manière la plus simple de procéder est:

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

Cela donne la colonne de date au moins dans un format lisible. De plus, si vous souhaitez changer de format, cliquez ici .


11
la question est SQLServer, pas MySQL
Mike M

4

En utilisant la distribution, vous pouvez obtenir la date à partir d'un champ d'horodatage:

SELECT CAST(timestamp_field AS DATE) FROM tbl_name

18
Cela ne semble pas fonctionner:Explicit conversion from data type timestamp to date is not allowed.
jocull

Mauvaise idée. Le champ d'horodatage n'est qu'une séquence. Vous pourriez avoir de la chance et avoir une date, mais la date n'aura aucun sens. Vous devez convertir en BIGINT si vous voulez un nombre décimal plutôt que hexadécimal. L'horodatage s'appelle désormais rowversion docs.microsoft.com/en-us/sql/t-sql/data-types
Jason S

3

Mes collègues m'ont aidé avec ceci:

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

Fonctionne bien, sauf ce message:

La conversion implicite du type de données varchar en horodatage n'est pas autorisée. Utilisez la fonction CONVERT pour exécuter cette requête

Alors oui, TIMESTAMP( RowVersion) n'est PAS une DATE :)

Pour être honnête, j'ai bricolé un certain temps moi-même pour trouver un moyen de le convertir en date.

Le meilleur moyen est de le convertir INTet de le comparer. C'est ce que ce type est censé être.

Si vous voulez une date - ajoutez simplement une Datetimecolonne et vivez heureux pour toujours :)

bravo Mac


1
Ou BIGINT car il fait 8 octets
Jason S

2

"Vous continuez à utiliser ce mot. Je ne pense pas que cela signifie ce que vous pensez que cela signifie." - Inigo Montoya

L'horodatage n'a absolument aucun rapport avec le temps, comme marc_s l'a dit à l'origine.

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

Remarquez dans la sortie que Ts (hex) incrémente de un pour chaque enregistrement, mais le temps réel a un intervalle de 10 secondes. S'il était lié au temps, il y aurait un intervalle dans l'horodatage pour correspondre à la différence de temps.


0

Après impelemtation de la conversion en entier CONVERT (BIGINT, [timestamp]) as Timestamp, j'ai le résultat comme

446701117 446701118 446701119 446701120 446701121 446701122 446701123 446701124 446701125 446701126

Oui, ce n'est pas une date et une heure, ce sont des numéros de série


0

pour moi fonctionne: TO_DATE ('19700101', 'yyyymmdd') + (TIME / 24/60/60) (oracle DB)


0

J'ai eu le même problème avec l'horodatage, par exemple: '29 -JUL-20 04.46.42.000000000 PM '. Je voulais le transformer en format «aaaa-MM-jj». La solution qui fonctionne enfin pour moi est

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


0

Je suppose que vous avez fait un vidage de données sous forme d'instructions d'insertion, et que vous (ou quiconque google ceci) essayez de comprendre la date et l'heure, ou de les traduire pour une utilisation ailleurs (par exemple: pour convertir en insertions MySQL). C'est en fait facile dans n'importe quel langage de programmation.

Travaillons avec ceci:

CAST(0x0000A61300B1F1EB AS DateTime)

Cette représentation hexadécimale est en fait deux éléments de données distincts ... Date et heure. Les quatre premiers octets sont la date, les quatre seconds sont l'heure.

  • La date est 0x0000A613
  • L'heure est 0x00B1F1EB

Convertissez les deux segments en nombres entiers en utilisant le langage de programmation de votre choix (c'est une conversion hexadécimale directe en entier, qui est prise en charge dans tous les langages de programmation modernes, donc, je ne gaspillerai pas d'espace avec du code qui peut ou non être le langage de programmation vous travaillez).

  • La date de 0x0000A613 devient 42515
  • L'heure de 0x00B1F1EB devient 11661803

Maintenant, que faire avec ces entiers:

Date

La date est depuis le 01/01/1900 et est représentée sous forme de jours. Donc, ajoutez 42515 jours au 01/01/1900, et votre résultat est le 27/05/2016.

Temps

Le temps est un peu plus complexe. Prenez cet INT et procédez comme suit pour obtenir votre temps en microsecondes depuis minuit (pseudocode):

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

À partir de là, utilisez les appels de fonction préférés de votre langue pour traduire les microsecondes (38872676666,7 µs dans l'exemple ci-dessus) en temps.

Le résultat serait 10: 47: 52.677


-1

Certains d'entre eux se transforment en une date-heure à partir de SQL Server 2008 .

Essayez la requête SQL suivante et vous verrez par vous-même:

SELECT CAST (0x00009CEF00A25634 AS datetime)

Ce qui précède aboutira, 2009-12-30 09:51:03:000mais j'en ai rencontré des qui ne correspondent pas à une date-heure.


1
Ne fais pas ça. Vous pourriez avoir de la chance et obtenir une conversion, mais la date et l'heure n'auront aucun sens et seront trompeuses. L'horodatage est juste un numéro de séquence et s'appelle désormais la version de ligne docs.microsoft.com/en-us/sql/t-sql/data-types/… . Si vous voulez un nombre décimal juste casté en BIGINT
Jason S


-3

Je ne sais pas si je manque quelque chose ici, mais ne pouvez-vous pas simplement convertir l'horodatage comme ceci:

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

Avez-vous essayé cela? TIMESTAMP n'a aucun rapport avec DATE.
Sean Pearce

Je l'utilise sur SQL Server 2008
Daniel

Encore une fois, n'essayez pas de convertir en datetime. Il s'agit simplement d'une séquence d'entiers sous forme hexadécimale. Il suffit de lancer BIGINT.
Jason S
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.