• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C#教程 > .NET企业级项目中遇到的国际化问题和解决方法

.NET企业级项目中遇到的国际化问题和解决方法

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了c net反射 解决问题,pvp.net断开怎么解决,项目问题解决方案,项目拟解决的关键问题,项目需要解决的问题等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

企业级的系统和我们平常桌面、手机上运行的软件有着很重要的区别,其中比较重要的一点就是环境(包括第三方的系统的不同接口以及各系统的不同版本、安全性、数据等)比较复杂,所以不论在产品维护还是部署过程中要考虑的因素都有很多。

偶们的系统的最新版本最近在南非上线,遇到了不少问题。昨天晚上本屌和同事解决了一个比较“严重”的问题(因为影响到系统的核心功能),发现是由“国际化”的问题所引起。虽然找到问题的原因并不困难,但是要在客户的环境解决还是费了不少精力(因为不能从产品中去修复这个问题,即使给一个补丁按照公司的流程至少也需要半个月)。之前我也帮运营团队解决过一部分这类问题,在工作中也看到过不少,那么这里一并记录一下吧。希望大家在以后的开发过程中多加注意。

一、数据库的日期时间格式问题

这应该是几乎所有的系统在部署到不同国家的客户环境中都会遇到的问题,卡死不少程序,耗费无数人力。因此这是在数据存储时一定要格外注意的地方。这里以SQL Server为例。

(1)数据表中的时间格式

对于日期和时间,SQL Server中提供了datetime、datetime2、datetimeoffset、date、time这几种类型。我个人推荐只使用datetime和datetime2,因为这两个类型与.NET的程序兼容性最好(都可以直接对应成DateTime)。在.NET中也提供了DateTimeOffset类型,但是在一些比较老的语言中并不支持,为了兼容使用datetime就足够了。使用其他类型会牵扯到转型的问题,应尽量避免以免产生额外的问题。

需要注意的是,datetime支持的最小时间是1753年,因此要避免在程序中直接使用DateTime.MinValue传到数据库中,否则会产生out-of-range的错误。

在一些古老的系统中,会使用int类型来存储日期,因为int会占4个字节,所以两者互相转型是支持的,使用convert进行转型即可,一般不会有什么问题。

(2)时区的问题

建议在数据库中所有数据都以UTC时间保存,在显示的时候客户端根据本地的时区进行处理,因此在存储过程中一定要注意把时间转换成UTC时间。如果不保存UTC时间,以后在显示和迁移的过程中难免会发生混乱,所以尽量不要使用当地的时间来保存,即使系统只在一个地区使用。

在设计SSRS报表时,也要注意时区的问题。由于数据库中存储的是UTC时间,所以在调用Reporting Service服务的时候应把用户输入的时间转换成UTC时间后传给报表服务。在显示的使用,使用如下代码格式化单元格:

不要在报表的存储过程中对时区进行处理。虽然很方便且直观,但是当你的系统有几十张报表并且由不同的人开发的时候就会发现混乱的局面。

(3)报表的时间格式

这是微软考虑不周导致的问题。由于报表服务是一个Web Service,所以在实际的运行环境中无论是日期控件还是报表中输出日期的单元格都是使用IE的语言设置,而非Windows的地区。但是在设计报表的时候它又是使用的Windows的日期格式。如果客户有这类需求,那么我们至少修改IE的设置。

但是最坑人的地方是要修改的是数据库所在的服务器的IE设置,这样做会影响到所有的客户端,那么这也没办法。有时候这样做了也不见得好使,似乎又与数据库的连接用户的默认语言有关,所以这类问题我们一般不会花太多时间去修正。

好在这只是一个显示的问题,并不影响系统的正常功能,也不会出错,所以很少会听到客户抱怨这类问题。

(4)应用程序与数据库之间的日期时间传递

我们首先来看下面一段代码:

string sql = string.Format("SELECT * FROM [User] WHERE [CreationTime] < '{0}'", creation_time);</div>
在数据库中CreationTime是一个datetime类型,而我们单引号之间的内容是一个字符串,此时SQL Server会自动对字符串进行转型,因此相当于隐式实现了一个convert语句,把{0}处的内容转型成datetime类型。{0}处实际上是一个字符串,在string.Format方法里会隐式调用creation_time的ToString方法,这个方法所返回的日期时间的格式会依据当前线程所处的语言环境来确定。

在调试的过程中似乎不会发现问题,但是当产品给一个国外的客户时,就很有可能发现SQL Server抛出out-of-range的错误,大意是将varchar转型成datetime类型时越界。导致这个问题的原因简单来说就是因为客户端的日期格式与数据库的设置不一致(更详细的下面会说明),此时系统理解的年、月、日这几个字段所处的位置不在正确的地方上,因此有时会越出月或者日的边界。

避免这个问题的根本解决办法是在访问数据库的时候只使用参数形式,根本不应该出现非参数的拼接形式(同时可以避免SQL注入以及其他bug),如果你在做代码审查,看到上面这种代码应该果断reject回去。使用参数形式的代码大概是这样:

