2014-05-20 8 views
9

Znalazłem coś naprawdę dziwnego dzisiaj, wykonując pracę konwertującą datetime na tekst w programie Excel i wykorzystując wygenerowany przez nią numer do konwersji na datetime w SQL Server.Różnica między konwersjami datetime w MSExcel i SQL Server

Co jest takiego dziwnego? Różne wyniki. Dokładność na dwa dni.

Zakładałem datę dzisiejszą (20/05/2014 dd/MM/rrrr) w programie Excel i otrzymałem 41779 jako wynik w tekście.

Datetime input

Convert to text

mam wartość tekstową i używam SQL konwertować do datetime pobrać wartość jako aktualne i nie uzyskać wynik chciałem.

SQL Convert to datetime

nawet przetestowany z datetime2 ale dowiedziałem się, że nie mogę przekonwertować int do datetime2

enter image description here

Nie jestem ekspertem MS Excel ani SQL Server ekspertem, ale co się dzieje? Mogę sprawić, żeby działało, wykonując numer wygenerowany przez MS Excel i usuwając 2, ale nadal nie ma dla mnie sensu.

+0

hehe porównać 'Select wylewane (0 jako DateTime) vs.' '= DATEVALUE (" 1900 -01-01 ")' i [** 'znajdź jeden dodatkowy rok przestępny' **] (http://www.joelonsoftware.com/items/2006/06/16.html) –

+0

To jest różnica 1 , ale dlaczego między tymi testami występuje dwudniowa różnica? –

+1

Teraz, gdy zobaczyłem twoją edycję, ma to sens. Ale tak naprawdę Microsoft? Cholerny. Jeśli mógłbyś opublikować to jako awnser, zaznaczę to jako odpowiedź. Dzięki. –

Odpowiedz

6

hehe;) jeden dzień przed wiekami zastanawiałem się to samo ... zrobić proste ćwiczenie:

porównanie Select Cast(0 as DateTime) vs. =DATEVALUE("1900-01-01")który wyjaśnia 1 dzień różnicy

i znaleźć taki, dodatkowy rok przestępny czytając father of VBA, Joel Spolsky, explanation

tl; dr

check out różnica - który exlpains 2. dniu

=DateValue("1900-02-28") i =DateValue("1900-03-01")

8

Koncentrując się konkretnie na DATETIME, gdzie odlewy z int są dozwolone, istnieją dwa powody rozbieżności.

  1. Excel wykorzystuje bazę 1 dla dat, SQL Server używa 0, tj 01/01/1900 po przeliczeniu na liczbę w programie Excel jest 1, jednak w SQL jest 0: SELECT CAST(CAST('19000101' AS DATETIME) AS INT); da 0.

  2. Istnieje celowy błąd w programie Excel, umożliwiający przenoszenie z programu Lotus, w którym błąd nie był celowy *. Excel uznaje datę 29 lutego 1900 roku za poprawny, ale rok 1900 nie był rokiem przestępnym. SQL nie ma tego problemu, więc oznacza to, że w kalendarzu programu Excel jest dodatkowy dzień.

* (dalszego czytania na ten sugeruje to może być celowe, lub uznane nieistotne)


DODATEK

Jest Microsoft Support Item że Sates:

Whe n Po raz pierwszy wydano Lotus 1-2-3, program zakładał, że rok 1900 był rokiem przestępnym, mimo że nie był to rok przestępny. Ułatwiło to programowi radzenie sobie z latami przestępnymi i nie spowodowało żadnych szkód w prawie wszystkich obliczeniach dat w Lotus 1-2-3.

Po wydaniu Microsoft Multiplan i Microsoft Excel, przyjęto również, że rok 1900 był rokiem przestępnym. Założenie to pozwoliło Microsoft Multiplan i Microsoft Excel na użycie tego samego seryjnego systemu dat używanego przez Lotus 1-2-3 i zapewnienie większej zgodności z Lotus 1-2-3.Traktowanie 1900 jako roku przestępnego również ułatwiło użytkownikom przenoszenie arkuszy roboczych z jednego programu do drugiego.

+0

Naprawdę chciałbym zaznaczyć to jako poprawną odpowiedź. –

-1

szukam tej stronie i znaleźć rozwiązanie na wygląd kodu tutaj. Musisz wykonać sprawdzenie dla dowolnej liczby poniżej 60, jeśli jest poniżej 60, nie odejmuj 1, ponieważ jeszcze nie masz błędu. Jeśli jest ponad trzeba odjąć jedną z datą z powodu błędu

Declare @dni INT = 41779

DECLARE @StartDate DATETIME = '1899-12-31'

02/29/1900

jeśli (@ dni> 59) SET @ dni = @ dni -1;

SELECT DATEADD (dzień, @ dni @ startDate)

To gdzie znalazłem rozwiązanie https://stackoverflow.com/a/727495/1692632

+1

Darka, nie. Są 2 odpowiedzi różne od twoich, które wyjaśniają faktyczną różnicę. –

+0

To jest to samo, co ten – Darka

+0

Darka, jest to obejście oparte na języku SQL, które zwraca tę samą datę co program Excel, ale nie rozwiązuje pierwotnego pytania. –

Powiązane problemy