Using AngularJS date filter with UTC date
Asked Answered
B

10

74

I have an UTC date in milliseconds which I am passing to Angular's date filter for human formatting.

{{someDate | date:'d MMMM yyyy'}}

Awesome, except someDate is in UTC and the date filter considers it to be in local time.

How can I tell Angular that someDate is UTC?

Thank you.

Berrie answered 18/12, 2013 at 15:31 Comment(5)
date filter converts it to local time automatically.Cunha
It doesn't know that the date is UTC so the conversion is wrong.Berrie
@see #20470639Tailband
Possible duplicate of Angular: date filter adds timezone, how to output UTC?Justus
{{someDate | date:'d MMMM yyyy' : 'UTC'}}Letha
A
56

Similar Question here

I'll repost my response and propose a merge:

Output UTC seems to be the subject of some confusion -- people seem to gravitate toward moment.js.

Borrowing from this answer, you could do something like this (i.e. use a convert function that creates the date with the UTC constructor) without moment.js:

controller

var app1 = angular.module('app1',[]);

app1.controller('ctrl',['$scope',function($scope){

  var toUTCDate = function(date){
    var _utc = new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(),  date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
    return _utc;
  };

  var millisToUTCDate = function(millis){
    return toUTCDate(new Date(millis));
  };

    $scope.toUTCDate = toUTCDate;
    $scope.millisToUTCDate = millisToUTCDate;

  }]);

template

<html ng-app="app1">

  <head>
    <script data-require="angular.js@*" data-semver="1.2.12" src="http://code.angularjs.org/1.2.12/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body>
    <div ng-controller="ctrl">
      <div>
      utc {{millisToUTCDate(1400167800) | date:'dd-M-yyyy H:mm'}}
      </div>
      <div>
      local {{1400167800 | date:'dd-M-yyyy H:mm'}}
      </div>
    </div>
  </body>

</html>

here's plunker to play with it

See also this and this.

Also note that with this method, if you use the 'Z' from Angular's date filter, it seems it will still print your local timezone offset.

Ashtray answered 14/2, 2014 at 17:19 Comment(0)
D
114

Seems like AngularJS folks are working on it in version 1.3.0. All you need to do is adding : 'UTC' after the format string. Something like:

{{someDate | date:'d MMMM yyyy' : 'UTC'}}

As you can see in the docs, you can also play with it here: Plunker example

BTW, I think there is a bug with the Z parameter, since it still show local timezone even with 'UTC'.

Doug answered 21/9, 2014 at 19:25 Comment(6)
I think what the PO wants is to format a UTC date to a local format string, just the opposite.Suh
Sadly this additional timezone parameter is not supported in Angular 2's Date pipe. Doing something like what is suggested in the first answer will still work in Angular 2.Cosecant
Hi @Doug This works for me. question: any way I can get the Month names in Spanish instaed of English as it gives in above. so instaed of the month names like January, February, March...etc I need to make those as: enero, febrero, marzo? Any pointers would help.Anesthetize
If you want to convert value 1506508005197 to 09-27-2010 then use above suggested method by nir {{record.deactivateDate | date:'MM-dd-yyyy' : 'UTC'}}Parotitis
Whatever or not it answers the question, this is what I was looking for and works perfectly. But maybe for others: If you want to have it the other way around you just have to make sure your back-end is sending it as 2018-07-17T21:26:00.000+00:00. Angular then knows it is an UTC time and will convert it correctly to local time by default.Wickliffe
{{ data.publishedDate | date: 'mediumDate':'UTC' }}Emancipation
A
56

Similar Question here

I'll repost my response and propose a merge:

Output UTC seems to be the subject of some confusion -- people seem to gravitate toward moment.js.

Borrowing from this answer, you could do something like this (i.e. use a convert function that creates the date with the UTC constructor) without moment.js:

controller

var app1 = angular.module('app1',[]);

app1.controller('ctrl',['$scope',function($scope){

  var toUTCDate = function(date){
    var _utc = new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(),  date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
    return _utc;
  };

  var millisToUTCDate = function(millis){
    return toUTCDate(new Date(millis));
  };

    $scope.toUTCDate = toUTCDate;
    $scope.millisToUTCDate = millisToUTCDate;

  }]);

template

<html ng-app="app1">

  <head>
    <script data-require="angular.js@*" data-semver="1.2.12" src="http://code.angularjs.org/1.2.12/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body>
    <div ng-controller="ctrl">
      <div>
      utc {{millisToUTCDate(1400167800) | date:'dd-M-yyyy H:mm'}}
      </div>
      <div>
      local {{1400167800 | date:'dd-M-yyyy H:mm'}}
      </div>
    </div>
  </body>

</html>

here's plunker to play with it

See also this and this.

