如何在没有时区的情况下发送 AngularStrap datepicker 值?
Posted
技术标签:
【中文标题】如何在没有时区的情况下发送 AngularStrap datepicker 值?【英文标题】:How to send AngularStrap datepicker value without timezone? 【发布时间】:2013-11-03 01:08:15 【问题描述】:我想知道是否可以在不保留用户语言环境的时区信息的情况下使用 AngularStrap 的日期选择器。在我们的应用程序中,我们希望处理具有到期日期的 Contract 对象。
添加或编辑合同对象时,有一个日期选择器字段用于选择日期。会发生以下情况:
-
用户选择日期(例如2013-10-24)
Angular 将 javascript 日期对象绑定到 ng-model 字段
绑定的日期对象位于用户的时区(例如 GMT+3)
用户提交表单
使用 Angular 的 $http 服务将日期发送到服务器
在第 5 步中,日期被转换为 UTC 格式。所选日期为 GMT+3 2013-10-24 午夜,但 UTC 转换将日期更改为 2013-10-23 晚上 9 点。
我们如何防止转换,或者在整个过程中使用 UTC 日期?我们不希望合同的日期根据用户的本地时区而改变。相反,我们希望日期始终为 2013 年 10 月 24 日,无论哪个时区。
我们当前的解决方案是对 AngularStrap 库进行小幅更改,以便日期在发送到服务器时不会更改。
如果我们可以在服务器中获取用户选择的时区,我们可以在那里进行另一次转换,但服务器没有该信息。
感谢所有想法!
【问题讨论】:
【参考方案1】:问题不在于 AngularStrap。它只是 javascript 日期的工作方式以及 JSON 如何格式化它们以进行传输。当您将 javascript 日期对象转换为 JSON 字符串时,它会将字符串格式化为 UTC。
例如,我在犹他州,现在是 2013 年 10 月 24 日的 07:41。如果我创建一个新的 javascript 日期并将其打印到控制台,它会说:
Thu Oct 24 2013 07:41:19 GMT-0600 (MDT)
如果我将同一日期字符串化(使用JSON.stringify(date)
,我会得到:
"2013-10-24T13:41:47.656Z"
您可以看到的不是我当前的时区,而是 UTC。因此,当表单从 javascript 对象转换为 JSON 字符串时,转换发生在表单发送到服务器之前。
最简单的方法是在将日期发送到服务器之前将日期更改为您自己选择的字符串。因此,与其让 JSON 将日期更改为 UTC,(假设您不关心一天中的时间),您可以这样做:
var dateStrToSend = $scope.date.getUTCFullYear() + '-' + ($scope.date.getUTCMonth() + 1) + '-' + $scope.date.getUTCDate();
这将为您提供一个类似于 '2013-10-24'
的基于 UTC 的字符串,然后您可以将其发送到服务器,而不是包含时间信息的 JSON 格式。希望这会有所帮助。
更新:正如@Matt Johnson 所说,有两种方法可以做到这一点。你说:How could we prevent the conversion, or use UTC dates during the whole process?
。如果您想使用 UTC,请使用我上面的解释。如果您只想“阻止转换”,可以使用以下内容:
var dateStrToSend = $scope.date.getFullYear() + '-' + ($scope.date.getMonth() + 1) + '-' + $scope.date.getDate();
【讨论】:
很好的解释,但为了避免 OP 描述的问题,您应该不在最后一步使用 UTC。 感谢详细的解释!我想我们希望我们可以自动化整个日期到字符串的转换,并且仍然保持 Angular 的自动数据绑定。但这对于我们的目的来说已经绰绰有余了。【参考方案2】:有点晚了,但我花了一个下午的时间在这上面,有人可能会觉得它很有用。
另一种以声明方式执行此操作的方法是使用 dateType、dateFormat 和 modelDateFormat 属性。在配置或 html 中设置这些,例如
angular.module('app').config(function ($datepickerProvider)
angular.extend($datepickerProvider.defaults,
dateFormat: 'dd-MMMM-yyyy',
modelDateFormat: "yyyy-MM-ddTHH:mm:ss",
dateType: "string"
);
);
DateFormat 是日期将在日期选择器中显示给用户的格式,而 modelDateFormat 是在绑定到您的模型之前将转换为的格式。
我也有来自服务器的默认值,我需要在页面加载时将其绑定到日期选择器。因此,我必须更新 JSON 中服务器序列化日期的格式以匹配 modelDateFormat。我正在使用 Web API,所以我使用了以下内容。
var jsonSettings = Formatters.JsonFormatter.SerializerSettings;
jsonSettings.DateFormatString = "yyyy-MM-ddTHH:mm:ss";
【讨论】:
如果您想以相同的方式处理所有客户(例如,对于您不关心时区的企业应用程序),这是一个很好的解决方案。在客户端,您的日期存储为按 modelDateFormat 属性指定的字符串格式(不幸的是,未记录)。然后可以通过指定 dateFormat 属性来单独本地化 UI 表示。 无法注入 $datepickerProvider。未知提供者:$datepickerProvider 你添加了 mgcrea.ngStrap 模块吗?日期选择器是完全工作还是只是上述实现失败了? 像魅力一样工作。谢谢 这个答案与操作员的要求无关。使用这种格式,它不会停止转换为 UTC,并且仍然会向服务器发布错误的日期。【参考方案3】:“Angular 方式”是使用$filter 服务来格式化日期选择器返回的日期。
示例(HTML):
inpDate | date: 'dd-MM-yyyy'
示例(JS):
$scope.processDate = function(dt)
return $filter('date')(dt, 'dd-MM-yyyy');
Plunkerhere
【讨论】:
是的,我做到了。我想说的是,使用 $filter 可以让你去掉时间部分并以你需要的任何格式使用日期。 @“我们希望日期始终是 2013-10-24,无论哪个时区”这怎么不相关? 问题是,当“过滤”日期被发送到服务器时,它会被序列化,从而返回到 UTC,不需要的时间调整会改变月份的日期。我的技巧是在过滤时将时间设置为中午,如下所示: $filter('date')(dt, 'yyyy-MM-ddT12:00:00.000Z');那么当地时间就不会搞砸了。注意我不确定它是否适用于所有时区。如果您在 +12 时区并且有额外的夏令时调整,则将无法正常工作。 @WeNeigh 仅仅因为日期看起来没有时区信息并不意味着当它被发送到服务器时时区信息不存在 很像接受的答案,过滤后的日期返回一个字符串,如“02-02-2016”。这没有任何时区信息。所见即所得。将其序列化为 JSON 字符串根本不会影响它。其他 Plunkr:plnkr.co/edit/2UrsN5qgTPEqhQjS0F3O?p=preview以上是关于如何在没有时区的情况下发送 AngularStrap datepicker 值?的主要内容,如果未能解决你的问题,请参考以下文章