DateTime проблема, когда глобальная культура сервера отличается на разных серверах - PullRequest
7 голосов
/ 24 октября 2011

Мой сайт размещен на нескольких серверах в разных местах

Везде Культура формата данных различна - мы используем формат mm/dd/yyyy везде, но если на каком-либо сервере установлена ​​культура dd/mm/yyyy, тогда наш веб-сайт генерирует исключение Datetime.

Ответы [ 4 ]

12 голосов
/ 24 октября 2011

Вы должны указать, какую культуру вы хотите использовать при конвертации строки в дату.

Культура, которую вы должны использовать, зависит от того, в какую культуру отформатированы даты. Например, если все даты, которые вы анализируете, отформатированы как Словацкий :

String s = "24. 10. 2011";

Затем вам нужно разобрать строку, как если бы она была в Словацкой (Словакия) (sk-SK) культуре:

//Bad:
d = DateTime.Parse(s);

//Good:
d = DateTime.Parse(s, CultureInfo.CreateSpecificCulture("sk-SK")); //Slovak (Slovakia)

Если все ваши даты в Таджикский (таджикская кириллица) , то вам нужно проанализировать его как tg-Cryl-Tj:

String s = "24.10.11"

DateTime d = DateTime.Parse(s, CultureInfo.CreateSpecificCulture("tg-Cryl-Tj"));

Что приводит к вопросу: какой формат даты вы используете? Вы не должны полагаться на настройку локали сервера, вы должны решить, какой формат вы хотите.

//Bad
String s = d.ToString();

//Good
String s = d.ToString(CultureInfo.CreateSpecificCulture("si-LK")); //Sinhala (Sri Lanka)

//s = "2011-10-24 12:00:00 පෙ.ව."

Я подозреваю, что вы предпочитаете делать все на английском. Но тогда вы должны решить, какой вариант английского языка:

  • en-AU (англ. Austrailia): 24/10/2011
  • en-IA (английский, Индия): 24-10-2011
  • en-ZA (английский, Южная Африка): 2011/10/24
  • en-US (английский США): 10/24/2011

Я подозреваю, что вы предпочитаете Английский (Индия) (en-IA).


Но если вы действительно не можете решить, какую культуру использовать при преобразовании дат в строки и наоборот, и даты никогда не предназначены для показа пользователю, тогда вы можете использовать Инвариантную культуру :

String s = "10/24/2011" //invariant culture formatted date

d = DateTime.Parse(s, CultureInfo.InvariantCulture); //parse invariant culture date

s = d.ToString(CultureInfo.InvariantCulture); //convert to invariant culture string
1 голос
/ 24 октября 2011

Никогда, никогда не храните даты внутри себя как строки. Не в базе данных, не в вашем приложении.

Если вам нужно переместить значения даты между серверами, перейдите в двоичную форму. Или, если вам действительно нужно использовать строки, используйте ToString(CultureInfo.InvariantCulture) - или просто сериализуйте свойство Ticks.

Кроме того, никогда не передавайте даты в виде строк в базу данных с помощью команд SQL, которые вы строите с помощью кода. Используйте SqlParameter для этого или, что еще лучше, положитесь на некоторые O / R Mapper, такие как Entity Framework или Linq to SQL.

0 голосов
/ 24 октября 2011

При развертывании на сервере, который не находится под вашим контролем, жизненно важно убедиться, что ваш код не имеет жестко-зависимых зависимостей от культуры.

Скорее всего, вы захотите найти в вашем коде DateTime.Parse или аналогичный. У нас есть набор методов расширения для DateTime, которые мы используем вместо этого для принудительной установки правильной культуры.

0 голосов
/ 24 октября 2011

Никогда полагаться на локаль сервера по умолчанию.Для вашего случая это означает:

  • Используйте подготовленные операторы, в которых вы передаете дату как (неформатированный) объект даты, а не как (отформатированный) строковый объект.В любом случае вам никогда не следует использовать строки для представления дат в вашем приложении, поскольку вы не можете выполнять над ними специфические для даты функции (например, добавление 1 месяца, получение последнего дня текущей недели и т. Д.)

  • Используйте функции SQL, такие как to_date и to_char везде (точные имена зависят от вашей СУБД), если вам действительно необходимо использовать строковые объекты в вашем приложении

...