Ответ 1
Это может зависеть от множества факторов - региональных настроек операционной системы, текущего языка пользователя и настроек даты. По умолчанию Windows использует US English
, а пользовательские настройки - US English
и MDY
.
Но вот несколько примеров, чтобы показать, как это может измениться.
Пользователь использует языковые настройки BRITISH:
-- works:
SET LANGUAGE BRITISH;
SELECT CONVERT(DATETIME, '30-04-2012 19:01:45');
-- fails:
SELECT CONVERT(DATETIME, '04/13/2012');
GO
(ошибка)
Msg 242, уровень 16, состояние 3, строка 5
Преобразование данных varchar тип к типу данных даты и времени привел к значению вне диапазона.
Пользователь использует Français:
-- works:
SET LANGUAGE FRENCH;
SELECT CONVERT(DATETIME, '30-04-2012 19:01:45');
-- fails:
SELECT CONVERT(DATETIME, '04/13/2012');
GO
(ошибка)
Msg 242, уровень 16, состояние 3, строка 1
La conversion d'un type de données varchar en type de données datetime a créé une valeur hors Limites.
Пользователь снова использует Français:
SET LANGUAGE FRENCH;
-- fails (proving that, contrary to popular belief, YYYY-MM-DD is not always safe):
SELECT CONVERT(DATETIME, '2012-04-30');
GO
(ошибка)
Msg 242, уровень 16, состояние 3, строка 1
La conversion d'un type de données varchar en type de données datetime a créé une valeur hors limites.
Пользователь использует DMY вместо 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
(ошибка)
Msg 242, уровень 16, состояние 3, строка 2
Преобразование varchar тип данных для типа данных даты и времени привел к превышению значения.
Лучше всего всегда использовать стандартные, нерегиональные, безопасные и недвусмысленные форматы даты. Обычно я рекомендую:
YYYYMMDD - for date only.
YYYY-MM-DDTHH:MM:SS[.mmm] - for date + time, and yes that T is important.
Ничего из этого не удалось:
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');
Поэтому я настоятельно рекомендую, чтобы вместо того, чтобы позволить пользователям вводить форматы текстовых дат (или использовать сами ненадежные форматы), контролируйте свои входные строки и следите за тем, чтобы они придерживались одного из этих безопасных форматов. Тогда не имеет значения, какие настройки у пользователя есть или какие базовые региональные настройки, ваши даты всегда будут интерпретироваться как даты, которые они должны были быть. Если вы в настоящее время разрешаете пользователям вводить даты в текстовое поле формы, прекратите это делать и внедрите элемент управления календарем или, по крайней мере, список выбора, чтобы вы могли в конечном счете управлять строковым форматом, который передается обратно на SQL Server.
Для некоторого фона, пожалуйста, прочитайте Tibor Karaszi "Конечный путеводитель по datetime datatypes" и мой пост "Плохие привычки к удару: запросы на обработку/задание неверной обработки" .