Also note that with this method, if you use the 'Z' from Angular's date filter, it seems it will still print your local timezone offset.

Ashtray answered 14/2, 2014 at 17:19 Comment(0)
A
11

Here is a filter that will take a date string OR javascript Date() object. It uses Moment.js and can apply any Moment.js transform function, such as the popular 'fromNow'

angular.module('myModule').filter('moment', function () {
  return function (input, momentFn /*, param1, param2, ...param n */) {
    var args = Array.prototype.slice.call(arguments, 2),
        momentObj = moment(input);
    return momentObj[momentFn].apply(momentObj, args);
  };
});

So...

{{ anyDateObjectOrString | moment: 'format': 'MMM DD, YYYY' }}

would display Nov 11, 2014

{{ anyDateObjectOrString | moment: 'fromNow' }}

would display 10 minutes ago

If you need to call multiple moment functions, you can chain them. This converts to UTC and then formats...

{{ someDate | moment: 'utc' | moment: 'format': 'MMM DD, YYYY' }}
Amyotonia answered 12/11, 2014 at 23:12 Comment(0)
T
4

There is a bug filed against this in angular.js repo https://github.com/angular/angular.js/issues/6546#issuecomment-36721868

Tradespeople answered 9/5, 2014 at 19:21 Comment(0)
M
4

An evolved version of ossek solution

Custom filter is more appropriate, then you can use it anywhere in the project

js file

var myApp = angular.module('myApp',[]);

myApp.filter('utcdate', ['$filter','$locale', function($filter, $locale){

    return function (input, format) {
        if (!angular.isDefined(format)) {
            format = $locale['DATETIME_FORMATS']['medium'];
        }

        var date = new Date(input);
        var d = new Date()
        var _utc = new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(),  date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
        return $filter('date')(_utc, format)
    };

 }]);

in template

<p>This will convert UTC time to local time<p>
<span>{{dateTimeInUTC | utcdate :'MMM d, y h:mm:ss a'}}</span>
Make answered 13/8, 2015 at 20:14 Comment(4)
this is actually wrong because it no longer uses date's UTC functions - contrary to ossek's script. it would work though, if the date in input included the string " UTC" at the end.Guru
Thanks for pointing out. It seems original answer has been updated after my reply :) I just wrapped his function in to a filter.Make
while we are at it: might i suggest using $locale['DATETIME_FORMATS']['medium'] instead of the fixed fallback format? that way you use angular's own localization. Your format looks awfully like the en_US format, that is very uncommon everywhere else in the worldGuru
done! :). Template section leaved intact to show that can use to override the default formatting.Make
B
3

If you do use moment.js you would use the moment().utc() function to convert a moment object to UTC. You can also handle a nice format inside the controller instead of the view by using the moment().format() function. For example:

moment(myDate).utc().format('MM/DD/YYYY')
Batruk answered 2/9, 2014 at 1:20 Comment(1)
He doesn't want converting it to UTC, since it is already in UTC time. You should use it like this: moment().utc(myDate).format('MM/DD/YYYY')Doug
B
2

After some research I was able to find a good solution for converting UTC to local time, have a a look at the fiddle. Hope it help

https://jsfiddle.net/way2ajay19/2kramzng/20/

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app ng-controller="MyCtrl">
  {{date | date:'yyyy-mm-dd hh:mm:ss' }}
</div>


<script>
function MyCtrl($scope) {
 $scope.d = "2017-07-21 19:47:00";
  $scope.d = $scope.d.replace(" ", 'T') + 'Z';
  $scope.date = new Date($scope.d);
}
</script>
Bloch answered 24/7, 2017 at 19:27 Comment(0)
S
1

You have also the possibility to write a custom filter for your date, that display it in UTC format. Note that I used toUTCString().

var app = angular.module('myApp', []);

app.controller('dateCtrl', function($scope) {
    $scope.today = new Date();
});
    
app.filter('utcDate', function() {
    return function(input) {
       return input.toUTCString();
    };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>  
  
<div ng-app="myApp" ng-controller="dateCtrl">      
    Today is {{today | utcDate}}       
</div>
Scotty answered 27/4, 2017 at 11:48 Comment(0)
J
0

Could it work declaring the filter the following way?

   app.filter('dateUTC', function ($filter) {

       return function (input, format) {
           if (!angular.isDefined(format)) {
               format = 'dd/MM/yyyy';
           }

           var date = new Date(input);

           return $filter('date')(date.toISOString().slice(0, 23), format);

       };
    });
Jiujitsu answered 22/3, 2016 at 11:1 Comment(0)
M
-2

If you are working in .Net then adding following in web.config inside

<system.web>

will solve your issue:

<globalization culture="auto:en-US" uiCulture="auto:en-US" />
Macknair answered 28/1, 2019 at 19:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.