【问题标题】:How SQLite.Net-PCL handle UTC timeSQLite.Net-PCL 如何处理 UTC 时间
【发布时间】:2017-01-03 18:17:50
【问题描述】:

我正在使用以下代码:

使用 new SQLite.Net.SQLiteConnection(new SQLitePlatformWinRT(), DBPath) 获取 SQLiteConnection 并创建表。

类包含 DateTime 数据类型

class Transaction 
    {
        [SQLite.Net.Attributes.PrimaryKey, SQLite.Net.Attributes.AutoIncrement]
        public int QId { get; set; }
        public DateTime PurchaseDate { get; set; }  
        public int Amount {get;set;}
        Public string ItemCode {get;set;}      
    }

插入数据如下:

var db = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), DBPath);

 var newItem = new Transaction()
  {  
     PurchaseDate = DateTime.Now,            
     Amount = 100,
     ItemCode = "Abc-C10"               
  };

 db.Insert(newItem);

日期将存储为刻度(例如 636071680313888433),这是 UTC 时间。

1) 使用上面的 DateTime.Now,如果我的电脑时间设置是

1a) 在英国时间,

上面的代码:purchase = DateTime.Now 能正确转换吗?

1b) 在美国时间,

上面的代码:purchase = DateTime.Now 能正确转换吗?

如何在 SQL 语句中处理这个刻度?

如何从某个日期范围内选择所有交易?比如,2016-07-10 到 2016-07-20?

谢谢

【问题讨论】:

  • “正确转换”是什么意思?最正确的行为是没有转化。

标签: sqlite winrt-xaml uwp


【解决方案1】:

使用日期最安全的方法是使用 DateTimeOffset 类型而不是 DateTime

DateTime 不包含有关创建它的时区的信息,它只知道是 UTC 还是本地时间,如果数据要在不同的位置使用,这还不够。

DateTimeOffset 不仅包含时间和日期信息,还包含时区,这意味着结果将始终如您所愿。

使用方式没有区别,只是换个类型:

class Transaction 
{
    [SQLite.Net.Attributes.PrimaryKey, SQLite.Net.Attributes.AutoIncrement]
    public int QId { get; set; }
    public DateTimeOffset PurchaseDate { get; set; }  
    public int Amount {get;set;}
    Public string ItemCode {get;set;}      
}

对于数据库访问:

var db = new SQLite.Net.SQLiteConnection(
   new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), DBPath);

var newItem = new Transaction()
  {  
     PurchaseDate = DateTimeOffset.Now, //or use DateTimeOffset.UtcNow for UTC datetime           
     Amount = 100,
     ItemCode = "Abc-C10"               
  };

 db.Insert(newItem);

【讨论】:

  • Sqlite包含UTC时间时如何选择日期范围。可以告诉我这是怎么做的。
  • 这不起作用,如果我使用 DateTimeOffset 并将其保存到 sqlite-net,那么当我检索它时,该偏移量丢失并已转换为具有零偏移量的等效项。所以使用它完全没有意义。
【解决方案2】:

1a) 在英国时间,上面的代码:purchase = DateTime.Now 能正确转换吗?

1b) 在美国时间, 上面的代码:purchase = DateTime.Now 会正确转换吗?

“正确转换”如果您的意思是转换为正确的时间值,答案是肯定的。它将使用刻度转换为 UTC 时间。

如何在 SQL 语句中处理这个勾号?

如何从某个日期范围内选择所有交易?比如,2016-07-10 到 2016-07-20?

从刻度到其他时间单位的转换如下:

  • 每天滴答声:864,000,000,000
  • 每小时滴答数:36,000,000,000
  • 每分钟滴答声:600,000,000
  • 每秒滴答声:10,000,000
  • 每毫秒滴答数:10,000

因此您可以使用如下 SQL 语句来获取 2016-07-10 到 2016-07-20 的数据:

SELECT min(PurchaseDate) as 'Date',sum(Qty) as 'Size' from Purchase 
group by (PurchaseDate/(864000000000*10)) //864000000000*10 = 1day*10
order by PurchaseDate

更新:如果要选择 2016-07-10 和 2016-07-20 之间的日期,可以使用以下 SQL 语句:

select strftime('%Y-%m-%d %H:%M:%S',purchaseDate/10000000 - 62135596800,'unixepoch') as 'date' from purchase where date between '2016-07-10' and '2016-07-20'

【讨论】:

  • @Xia: 如何在 2016-07-10 和 2016-07-20 之间选择日期?选择 min(PurchaseDate) 作为 'Date', sum(Amount) from Purchase Between " " And " " 。如何在双引号“”中表示日期?
  • 您不能在 SQLite 中的双引号内表达日期。如需在 2016-07-10 和 2016-07-20 之间进行选择,请查看我的更新。
  • @Xia:我很快就会回来。非常感谢你。我会努力在这个项目上展示基于微软 UWP 的 App。我希望我可以为这个 SQLite 数据演示使用一些很酷的控件和 UI。
  • @Xia:在同一个 SQLite 上,我有这个问题,用于使用 SQLite 进行趋势分析。在这里:stackoverflow.com/questions/39487681/…请帮忙。
猜你喜欢
  • 1970-01-01
  • 2015-08-04
  • 1970-01-01
  • 1970-01-01
  • 2016-12-28
  • 1970-01-01
  • 2019-06-24
  • 2011-09-16
  • 2018-11-23
相关资源
最近更新 更多