角度日期在 $format 上四舍五入

Posted

技术标签:

【中文标题】角度日期在 $format 上四舍五入【英文标题】:Angular date rounding down on $format 【发布时间】:2015-03-03 11:42:33 【问题描述】:

所以我试图用 mongodb / mongoose / angular 来处理日期。

我试图将 用作日期选择器。但它需要 yyyy-MM-dd 格式。猫鼬模式生成的日期在哪里:

created: 
    type: Date,
    default: Date.now
,

这些日期的格式如下:2014-12-13T22:23:20.633Z

所以我四处寻找人们在需要转换时如何处理与数据模型的绑定。

我想出了以下指令。

'use strict';

angular.module('clients').directive('mongooseDateFormat', ['$filter',
function ($filter) 
    return 
        require: 'ngModel',
        link: function (scope, element, attrs, ngModelController) 
            ngModelController.$parsers.push(function (data) 
                console.log(data);
                data = $filter('date')(data, 'yyyy-MM-dd');
                console.log(data);
                return data; //converted
            );

            ngModelController.$formatters.push(function (data) 
                console.log(data); // gets 2015-01-12T00:00:00.000Z
                data = $filter('date')(data, 'yyyy-MM-dd');
                console.log(data); // converts to 2015-01-11
                return data; //converted
            );
        
    ;

]);

所以我包含了我正在测试值的 console.log 函数,并在上面的代码中显示了 cmets 中的一些示例日期。

可以看到 2015-01-12T00:00:00.000Z 变成了 2015-01-11。

因此发送到过滤器的值带有 0 时间戳,并且 $format(date)(data, "yyyy-MM-dd") 命令删除了时间戳但更改了日期。

(..sigh.. 脏话已删除)

对于必须关心日期格式的新手来说,这简直令人震惊。是我没有使用时区的问题吗?我的意思是 mongodb 和 mongoose 没有生成时区?当您尝试格式化时,为什么时间为零的日期会向下舍入到前一个日期?

当有人告诉我简单的答案时,我可以继续抱怨这有多奇怪,并让自己听起来很愚蠢。我就发帖看看有没有人知道。

<input type="text" data-mongoose-date-format data-ng-model="client.mydate">

<input type="date" data-mongoose-date-format data-ng-model="client.mydate">

它们都在您输入日期后绑定,它被转换并返回一个少一天的日期。

【问题讨论】:

【参考方案1】:

这是因为您的时间字符串末尾的 Z 表明这是 UTC,并且日期过滤器将日期转换为您的本地时区。如果您使用 Angularjs 1.3.*,您可以添加时区参数:

$filter('date')(data, 'yyyy-MM-dd', 'UTC');

【讨论】:

"dependencies": "bootstrap": "~3", "angular": "~1.2", "angular-resource": "~1.2", "angular-mocks": "~1.2", "angular-cookies": "~1.2", "angular-animate": "~1.2", "angular-touch": "~1.2", "angular-sanitize": "~1.2", "angular-bootstrap": "~0.11.2", "angular-ui-utils": "~0.1.1", "angular-ui-router": "~0.2.11" 这是我的凉亭配置,它是 meanjs.org 堆栈。不幸的是还没有1.3。我想我可以手动尝试自己升级。但我宁愿有一个无需更改包即可工作的解决方案。 您也可以在字符串中正确设置时区:2015-01-12T00:00:00.000+03:00【参考方案2】:

我也在使用 meanjs.org 样板,并且我已经尝试解决同样的问题几个小时了。我将它存储为日期,但由于上述格式错误,无法将其与 ng-model 一起使用。所以我创建了上面的指令,只是发现如果我不希望它自动减去 8 小时,我需要 angular 1.3 来获取 $filter 的时区参数。但是我发现将 angular 升级到 1.3 真的很痛苦,因为很多其他东西都坏了,所以我决定恢复到 1.2,而不是跟随那个兔子洞。

但是,我没有骗你,我可以通过在我的服务器模型中将 mongoose 数据类型从 Date 更改为 String 来规避整个问题。这消除了自动时区转换,但仍允许您在数据绑定中使用日期过滤器。

show.date | date: 'mediumDate' 尽管以字符串形式存储在 mongo 中,但它的格式仍然完美,没有令人讨厌的自动时区转换。

此外,当日期存储为字符串时,在编辑表单中使用时,它完全不需要转换。

<input type="date" data-ng-model="show.date" id="date" class="form-control" placeholder="Show date" required> 工作正常,您不需要指令。

我意识到,从数据架构的角度来看,最好将日期存储为 Date 类型。但是,对我来说,这是一个更简单的解决方案,直到样板以 1.3 角度开箱即用,这将更容易避免存储日期的自动时区转换。

【讨论】:

以上是关于角度日期在 $format 上四舍五入的主要内容,如果未能解决你的问题,请参考以下文章

27 Python - 数值 日期与时间

MySQL处理函数

如何使 number_format() 不四舍五入

如何将日期时间列四舍五入到最近的一刻钟

d3.format "none" 类型不四舍五入

PHP number_format():将数字四舍五入,然后格式化为货币