【问题标题】:Azure Mobile Apps saves incorrect datetime in Sqlite databaseAzure 移动应用在 Sqlite 数据库中保存不正确的日期时间
【发布时间】: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


【解决方案1】:

这看起来像是一个已经报告的错误:https://github.com/Azure/azure-mobile-apps-net-client/issues/131

随时关注该错误。

【讨论】:

  • 是的,它们是相关的,因为 DateTime 在 Sqlite 客户端数据库中存储为 Local 而不是 UTC。您是否知道此错误是否正在解决或何时可以修复?
  • 目前尚未发布。这个周末我会看看它,看看涉及到什么。如果您有一个带有前端和后端的 GitHub 存储库以及最少的复制,那将会很有帮助。 (否则,我将不得不花时间制作一个)。如果有,请将其添加到问题中。
  • 对不起,我正在为客户的应用程序使用移动应用程序,无法将整个应用程序放在 GitHub 中。
  • 明白。如果没有有效的复制,我们将不得不生成一个。这需要时间,这意味着任何修复都会被延迟。
猜你喜欢
  • 2013-04-20
  • 2019-02-26
  • 1970-01-01
  • 2019-10-30
  • 1970-01-01
  • 1970-01-01
  • 2018-08-23
  • 1970-01-01
相关资源
最近更新 更多