Web API OData -日期和夏令时

本文关键字:夏令时 日期 API OData Web | 更新日期: 2023-09-27 18:14:35

我有一个包含(除其他字段外)日期和值的数据库表。一年中的每一天都有记录,下面的子集包含2015年夏时制开始和结束的日期范围:

Source Data:
ID     Date (dd/mm/yyyy)     Value
...    ...                   ...
8E5    27/03/2015            600
8F5    28/03/2015            600
905    29/03/2015            600  // DST Starts
915    30/03/2015            600
925    31/03/2015            600
...    ...                   ...    
615    24/10/2015            600
625    25/10/2015            600  // DST Ends
635    26/10/2015            600
645    27/10/2015            600

我使用Web API OData从这个表返回数据,下面是相同日期范围的JSON响应:

...
{
  "Id":"8E5",
  "CostDate":"2015-03-27T00:00:00Z",
  "Value":600
},{
  "Id":"8F5",
  "CostDate":"2015-03-28T00:00:00Z",
  "Value":600
},{
  "Id":"905",
  "CostDate":"2015-03-29T00:00:00Z",
  "Value":600
},{
  "Id":"915",                              // Duplicate 29/03/2015, ID field out of sync
  "CostDate":"2015-03-29T23:00:00Z",
  "Value":600
},{
  "Id":"925",
  "CostDate":"2015-03-30T23:00:00Z",
  "Value":600
}
...
{
  "Id":"625",
  "CostDate":"2015-10-24T23:00:00Z",
  "Value":600
},{
  "Id":"635",                              // Missing 25/10/2015?
  "CostDate":"2015-10-26T00:00:00Z",
  "Value":600
},{
  "Id":"645",
  "CostDate":"2015-10-27T00:00:00Z",
  "Value":600
}
...

注意到重复的3月29日吗?从那天起,ID就与源数据不同步了,而且还缺少10月25日。

我的假设是,当数据被序列化为JSON时,本地时间和UTC时间发生了一些事情。

如果我从方程中删除OData并使用正常的Web API,我无法重新创建问题,似乎问题是与OData或JSON格式化器。

我需要做些什么来获得出现在源数据中的日期?

代码(如果相关):

public class BudgetDto
{
    [Key]
    public string Id { get; set; }
    public DateTime CostDate { get; set; }
    public double Value { get; set; }
}
public class BudgetsController : ODataController
{    
    private IBudgetService BudgetService { get; }
    public BudgetsController(IBudgetService budgetService)
    {
        BudgetService = budgetService;
    }
    [EnableQuery(PageSize = 400)]
    public IQueryable<BudgetDto> Get(ODataQueryOptions<BudgetDto> queryOptions)
    {
        return BudgetService.Budgets(queryOptions);
    }
}

更新1
这个链接似乎对这个问题有所启发:
http://blogs.msdn.com/b/bclteam/archive/2010/11/28/time-travel-with-net-or-datetime-datetimeoffset-and-the-lost-dst-hour-greg.aspx

当我的模型使用DateTime作为类型时,OData正在切换到DateTimeOffset,也许这解释了OData和Web API之间的差异,前者不支持DateTime,后者支持。

更新2
DateTimeOffset有一个LocalDateTime属性,它根据源数据包含正确的日期。我不明白的是,源数据上没有任何时区信息,返回的JSON是UTC(参见时间戳末尾的'Z' ?)。

Web API OData -日期和夏令时

OData V4不包括DateTime作为其标准edm类型。在Web API中,DateTime被映射为DateTimeOffset。

如果你想使用DateTime,请确保你已经设置了TimeZoneInfo,否则,它将使用本地设置。

更多信息,请参考odata团队的样例页面