【发布时间】:2017-02-14 21:21:44
【问题描述】:
我正在尝试在 Xamarin Forms 应用程序的 AzureMobileServicesClient SQLite 数据库中保存具有 ID 和 DateTimeOffset 的实体。
只要时间戳没有歧义,这项工作就可以正常工作。当我们从夏令时转到标准时间时,有一段时间时间戳可能会因时区而模棱两可。 2016 年在丹麦是 10 月 30 日凌晨 2:00-3:00。
我将实体 DateTimeOffset 保存为 UTC,但它保存为本地时间戳。
当我将不明确的时间戳保存为 2016-10-30 12:30 AM + 0:00 时,它会返回为 2016-10-30 11:30 AM +0:00。 我已经在其他时区对此进行了测试,并且仅在该特定时区从夏令时转换为标准时间期间的模棱两可的时间发生。
我在这里看到了针对普通 SQLite 数据库修复的问题:http://www.thomaslevesque.com/2015/06/28/how-to-retrieve-dates-as-utc-in-sqlite/
但是因为我使用的是 AzureMobileServes,所以解决方案在这种情况下不起作用。
在这段代码中,我初始化了 AzureMobileService,保存了一个模糊的时间戳,然后再次检索它,并将两次写入屏幕以查看不同的输出
public static class SaveTimeStamp
{
public static async Task Save()
{
//Init mobile service Client
var mobileService = new MobileServiceClient(Configuration.MobileAppsUrl);
//init MobileService Database
var dataStore = DependencyService.Get<IDataStore>();
var path = dataStore.GetPath("store.db");
dataStore.CreateFile(path);
var store = new MobileServiceSQLiteStore(path);
store.DefineTable<Entity>();
await mobileService.SyncContext.InitializeAsync(store, StoreTrackingOptions.NotifyLocalAndServerOperations).ConfigureAwait(false);
var entityTable = mobileService.GetSyncTable<Entity>();
//Save entity with ambiguous timestamp
var ambiguousTimestamp = new DateTimeOffset(2016, 10, 30, 0, 30, 0, TimeSpan.Zero); //UTC: 30th of October 12:30 AM + 0:00 => DK time:30th of october 2:30 AM + 2:00
var entity = new Entity
{
Id = Guid.NewGuid().ToString(),
Timestamp = ambiguousTimestamp
};
Debug.WriteLine("Saving datetime UTC: " + entity.Timestamp.UtcDateTime);
await entityTable.InsertAsync(entity).ConfigureAwait(false);
//Fetch saved entity
var refecthedEntities = await entityTable.Where(e => e.Id == entity.Id).ToListAsync();
var refecthedEntity = refecthedEntities.FirstOrDefault();
if (refecthedEntity.Timestamp != ambiguousTimestamp)
{
Debug.WriteLine("Refecthed datetime UTC do not match: " + refecthedEntity.Timestamp.UtcDateTime);
}
else
{
Debug.WriteLine("Refecthed datetime UTC: " + refecthedEntity.Timestamp.UtcDateTime);
}
//output
//[0:]Saving datetime UTC: 10/30/2016 12:30:00 AM
//[0:]Refecthed datetime UTC do not match: 10/29/2016 11:30:00 PM
}
}
class Entity
{
public string Id { get; set; }
public DateTimeOffset Timestamp { get; set; }
}
因为这是一个 Xamarin 应用程序,所以我在 xamarin.ios 项目中也有一些代码来初始化数据库。
//IN Xamarin.IOS
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
Microsoft.WindowsAzure.MobileServices.CurrentPlatform.Init(); //Init Azure mobileservies on IOS Current IOS 9.3
SQLitePCL.CurrentPlatform.Init();
LoadApplication(new App());
App.ScreenWidth = (int)UIScreen.MainScreen.Bounds.Width;
App.ScreenHeight = (int)UIScreen.MainScreen.Bounds.Height;
return base.FinishedLaunching(app, options);
}
public override void WillEnterForeground(UIApplication uiApplication)
{
base.WillEnterForeground(uiApplication);
uiApplication.IdleTimerDisabled = true;
}
public override void DidEnterBackground(UIApplication uiApplication)
{
base.DidEnterBackground(uiApplication);
uiApplication.IdleTimerDisabled = false;
}
}
我尝试在实体上使用 DateTime 而不是 DateTimeOffset,并且只使用 DateTimeKind=UTC,但得到了相同的结果。
【问题讨论】:
-
如何存储日期时间?作为蜱虫?
-
那是由框架决定的;实体类有一个 DateTimeOffset 类型的属性 Date。当我检查 Sqlite 数据库时,它被保存为自某个偏移量以来的秒数。
-
对,AsTicks 确实是默认设置。只是想验证一下。 SqlLite 对此没有任何问题,因此确实是 Azure 服务问题。
-
你有完整的样本要分享吗?我想看看上下文。
-
第一个代码中存在一些错误,现已修复。 SaveTimeStamp 类不是我的应用程序的一部分,但我编写了该类来识别保存不明确时间戳的问题。我将 SaveTimeStamp 转换为静态,所以我希望它包含足够的信息。如果您需要更多信息,请告诉我。
标签: c# sqlite datetime xamarin.forms azure-mobile-services