我正在开发一个使用 Xamarin.Forms 和 Azure 应用服务(包括离线同步)的应用程序。
在客户端有这样一段代码:
appointment.StartDate = System.DateTime.Now;
假设约会。StartDate 现在是 2017-07-05 12:00:00.
用户将数据同步到服务器后,会发生以下情况:
SqlLite 数据库中的日期(客户端):2017-07-05 12:00:00
服务器数据库中的日期:2017-07-05 10:00:00
因此,我假设 Azure 将我的日期更改为 UTC。这在技术上可能是正确的,因为您应该始终将 UTC 存储在数据库中并在客户端中处理时区转换。但不幸的是,服务器数据库很旧并且存储区域设置日期。
如何让 Azure 将客户端的本地日期而不是 UTC 存储在服务器数据库中?
我尝试将 Azure 中的 WEBSITE_TIME_ZONE 属性更改为我的本地时区,但这不起作用:http://www.louischarlesgagnon.com/post/azure-app-service-set-timezone-for-your-web-应用
更新 06.07.2017:
经过进一步研究,我发现这是一个已知的“问题”。
看这里:
https://github.com/Azure/azure-mobile-apps-net-client/issues/131
Azure 移动应用程序在 Sqlite 数据库中保存错误的日期时间
https://forums.asp.net/t/1808269.aspx?DateTime+issues+with+Azure+c+javascript+sql+so+confused+
读完本文后,我能够构建一个解决部分问题的解决方案。在客户端,我现在正在做类似的事情。
public System.DateTime? Start
{
get
{
System.DateTime? dateTime = GetValue<System.DateTime?>(_start);
if (dateTime.HasValue)
dateTime = System.DateTime.SpecifyKind(dateTime.Value, System.DateTimeKind.Utc);
return dateTime;
}
set
{
System.DateTime? dateTime = value;
if (dateTime.HasValue)
dateTime = System.DateTime.SpecifyKind(dateTime.Value, System.DateTimeKind.Utc);
SetValue<System.DateTime?>(_start, dateTime);
}
}
这告诉 Azure 该日期已经是 UTC 格式,Azure 无需进行转换。这适用于客户端创建的 System.DateTime 现在无需转换即可成功存储在服务器数据库中的情况。
但是现在还有一个问题:
当 Azure 将服务器数据库中存储的日期返回给客户端时,Azure 会将“UTC 日期”转换为本地日期。以下是当前情况的示例:
客户日期:2017年7月6日14:30
-> 客户端将日期推送到服务器
服务器日期:2017年7月6日14:30
-> 客户端从服务器获取日期
客户日期:2017年7月6日16:30
但不幸的是,服务器数据库很旧并且存储区域设置日期。如何使 Azure 将客户端的本地日期而不是 UTC 存储在服务器数据库中?
根据您的描述,我建议您可以存储长类型值 DateTime.UtcNow.Ticks 因为您的日期时间不使用日期时间类型。
该值不会在您的服务器数据库中更改,并且可以转换回 UTC 时间。
当您想使用时间时,您可以将 Ticks 转换回日期时间。
更多详情,可以参考以下代码:
//get utc time ticks
long i = DateTime.UtcNow.Ticks;
//convert back to local time
DateTime myDate = new DateTime(i).ToLocalTime();
我是对的,我必须调整我的旧应用程序,以便它们可以处理 UTC?
我认为,我建议您可以将 UTC 时间存储到数据库中。然后您可以将 UTC 时间转换为本地时间。这是设计应用程序的正确方法。如果有不同时区的客户,如何将数据库的本地时间转换为客户时区的本地时间?
UTC 是全球通用的时间标准。世界计时中心已同意保持其时间尺度紧密同步或协调,因此被称为协调世界时。
所以我建议您可以使用 tolocaltime 方法将 UTC 时间转换为应用程序中的本地时间。