SqlCommand command = new SqlCommand("SELECT * FROM [User] WHERE [CreationTime] < @creationTime", connection);
command.Parameters.AddWithValue("creationTime",  creation_time);</div>
这样,就会避免将DateTime类型转型成字符串,直接使用SQL Server兼容的类型访问,就避免了格式不一致导致的转型失败(或者转换成错误的结果)。

我们在系统日志中发现某个模块频繁抛出越界的错误,就是因为没有使用参数的形式进行访问。与此对应的系统其他模块都没有这个类型的错误。

 (5)SQL语句中的日期格式转型问题

这就是昨天做支持过程中遇到的一个非常诡异的问题。在我们的产品的SQL语句中有一段类似下面这样的代码:

DECLARE @startTime VARCHAR(100)
SELECT @startTime = CONVERT(VARCHAR, timeIn, 23), @endTime = CONVERT(VARCHAR, timeIn + 1, 23) FROM...</div>

我们不谈论这段代码写得怎样,我们只关心为什么会出错。在客户现场中,客户的描述是:“在前一天系统还是好的,但是在换班后(我们的系统执行换班操作后日期会往后加一天),系统就无法操作。”

分析日志发现抛出的错是日期转型越界,出错的代码片段应该就是在这个地方,那么为什么会出错呢?

经过一番折腾,发现了SQL Server的一个隐藏炸弹(还好有测试的同事在其他系统见过这个问题,否则也不会往这个方向去想):对于每一个有权限访问数据库的用户(包括Windows登录方式和SQL Server登录方式),在用户的属性中都有一个称之为“默认语言”的属性。在我们公司的产品中,基本只会在British English和English这两者之间进行选择。

这个属性会影响到SQL语句中牵涉到日期与字符串转型时的处理。因此,在SQL语句中转型是与这个“默认语言”有关系的。同时,还会与客户端(访问数据库的服务所在的机器)的本地时间格式有关。

客户的数据库登录用户的默认语言选择是British English,而数据库服务器和客户端的时间格式配置都是南非的时间格式。这种不一致可能会导致一些不可预知的问题。我们要用户把默认语言给成English(注意:1. 改了之后要重启SQL Server的服务使之生效; 2. 特别注意修改的是访问数据库的用户,每个用户都有这个属性),然后问题莫名其妙地就解决了。

但是后来我们在实验环境中按照这种配置都无法重现这个问题,我觉得有可能是客户修改了一些日期格式的原因所导致。

今天早上我做了一个实验,把默认语言设置成British English,而客户端的时间格式是中国的格式,此时上面的timeIn + 1得到的结果竟然是月份加1!这样就使我们恍然大悟:难怪客户在前一天没有问题,而过了一天问题才出现。因为出现问题的时间是6月12日,由于某种特殊的配置(我们至今还是没尝试出是何种格式),系统把12当成是月份+1,得到13就越界了,而使用6月11日就不会出越界的问题,但结果是错误的。

这显而易见是微软的一个bug,无论何种配置,都不应该转型出错,即使是月份+1,应该会进到年的字段去。

上面这段SQL语句的正确写法应该是使用DATEDIFF进行日期运算,而且更不应该出现第三个参数“23”这种直接指定格式的输出。

(6)结论

通过上面的分析,有一点可以肯定的是:在编码过程中,除非仅用于显示,否则必须要避免日期和字符串的相互转换!

日期转型成字符串应该只在客户端显示的最后一步进行转型,而字符串转换成时间应该只在应用程序中使用DateTime提供的与时间格式相关的方法进行完成。一定要避免使用字符

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • .Net常见问题之C#中的委托
  • .NET企业级项目中遇到的国际化问题和解决方法

相关文章

  • 2017-05-28C#图形区域剪切的实现方法
  • 2017-05-28c#消息提示框messagebox的详解及使用
  • 2017-05-28C#怎样才能实现窗体最小化到托盘呢?
  • 2017-05-28WPF弹出带蒙板的消息框
  • 2017-05-28C#独立域名查询代码
  • 2017-05-28C#面向对象特征的具体实现及作用详解
  • 2017-05-28C# 开发圆角控件(窗体)的具体实现
  • 2017-05-28C# Dynamic关键字之:调用属性、方法、字段的实现方法
  • 2017-05-28浅谈C#中的常量、类型推断和作用域
  • 2017-05-28再谈异常处理try catch finally

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • c#英文单词分类统计示例分享
    • winform dateTime数据类型转换方法
    • C#线性渐变画刷LinearGradientBrush用法实例
    • C#中一些你可能没用过的调试窗口的方法
    • C#实现TIF图像转PDF文件的方法
    • 深入探讨C#中的结构struct
    • C#实现根据年份计算生肖属相的方法
    • C#在MySQL大量数据下的高效读取、写入详解
    • C#基础语法:方法参数详解
    • 实例详解C#正则表达式

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有