【问题标题】:Angularjs date filter and moment js return the year '1970' when formatting a yearAngularjs日期过滤器和时刻js在格式化年份时返回年份'1970'
【发布时间】:2017-02-23 16:49:28
【问题描述】:

我有一个从服务器获取的对象,该对象有一个属性:例如obj.year: "2017"。该属性是number。 我只需要显示年份的最后两位数。 当我像这样在 HTML 中格式化它时:

{{obj.year | date : 'yy'}}

它显示:70。我尝试了各种内置的 Angular 年份过滤器,并尝试了 moment js 格式化函数:

  function formatYear(year) {
    return moment(year).format('YY');
  }

但它仍然返回年份 1970。 我不明白为什么它今年会返回,而且只有在格式化时才会发生这种情况?如果我不对它应用任何格式,它会返回对象的正常值 - 2017

【问题讨论】:

  • momentJs 接受完整日期作为字符串或时间戳。例如:moment('2016-08-20').format('YY'); moment(new Date().getTime()).format('YY');

标签: angularjs momentjs


【解决方案1】:

date 过滤器的文档解释了为什么会发生这种情况。它期望您提供的值是 Date 对象、日期字符串或以毫秒为单位的数字。

这是他们的描述:

日期格式为日期对象、毫秒(字符串或数字)或各种 ISO 8601 日期时间字符串格式(例如 yyyy-MM-ddTHH:mm:ss.sssZ 及其较短的版本,如 yyyy-MM-ddTHH:mmZ, yyyy-MM-dd 或 yyyyMMddTHHmmssZ)。如果字符串输入中没有指定时区,则时间被认为是本地时区。

您得到 1970 的原因是 b/c date 过滤器将您的年份 2017 解释为自纪元或 unix time 以来的毫秒数。

要使date 过滤器起作用,您只需将您的年份值转换为Date(或使用时刻时的类似方法):

var date = new Date(obj.year, 0,1); // Jan 1

【讨论】:

  • 谢谢,您的建议实际上解决了我的问题。我认为文档不太清楚,首先我认为后端以错误的格式向我传递了数据。
【解决方案2】:

{{obj.year | date : 'yy'}} 输出 70 的原因是因为您将数字 2017 传递给 angular 的 date 过滤器,因此相当于 new Date(2017) 返回日期和时间为 2017 毫秒来自1970-01-01 00:00:00:000,或者更准确地说是1970-01-01 00:00:02:017。因此,当您使用 yy 格式化字符串通过 angular 的 date 过滤器运行它时,您会得到年份的最后两位数字,当然是 70

要提供替代解决方案,您可以使用 Angular 的 limiTo 过滤器:

{{ obj.year | limitTo : 2 : 2 }}

【讨论】:

  • 谢谢你,我喜欢你的解释,我认为它易于理解并且对其他人也有用。
【解决方案3】:

正如其他答案所述,您得到的是70 而不是17,因为角度date 过滤器接受:

日期对象,毫秒(字符串或数字)或各种 ISO 8601 日期时间字符串

所以你的输入被解释为自1 January 1970 00:00:00以来的毫秒数,基本上相当于:

console.log(new Date(2017)); // 1970-01-01T00:00:02.017Z

您的 formatYear 函数使用 moment 具有相同的逻辑,因此它给出了相同的错误结果。如果您使用矩解析指定格式(moment(String, String); 而不是moment(Number);),您的输入将被视为字符串,您将获得正确的输出:

function formatYearBad(year) {
  // uses moment(Number)
  return moment(year).format('YY');
}

function formatYearOk(year) {
  // uses moment(String, String)
  return moment(year, 'YYYY').format('YY');
}

console.log( formatYearBad(2017) ); // 70
console.log( formatYearOk(2017) );  // 17
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>

要在 angularjs 视图中使用正确的时刻逻辑,您必须使用 angular-moment 库。您可以使用amParse 指定输入字符串的格式(在您的情况下为四位数年份),并使用amDateFormat 指定输出格式(在您的情况下为两位数年份)。这是一个工作示例:

angular.module('MyApp',['angularMoment'])
.controller('AppCtrl', function($scope) {
  $scope.obj = {
    year: "2017"
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-moment/1.0.1/angular-moment.min.js"></script>

<div ng-app="MyApp" ng-controller="AppCtrl">
  {{obj.year | amParse:'YYYY' | amDateFormat:'YY'}}
</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-19
    • 2017-12-25
    • 1970-01-01
    • 2017-07-01
    • 2015-09-20
    • 2016-03-29
    相关资源
    最近更新 更多