简体   繁体   English

这个C#代码足以应付全球化吗?

[英]Is this c# code enough to handle globalization?

My C# winforms program will be used in following countries 我的C#winforms程序将在以下国家/地区使用

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 ','

I want to make the program run properly irrespective of what regional settings are on users computer. 我想使程序正常运行,而不管用户计算机上的区域设置如何。 My main concern is handling date format and currency fields (Language translation is not a problem because the program will only show English text) 我主要关心的是处理日期格式和货币字段(语言翻译不是问题,因为该程序只会显示英文文本)

To do this I have decided that all dates in the database will be saved with yyyy-mm-dd format and all decimal fields will be saved with . 为此,我决定将数据库中的所有日期都保存为yyyy-mm-dd格式,并将所有十进制字段都保存为. as separator. 作为分隔符。
I created the database with Danish_Norwegian_CI_AS collation . 我使用Danish_Norwegian_CI_AS排序规则创建了数据库。 So I am assuming the data will be saved in the above datetime format & decimal format without me requiring to do anything special. 因此,我假设数据将以上述datetime格式和十进制格式保存,而无需执行任何特殊操作。

I have put the following code in my program 我在程序中添加了以下代码

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

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

Please help me by telling from your experience if the above code is enough to make my program safe 请根据您的经验告诉我上述代码是否足以确保我的程序安全,以帮助我

Culture applies only in the following two scenarios: 文化适用于以下两种情况:

  • Converting a string representation of a value to a native format, which is called "parsing". 将值的字符串表示形式转换为本地格式,称为“解析”。

  • Converting the native format of a value to a string representation, which is called "formatting". 将值的本机格式转换为字符串表示形式,这称为“格式设置”。

When you store a datetime or a decimal or some other type into the database, it is stored in a native format. 当您将datetimedecimal或其他类型的数据存储到数据库中时,它将以本机格式存储。 In a SQL database, this is usually some compact binary value that you will never work with directly. 在SQL数据库中,这通常是一些紧凑的二进制值,您永远不会直接使用它。

Consider the following SQL: 考虑以下SQL:

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

In the first line, we declare a variable of type datetime . 在第一行中,我们声明一个类型为datetime的变量。 It's not a string, it's a specific data type that takes up 8 bytes of memory or disk. 它不是字符串,而是一种占用8个字节内存或磁盘的特定数据类型。

In the second line, we assign a string value to the variable. 在第二行中,我们为该变量分配一个字符串值。 SQL parses the string, converting it to a datetime so it can be stored in the @dt variable. SQL 解析该字符串,将其转换为datetime以便可以将其存储在@dt变量中。 The actual value stored has a hexadecimal representation of 0x0000A41400CF5940 . 存储的实际值具有十六进制表示形式0x0000A41400CF5940

When it did the parsing, the current culture for the environment where the code was running was applied. 进行解析时,将应用当前运行代码环境的区域性。 Because I am in the USA, it interpreted the date as January 2nd. 因为我在美国,所以它将日期解释为1月2日。 If I was in Europe, it would interpret the date as February 1st (changing the internal value to 0x0000A43200CF5940 ). 如果我在欧洲,它将日期解释为2月1日(将内部值更改为0x0000A43200CF5940 )。

Using dates in yyyy-mm-dd format will avoid misinterpretation, but that does not mean that the actual value is stored as a string in that format. yyyy-mm-dd格式使用日期将避免误解,但这并不意味着实际值将以该格式存储为字符串。 It's just that the format is unambiguous, so it will be parsed the same way regardless of culture. 只是格式是明确的,因此无论使用哪种文化,都将以相同的方式解析它。

In the third line of code above, we select the variable to include it in a result set. 在上面的第三行代码中,我们选择变量以将其包括在结果集中。 Though we are selecting it in its native form without any conversion, we ultimately see it in a string representation. 尽管我们以其本机形式选择它而不进行任何转换,但最终还是以字符串表示形式看到它。 If you are running the query in a tool such as SQL Server Management Studio, the output window will format the native values to strings so you can read them. 如果在诸如SQL Server Management Studio之类的工具中运行查询,则输出窗口会将本机值格式化为字符串,以便您可以读取它们。 When doing so, the current culture is again applied. 这样做时,将再次应用当前的文化。 SQL's default is to show dates in yyyy-mm-dd format, rather than the culture-specific format. SQL的默认设置是以yyyy-mm-dd格式显示日期,而不是区域性特定的格式。 But other values, such as decimals, will use the current culture's separator. 但是其他值(例如小数)将使用当前区域性的分隔符。

If instead of running this in SSMS you actually retrieved the results through your own code in a SqlDataReader (for example), then formatting never occurs. 如果实际上不是通过SSMS运行此程序,而是通过自己SqlDataReader 代码检索了结果(例如),则永远不会进行格式化。 The reader maps SQL's binary native value directly to the appropriate .NET native type, using the mappings shown here . 读者可以使用此处显示的映射将SQL的二进制本机值直接映射到适当的.NET本机类型。 A SQL datetime gets natively mapped to a .NET DateTime . SQL datetime时间本机映射到.NET DateTime

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

Now quite often, you see someone doing silly things like this: 现在,您经常看到有人在做这样的愚蠢的事情:

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

This is wasteful because the value is already a DateTime , and this code would use the current culture to format the string, then use it again to parse the string. 这很浪费,因为该值已经DateTime ,并且此代码将使用当前区域性来格式化字符串,然后再次使用它来解析字符串。 That's a lot of string manipulation for no reason whatsoever. 毫无疑问,这是很多字符串操作。

Ultimately, in your .NET code, you will end up using that DateTime value and converting it to a string somewhere for output. 最终,在您的.NET代码中,您将最终使用该DateTime值并将其转换为某个字符串以进行输出。 When you do, that's when you apply the current culture. 当您这样做时, 即是您应用当前的文化。

Likewise, when you receive an input string from your user (such as when filling out a form), you parse the value to a DateTime using the current culture again. 同样,当您从用户那里收到输入字符串时(例如,填写表单时),您将使用当前区域性再次将值解析DateTime

Native data types are not strings - and are thus not affected by culture. 本机数据类型不是字符串 ,因此不受区域性的影响。

Notes: 笔记:

  • If you want to see the hexadecimal representation of the native binary form of any SQL data type, you can use something like: select convert(varbinary, @dt) 如果要查看任何SQL数据类型的本机二进制形式的十六进制表示形式,则可以使用以下方法: select convert(varbinary, @dt)

  • Be aware of whatever the native format is for anywhere you are working. 请注意您在任何地方使用的本机格式是什么。 If you're writing to an http stream, a text file, or a document database, etc., the string representation does indeed matter, because a string is the native format in those scenarios. 如果您正在写入http流,文本文件或文档数据库等,则字符串表示形式确实很重要,因为在这种情况下,字符串本机格式。

And just to prove this applies to more than dates, consider: 为了证明这不仅适用于日期,请考虑:

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

--results:    123    123.45    0x0000007B    0x0502000139300000

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM