如何在ASP.NET应用程序中调整时区



我们的ASP.NET应用程序托管在+3时区的服务器上。数据库也位于+3时区。客户端可以在其他时区。

应用程序按日期范围搜索某些事件。我们使用2个Bootstrap日期选择器(BeginDate和EndDate)提取日期。问题是返回了所选BeginDate之前的一些事件,这是不正确的。例如,如果我们在客户端选择BeginDate=11.02.2015。结束日期=2015年2月11日。对于某些时区,时间以这种方式移动:

  1. 客户端位于+3时区:@BeginDate='2015-02-11 00:00:00',@EndDate='2015-03-11 00:00:00'(由于客户端和服务器位于同一时区,因此没有切换)
  2. 客户端位于+6时区:@BeginDate='2015-02-10 21:00:00',@EndDate='2015-03-10 21:00:00](由于客户端位于服务器时区的+3,因此有3个小时的轮班)
  3. 客户端位于+7时区:@BeginDate='2015-02-10 20:00:00',@EndDate='2015-03-10 20:00:00](由于客户端位于服务器时区的+4,因此有4个小时的轮班)
  4. 客户端位于+8时区:@BeginDate='2015-02-10 19:00:00',@EndDate='2015-03-10 19:00:00](由于客户端位于服务器时区的+5,因此有5个小时的轮班)

很明显,前一天发生的一些事件是2015年2月10日。也将被退回。

如何克服这个问题?

附加信息:

似乎问题出在客户端,我们有以下代码:

$scope.actionDatesQuery = {
    actionId: -1,
    limit: 10,
    toJSON: function () {
        return ($scope.actionsQuery.searchText) ? {
            ActionId: this.actionId,
            FromDate: moment().toJSON(),
            ToDate: moment().add('y', 1).toJSON()
        } : {
            ActionId: this.actionId,
            FromDate: ($scope.actionsQuery.fromDate) ? moment($scope.actionsQuery.fromDate).toJSON() : moment().toJSON(),
            ToDate: ($scope.actionsQuery.toDate) ? moment($scope.actionsQuery.toDate).add('d', 1).toJSON() : moment().add('y', 1).toJSON(),
            IsOpenDatesIncluded: $scope.actionsQuery.isOpenDatesIncluded
        };
    }
};

选择FromDate和ToDate日期后,我们在服务器端使用它们:

public IEnumerable<ActionInformation> QueryActionsInformation(ActionsQuery query)
{
    var sql = query.BuildSql();
    using (var cn = ConcertDb.CreateSqlConnection())
    {
        var searchText = string.Empty;
        if (!string.IsNullOrWhiteSpace(query.SearchText))
            searchText = "%" + DapperUtils.EncodeLikeString(query.SearchText) + "%";
        return cn.Query<ActionInformationDTO>(sql, new
        {
            BeginDate = query.FromDate,
            EndDate = query.ToDate,
            query.CounterAgentId,
            SearchText = searchText,
            query.CityId,
            query.ActionPlaceId,
            query.ActionTypeIDArray,
            query.MaxPrice,
            query.MinPrice
        }).Select(t => (ActionInformation) t);
    }
}

正如您所看到的,我们也使用moment.js库,似乎我应该在客户端更改该部分,但我不确定是哪种方式。

您应该在概念上进行切换:根本不要在数据库中存储分区时间,而是使用UTC。这样,服务器的物理位置就无关紧要了。

然后,在客户端,您可以使用JavaScript函数Date.getTimezoneOffset()并将其值传递给隐藏字段。回发后,您可以读取服务器端的值,并以适当的方式对其作出反应。

最新更新