Web API OData - 日期和夏令时
Web API OData - dates and daylight savings
我有一个数据库 table 包含(在其他字段中)一个日期和一个值。
一年中的每一天都有记录,下面的子集包含夏令时(英国夏令时)开始和结束的 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 来 return 来自这个 table 的数据,这里是相同日期范围的 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
link 似乎对这个问题有了一些启发:
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 returned 是 UTC(见时间末尾的 'Z'邮票?)。
OData V4 不包括 DateTime
作为其标准 edm 类型。在 Web API 中,DateTime 映射到 DateTimeOffset。
如果要使用DateTime,请确保您设置了TimeZoneInfo,否则将使用本地设置。
更多信息,请参考来自odata团队的sample page。
我有一个数据库 table 包含(在其他字段中)一个日期和一个值。 一年中的每一天都有记录,下面的子集包含夏令时(英国夏令时)开始和结束的 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 来 return 来自这个 table 的数据,这里是相同日期范围的 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
link 似乎对这个问题有了一些启发:
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 returned 是 UTC(见时间末尾的 'Z'邮票?)。
OData V4 不包括 DateTime
作为其标准 edm 类型。在 Web API 中,DateTime 映射到 DateTimeOffset。
如果要使用DateTime,请确保您设置了TimeZoneInfo,否则将使用本地设置。
更多信息,请参考来自odata团队的sample page。