我正在处理一个数据库,其中所有的日期都被错误地使用web服务器本地日期/时间(在本例中是东方时间)存储。假设数据库中持久化的所有日期/时间都是东方的,那么一旦我将数据选择到我的C#模型中,如何将此日期转换为本地时间?
发布于 2015-03-13 04:30:46
您可以在数据库中存储基于UTC的日期时间,也可以存储具有正确偏移量的datetimeoffset。请参阅DateTime对DateTimeOffset,以决定用例中哪一个是有意义的。(我将假定此响应的其余部分为UTC日期)
问题是,由于您只存储了一个datetime,并且它是基于美国东部时间的,您已经有一个潜在的信息丢失。让我解释一下:
现在也许你会很幸运,并发现在这个小窗口中没有任何交易记录,但也许没有。不过,有一种方法可以消除歧义。
在上表中,由于我们在1:00时有一些不符合顺序的记录,所以合理的假设是,记录101-104发生在东部夏令时(UTC-4),记录105-107发生在东部标准时间(UTC-5)。
但是,这种方法并不是很容易自动化的。有时,您会在不确定的时间内处理事务,但不会出现任何不顺序的事务。这意味着,要么所有的人都是在过渡之前,要么是所有的人都是在过渡之前。没办法说出来。
您需要编写一些C#代码或SQL脚本来查询表并转换数据。我建议为输出创建第二个表,或者在现有表中创建第二个列。不要试图更新合适的值,否则如果事情出了问题,你将很难解开它。
关于转换本身,如果使用.NET代码进行转换,可以使用TimeZoneInfo类和"Eastern Standard Time"时区id。不要与命名混淆,该标识符代表EST和EDT -尽管它的名称中有“标准”一词。
DateTime dt = (DateTime) yourSqlDataReader["TransactionDate"];
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
if (tz.IsAmbiguousTime(dt))
{
// record this item in some way, so you can review it manually later
}
else
{
DateTime utc = TimeZoneInfo.ConvertTimeToUtc(dt, tz);
// save this field to a new table or a new column in the current table
}在您完成转换之后,尽管去手工填补任何不明确时期的空白。当您满意时,然后将值复制回原处,或者将代码移动到指向新的UTC列,等等。
从这一点开始,始终按照UTC来存储事务时间。在.NET中使用DateTime.UtcNow,在SQL中使用GETUTCDATE()或SYSUTCDATETIME()。
现在问题的最后一部分是-您将如何转换到用户的时区显示?当然,您可以再次使用TimeZoneInfo,也可以使用更全面的库,如野田时间。但是无论你走哪条路,你都可能需要知道用户的时区是什么!最简单的方法是通过用户配置文件页面中的下拉设置(例如)从应用程序的用户收集这些信息。
另一种方法是,如果您熟悉JavaScript,可以将UTC时间一直传递到客户端,然后将其加载到JavaScript Date对象中,或者使用像moment.js这样的JavaScript库。这两种方法的好处是,客户端将能够自动将值转换为用户计算机设置的任何时区。如果您使用的是现代应用程序开发风格,比如通过WebAPI发送数据,并使用JavaScript框架(如Angular )显示数据,这一点尤其有效。
发布于 2015-03-13 03:46:17
您可以将TimeZoneInfo类用于这样的操作(来自客户端)
将时间从一个时区转换为另一个时区。
String dbTime = "2015.02.21 1:00 AM"; // <= A sample time
DateTime time = DateTime.Parse(dbTime); // <= Convert it to a datetime
TimeZoneInfo eastern = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"); // <= TimeZoneInfo for Eastern
TimeZoneInfo local = TimeZoneInfo.Local; // <=TimeZoneInfor for local
Console.WriteLine(TimeZoneInfo.ConvertTime(time, estern, local)); // Will return the Local time related to provided to Eastern Time附加:正如Matt所解释的,是的,local将是服务器的时区。因此,要使用这种方法,正如他Matt解释的那样,您需要从先前设置的设置中识别用户时区,或者从他们的IP (如果可能的话)或通过传递给服务器的字段(可能是通过URL)识别用户时区。
https://stackoverflow.com/questions/29024394
复制相似问题