2015-03-28 2 views
0

Моя программа # WinForms C будет использоваться в следующих странахЭтот код C# достаточно для обработки глобализации?

United Kingdom : date format day-month-year , currency separator is '.' 
United States : date format month-day-year , currency separator is '.' 
Denmark   : date format day-month-year , currency separator is ',' 

Я хочу, чтобы сделать запуск программы должным образом, независимо от того, что региональные настройки на компьютере пользователя. Моя основная проблема заключается в обработке формата даты и валютных полей. (Перевод на русский язык не является проблемой, потому что программа будет показывать только текст на английском языке)

Для этого я решил, что все даты в базе данных будут сохранены в формате yyyy-mm-dd и все десятичные поля будут сохранены с разделителем ..
Я создал базу данных с Danish_Norwegian_CI_AS сортировки. Итак, я предполагаю, что данные будут сохранены в приведенном выше формате datetime & десятичный формат без меня, требуя чего-то особенного.

Я поставил следующий код в моей программе

var cult = new CultureInfo("en-GB"); 
Thread.CurrentThread.CurrentCulture = cult; 
Thread.CurrentThread.CurrentUICulture = cult; 

CultureInfo.DefaultThreadCurrentCulture = cult; 
CultureInfo.DefaultThreadCurrentUICulture = cult; 

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

+3

Я надеюсь, что ваша база данных на самом деле не хранить десятичные и даты в виде строки столбцов. –

+0

Хенк - нет, все даты хранятся в столбце datetime, а десятичные значения и значения валюты хранятся в десятичных столбцах. – Cheryl

+1

. Тогда _dates в базе данных будут сохранены с yyyy-mm-dd format_ не применяется. –

ответ

2

Культура относится только в после двух сценариев:

  • Преобразование строкового представления значения в собственный формат, wh Его называют «разбор».

  • Преобразование собственного формата значения в строковое представление, которое называется «форматирование».

При сохранении datetime или decimal или какой-либо другой тип в базу данных, она хранится в родном формате . В базе данных SQL это обычно небольшое двоичное значение, с которым вы никогда не будете работать напрямую.

Рассмотрим следующий SQL:

declare @dt datetime 
set @dt = '01/02/2015 12:34:56' 
select @dt 

В первой строке мы объявляем переменную типа datetime. Это не строка, это особый тип данных, который занимает 8 байт памяти или диска.

Во второй строке мы присваиваем значение переменной переменной. SQL анализирует строку, преобразуя ее в datetime, поэтому ее можно сохранить в переменной @dt. Фактическое сохраненное значение имеет шестнадцатеричное представление 0x0000A41400CF5940.

Когда он выполнял синтаксический анализ, применялась текущая культура среды, в которой выполнялся код. Поскольку я нахожусь в США, он интерпретировал дату как 2 января. Если бы я был в Европе, он интерпретировал бы дату 1 февраля (изменение внутреннего значения до 0x0000A43200CF5940).

Использование дат в формате yyyy-mm-dd позволит избежать неправильной интерпретации, но это не означает, что фактическое значение составляет , сохраненное в как строка в этом формате.Просто формат недвусмыслен, поэтому будет разобранным таким же образом, независимо от культуры.

В третьей строке приведенного выше кода мы выбираем переменную, чтобы включить ее в результирующий набор. Хотя мы выбираем его в своей нативной форме без какой-либо конверсии, мы в конечном счете см. в строчном представлении. Если вы выполняете запрос в таком инструменте, как SQL Server Management Studio, то в окне вывода будет формат собственных значений строк, чтобы вы могли их прочитать. При этом текущая культура снова применяется. По умолчанию SQL используется для отображения дат в формате yyyy-mm-dd, а не для конкретного формата. Но другие значения, такие как десятичные знаки, будут использовать разделитель текущей культуры.

Если вместо этого в SSMS вы действительно получили результаты через свой код (например,), форматирование никогда не происходит. Читатель сопоставляет двоичное значение базы данных SQL непосредственно с соответствующим родным типом .NET, используя the mappings shown here. SQL datetime получает естественное отображение на .NET DateTime.

DateTime dt = (DateTime) reader["dt"]; 

Сейчас довольно часто, вы видите кого-то делать глупые вещи, как это:

DateTime dt = Convert.ToDateTime(reader["dt"].ToString()); 

Это расточительно, поскольку значение ужеDateTime, и этот код будет использовать текущую культуру в формат строку, а затем использовать ее снова для синтаксического анализа строки. Это много манипуляций с строками без всякой причины.

В конечном счете, в вашем коде .NET вы в конечном итоге используете это значение DateTime и преобразовываете его в строку где-нибудь для вывода. Когда вы это сделаете, - это, когда вы применяете текущую культуру.

Точно так же, когда вы получаете входную строку из вашего пользователя (например, при заполнении формы), вы разобрать значение к DateTime, используя текущую культуру снова.

Собственные типы данных не являются строками - и, следовательно, культура не зависит от них.

Примечания:

  • Если вы хотите, чтобы увидеть шестнадцатеричное представление родной двоичной форме любого типа SQL данных, вы можете использовать что-то вроде: select convert(varbinary, @dt)

  • Осознайте то, что родной формат предназначен для использования в любом месте. Если вы пишете HTTP-поток, текстовый файл или базу данных документов и т. Д., Строковое представление действительно имеет значение , потому что строка - это собственный формат в этих сценариях.

И чтобы доказать это относится к более даты, считают:

select 123, 123.45, convert(varbinary, 123), convert(varbinary, 123.45) 

--results: 123 123.45 0x0000007B 0x0502000139300000 
+0

Мэтт, вы упомянули 'SSMS, что вы действительно получили результаты через свой кода в SqlDataReader'. Просто интересно, где доступна информация в Интернете? –

+0

@ Love - извините, я не понимаю, что вы просите. –

+0

Я имел в виду, если вы запускаете запрос в 'SSMS', код под капотом фактически использует' SqlDataReader' для получения результата? Другими словами, если мы проверим dlls 'SSMS' на отражение красных ворот или' IL Spy'. Он содержит 'SqlDataReader'. Это твой смысл? –

Смежные вопросы