我需要在一个非常大而古老的Delphi系统中实现时区,在这个系统中有一个中央SQL Server数据库,并可能在世界各地不同时区中安装数百个客户端。应用程序仅通过使用数据库服务器的日期/时间与数据库进行交互。因此,在数据库和客户端机器上保存的所有时间戳都是数据库服务器发生时的日期/时间,而不是客户机的时间。
因此,当客户端要显示来自此数据库的某事物(例如事务)的日期/时间时,它需要显示转换到本地时区的日期/时间。这就是我迷路的地方。
我很自然地假设在SQL中应该有一些东西可以识别时区并动态地转换DateTime字段。不过,我不确定这样的事情是否存在。如果是这样的话,那将是完美的,但如果不是,我需要找到另一种方法。
这个Delphi系统(多个项目)使用使用ADO组件、VCL数据感知控件和QuickReports (使用数据源)的Server数据库。因此,有很多地方的数据直接从数据库查询到屏幕上的呈现,没有任何代码实际将这些数据放在屏幕上。最后,我需要知道何时以及如何获得适当的转换时间?
如何确保在遗留应用程序中正确处理日期和时间?
发布于 2012-12-07 18:23:15
日期和时区是很棘手的事情,而且通常不管您正在处理的是哪种技术栈,很少有关键的解决方案。
大多数数据库都会将日期或时间戳存储为与给它的确切日期或时间戳相同的值。当通过查询与数据库交谈时,他们通常假设所有日期和时间戳都代表同一时区下的一个时间点。换句话说,如果我写了一个查询,看看2012年8月2日下午4:10是否在同一天下午5:10之前,那么这将评估我是否真正返回了那个记录。假设当我的数据库服务器位于太平洋标准时间时,记录保存为下午4:10东部标准时间。数据库与时区无关,现在我的查询没有返回预期的数据。
之前将所有应用日期和时间转换为UTC或GMT。
像Java、Javascript和C#这样的语言对日期和时间的处理方式有点不同。它们通常将时间度量为从给定的通用时间点起的毫秒数。这是一个普遍的时间,因为从0起的特定毫秒数代表了任意给定点上不同时区中的不同日期或时间。这些语言中的大多数通常都有一个可靠的日期和时间API,或者可以找到一个好的第三方库,使在多个时区中查看这毫秒尽可能不痛苦。
除非另有规定,否则,如果我在公共语言中使用标准数据访问API,大多数用户将接受date对象并将其转换为服务器默认时区的日期和时间(以指定的数据库格式表示)。了解语言数据访问API和数据库是如何存储日期的,以及它如何从数据库中解释日期,并尝试在GMT中将日期存储在数据库级别。同样,当查询时,请确保您的语言中的Date对象或变量表示相当于存储在数据库中的GMT日期时间的毫秒计数。
中使用的日期保留时区
我的意思是,如果数据库中有一个修改过的日期列,那么它对业务逻辑可能并不重要,但是列约会日期可能很重要。
在架构中的某个位置,您需要确定区域设置特定数据的存储位置,并将时区存储到相应的父表中来定义该区域设置。您正在考虑日期的业务逻辑或准备显示日期的演示逻辑必须能够获取适当的时区,以便当我比较下午4:10到5:10时,我将比较来自适当的通用时间的日期。美国东部时间下午4:10和PST下午4:10是世界时间的分离点。同样,一个好的日期和时间API或第三方库使日期比较变得容易,当您了解日期在该编程语言中如何工作的基本性质时。
业务逻辑应该重构为时区感知。
应该重构表示逻辑,以表示一个显示值,该值将根据适当的给定时区适当地显示正确的数据。
在执行这项工作时,需要考虑的最后一个想法是编写详尽的单元测试,彻底耗尽许多类型的日期和时间组合,以确保所有业务逻辑都能按预期工作。
发布于 2014-12-30 16:36:22
这里的问题是视图直接连接到模型。
虽然在delphi中实现这一点听起来很可怕,但第一步是执行关注点分离。
您可以使用MVVM方法并具有中间视图--执行数据库值本地化转换以供显示的中间视图。这些相同的视图模型可以将本地化的输入转换为数据库在存储数据时所期望的时区。
MVP或其他MV*变体可能更适合您目前的设置和您的确切需求,但您得到了图片。所有这些工作的好处是,未来的本地化改革将非常、更容易实现。
https://softwareengineering.stackexchange.com/questions/178661
复制相似问题