Może to zależeć od wielu czynników - ustawień regionalnych systemu operacyjnego, języka bieżącego użytkownika i ustawień formatu daty. Domyślnie system Windows używa US English
, a ustawienia użytkownika to US English
i MDY
.
Ale oto kilka przykładów pokazujących, jak to się może zmienić.
użytkownik korzysta brytyjskich ustawień językowych:
-- works:
SET LANGUAGE BRITISH;
SELECT CONVERT(DATETIME, '30-04-2012 19:01:45');
-- fails:
SELECT CONVERT(DATETIME, '04/13/2012');
GO
(Błąd)
Msg 242, Level 16, State 3, Line 5
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
użytkownik korzysta Francais:
-- works:
SET LANGUAGE FRENCH;
SELECT CONVERT(DATETIME, '30-04-2012 19:01:45');
-- fails:
SELECT CONVERT(DATETIME, '04/13/2012');
GO
(Błąd)
Msg 242, Level 16, State 3, Line 1
La conversion d'un type de données varchar en type de données datetime a créé une valeur hors limites.
użytkownika jest ponownie przy użyciu Francais:
SET LANGUAGE FRENCH;
-- fails (proving that, contrary to popular belief, YYYY-MM-DD is not always safe):
SELECT CONVERT(DATETIME, '2012-04-30');
GO
(błąd)
Msg 242, Level 16, State 3, Line 1
La conversion d'un type de données varchar en type de données datetime a créé une valeur hors limites.
użytkownik stosuje DMY zamiast MDY:
SET LANGUAGE ENGLISH;
SET DATEFORMAT DMY;
-- works:
SELECT CONVERT(DATETIME, '30-04-2012 19:01:45');
-- fails:
SELECT CONVERT(DATETIME, '04-30-2012');
GO
(błąd)
Msg 242, Level 16, State 3, Line 2
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
Zawsze najlepiej jest używać standardowych, nieregionalnych, bezpiecznych i jednoznacznych formatów daty ISO. Obaj ja zwykle zalecane są:
YYYYMMDD - for date only.
YYYY-MM-DDTHH:MM:SS[.mmm] - for date + time, and yes that T is important.
Żaden z nich nie:
SET DATEFORMAT MDY;
SET LANGUAGE ENGLISH;
SELECT CONVERT(DATETIME, '20120430');
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45');
SET LANGUAGE FRENCH;
SELECT CONVERT(DATETIME, '20120430');
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45');
SET LANGUAGE BRITISH;
SELECT CONVERT(DATETIME, '20120430');
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45');
SET DATEFORMAT DMY;
SELECT CONVERT(DATETIME, '20120430');
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45');
Dlatego zalecamy zamiast pozwolić użytkownikom wpisać w wolnych formatów daty tekst (lub użyć zawodne formatów siebie), kontroluj swoje ciągi wejściowe i upewnij się, że są zgodne z jednym z tych bezpiecznych formatów. Wtedy nie będzie miało znaczenia, jakie ustawienia ma użytkownik lub jakie są ustawienia regionalne, twoje daty będą zawsze interpretowane jako daty, w których miały być.Jeśli obecnie pozwalasz użytkownikom wprowadzać daty w polu tekstowym formularza, przestań to robić i zaimplementuj kontrolkę kalendarza lub przynajmniej listę wyboru, aby ostatecznie kontrolować format ciągu, który jest przekazywany do SQL Server.
jakiegoś tle, proszę przeczytać Tibor Karaszi na "The ultimate guide to the datetime datatypes" i mój post "Bad Habits to Kick : Mis-handling date/range queries."
Zobacz moją odpowiedź [tutaj] (http://stackoverflow.com/a/23369706/2108149), jak to zrobić w ramach funkcji zdefiniowanej przez użytkownika. –
@ Eli Myślę, że brakuje ci punktu, który próbowałem stworzyć. Jeśli jedna osoba przebywa w Anglii i ma napis "09/04/2014", a inna osoba przebywa w USA i mija rok "09/04/2014", w jaki sposób twoja funkcja w magiczny sposób wie, który z nich oznaczał 9 kwietnia, a który oznaczało 4 września? –
Muszę przyznać, że nie przeczytałem całej twojej nitki, szukałem miesięcznego rozwiązania tłumaczeniowego i gdy go szukałem natknąłem się na twoją odpowiedź, więc pomyślałem, że niektórym ludziom może się to przydać ... –