Jak przekonwertować kolumnę sygnatury czasowej SQL Server na format daty i godziny

90

Ponieważ SQL Server zwraca znacznik czasu podobny do tego 'Nov 14 2011 03:12:12:947PM', czy istnieje prosty sposób na przekonwertowanie ciągu znaków na format daty, taki jak „Ymd H: i: s”.

Póki co używam

date('Y-m-d H:i:s',strtotime('Nov 14 2011 03:12:12:947PM'))
Jayson
źródło

Odpowiedzi:

252

Typ danych SQL Server nie TIMESTAMPma nic wspólnego z datą i godziną!

Jest to po prostu szesnastkowa reprezentacja kolejnej 8-bajtowej liczby całkowitej - jest to dobre tylko do upewnienia się, że wiersz nie zmienił się od czasu odczytania.

Możesz odczytać szesnastkową liczbę całkowitą lub jeśli chcesz BIGINT. Jako przykład:

SELECT CAST (0x0000000017E30D64 AS BIGINT)

Wynik to

400756068

W nowszych wersjach SQL Server nazywa się to RowVersion- ponieważ tak naprawdę jest. Zobacz dokumentację MSDN na ROWVERSION :

To typ danych, który ujawnia automatycznie generowane, unikalne liczby binarne w bazie danych. wierszversion jest zwykle używany jako mechanizm dla wierszy tabeli znakowania wersji. Typ danych rowversion to tylko rosnąca liczba i nie zachowuje daty ani godziny . Aby zarejestrować datę lub godzinę, użyj typu danych datetime2.

Nie można więc przekonwertować SQL Server TIMESTAMPna datę / godzinę - to po prostu nie jest data / godzina.

Ale jeśli mówisz o sygnaturze czasowej, ale tak naprawdę masz na myśli DATETIMEkolumnę - możesz użyć dowolnego z tych prawidłowych formatów daty opisanych w temacie RZUTUJ i KONWERTUJ w pomocy MSDN. Są one definiowane i obsługiwane „po wyjęciu z pudełka” przez SQL Server. Wszystko inne nie jest obsługiwane, np. Musisz wykonać dużo ręcznego rzutowania i łączenia (niezalecane).

Format, którego szukasz, wygląda trochę jak kanoniczny ODBC (style = 121):

DECLARE @today DATETIME = SYSDATETIME()

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

daje:

2011-11-14 10:29:00.470

SQL Server 2012 będzie wreszcie miał FORMATfunkcję niestandardowego formatowania ......

marc_s
źródło
5
Prawdopodobnie mój największy zirytowany SQL Server. Po co nazywać to sygnaturą czasową, jeśli nie mogę za jej pomocą określić czasu?
BelgoCanadian
1
@BelgoCanadian: zapytaj Sybase - to funkcja, która była w Sybase / SQL Server od zawsze .....
marc_s
1
@BelgoCanadian Powinieneś się cieszyć, że teraz nazywa się rowversion docs.microsoft.com/en-us/sql/t-sql/data-types/ ...
Jason S
TIMESTAMPkolumny typu
Ghilteras
4

Najprostszym sposobem na to jest:

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

Dzięki temu kolumna z datą jest przynajmniej w czytelnym formacie. Jeśli chcesz zmienić format, kliknij tutaj .

Sudeep nayak
źródło
11
pytanie brzmi SQLServer, a nie MySQL
Mike M
4

Korzystając z przesyłania, możesz pobrać datę z pola znacznika czasu:

SELECT CAST(timestamp_field AS DATE) FROM tbl_name
Ali
źródło
18
To nie wydaje się działać:Explicit conversion from data type timestamp to date is not allowed.
żartobliwy
Kiepski pomysł. Pole datownika to tylko sekwencja. Możesz mieć szczęście i umówić się na randkę, ale data nie będzie miała znaczenia. Powinieneś rzutować na BIGINT, jeśli chcesz liczbę dziesiętną, a nie szesnastkową. Sygnatura czasowa
Jason S
3

Moi współpracownicy pomogli mi w tym:

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

lub

select CONVERT(DATE, <tms_column>, 112), count(*)
from table where <tms_column> > '2012-09-10'
group by CONVERT(DATE, <tms_column>, 112);
Jadwiga
źródło
3

Działa dobrze, z wyjątkiem tej wiadomości:

Niejawna konwersja z typu danych varchar na znacznik czasu jest niedozwolona. Użyj funkcji CONVERT, aby uruchomić to zapytanie

Więc tak, TIMESTAMP( RowVersion) NIE jest DATĄ :)

Szczerze mówiąc, sam przez jakiś czas majstrowałem, żeby znaleźć sposób na przekształcenie tego w randkę.

Najlepszym sposobem jest przekonwertowanie go INTi porównanie. Taki ma być ten typ.

Jeśli chcesz randkę - po prostu dodaj Datetimekolumnę i żyj długo i szczęśliwie :)

okrzyki mac

Prochowiec
źródło
1
Lub BIGINT, ponieważ ma 8 bajtów
Jason S
2

- Ciągle używasz tego słowa. Nie sądzę, żeby znaczyło to, co myślisz. - Inigo Montoya

Znacznik czasu nie ma absolutnie żadnego związku z czasem, jak pierwotnie powiedział 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

Zwróć uwagę na wynik, że Ts (hex) zwiększa się o jeden dla każdego rekordu, ale rzeczywisty czas ma przerwę 10 sekund. Gdyby odnosiło się to do czasu, w sygnaturze czasowej byłaby luka odpowiadająca różnicy czasu.

user432532
źródło
0

Po zainicjowaniu konwersji na liczbę całkowitą CONVERT (BIGINT, [timestamp]) jako znacznik czasu otrzymałem wynik taki jak

446701117 446701118 446701119 446701120 446701121 446701122 446701123 446701124 446701125 446701126

Tak, to nie jest data i godzina, to numery seryjne

user1575120
źródło
0

dla mnie działa: TO_DATE ('19700101', 'yyyymmdd') + (TIME / 24/60/60) (oracle DB)

Baidiuk Yevhen
źródło
0

Miałem ten sam problem ze znacznikiem czasu, np .: „29 -JUL-20 04.46.42.000000000 PM”. Chciałem przekształcić go w format „yyyy-MM-dd”. Rozwiązanie, które w końcu działa dla mnie, to

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

chrupiące
źródło
0

Zakładam, że wykonałeś zrzut danych jako instrukcje wstawiania, a ty (lub ktokolwiek to szuka w Google), próbujesz znaleźć datę i godzinę lub przetłumaczyć je do użytku w innym miejscu (np .: aby przekonwertować na wstawki MySQL). Jest to rzeczywiście łatwe w każdym języku programowania.

Pracujmy z tym:

CAST(0x0000A61300B1F1EB AS DateTime)

Ta reprezentacja szesnastkowa to w rzeczywistości dwa oddzielne elementy danych ... Data i godzina. Pierwsze cztery bajty to data, drugie cztery bajty to czas.

  • Data to 0x0000A613
  • Czas to 0x00B1F1EB

Zamień oba segmenty na liczby całkowite przy użyciu wybranego języka programowania (jest to bezpośrednia konwersja szesnastkowa na liczbę całkowitą, która jest obsługiwana w każdym nowoczesnym języku programowania, więc nie będę marnował miejsca na kod, który może być językiem programowania lub nie w którym pracujesz).

  • Data 0x0000A613 staje się 42515
  • Czas 0x00B1F1EB staje się 11661803

A teraz co zrobić z tymi liczbami całkowitymi:

Data

Data przypada od 01/01/1900 i jest reprezentowana jako dni. Więc dodaj 42,515 dni do 01.01.1900, a Twój wynik to 27.05.2016.

Czas

Czas jest trochę bardziej złożony. Weź tę INT i wykonaj następujące czynności, aby uzyskać czas w mikrosekundach od północy (pseudokod):

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

Następnie użyj ulubionych wywołań funkcji swojego języka, aby przetłumaczyć mikrosekundy (38872676666,7 µs w powyższym przykładzie) na czas.

Wynik byłby 10: 47: 52,677

Robert Mauro
źródło
-1

Niektóre z nich faktycznie ukrywają datę od SQL Server 2008 r.

Wypróbuj następujące zapytanie SQL, a sam się przekonasz:

SELECT CAST (0x00009CEF00A25634 AS datetime)

Powyższe spowoduje, 2009-12-30 09:51:03:000ale napotkałem takie, które w rzeczywistości nie są mapowane na datę i godzinę.

ambodi
źródło
1
Nie rób tego. Możesz mieć szczęście i uzyskać konwersję, ale data i godzina będą bez znaczenia i wprowadzające w błąd. Sygnatura czasowa to tylko numer kolejny i nazywa się teraz wersją wiersza docs.microsoft.com/en-us/sql/t-sql/data-types/… . Jeśli chcesz mieć liczbę dziesiętną, po prostu rzuć na BIGINT
Jason S
-1

Dlaczego nie spróbować FROM_UNIXTIME(unix_timestamp, format)?

user3541554
źródło
23
Ponieważ to pytanie dotyczy SQL firmy Microsoft, a nie MySQL.
Slogmeister Extraordinaire,
-3

Nie jestem pewien, czy coś mi tu brakuje, ale czy nie możesz po prostu przekonwertować znacznika czasu w ten sposób:

CONVERT(VARCHAR,CAST(ZEIT AS DATETIME), 110)
Daniel
źródło
Próbowałeś tego? TIMESTAMP nie ma związku z DATE.
Sean Pearce,
Używam go na SQL Server 2008
Daniel,
Ponownie, nie próbuj przesyłać do daty i godziny. Jest to po prostu ciąg liczb całkowitych w postaci szesnastkowej. Po prostu prześlij do BIGINT.
Jason S