flight.departure_at is a UTC format 2016-05-04T19:00:00.000Z
When I display this expression in the page,
It's format is totally out of expectation.
Why does the 12:00 come out? How come?
I also want to know how could I keep all the time format in UTC globally without adding options everywhere. It will make the whole App vulnerable
code
Departure_time: {{flight.departure_at}} ||| {{flight.departure_at | date: 'HH:mm'}}
output
Departure_time: 2016-05-04T19:00:00.000Z ||| 12:00
This standard is called ISO-8601 and the format is: YYYY-MM-DDTHH:mm:ss.sssZ
'T' is just a separator between date and time in ISO-8601 format.
'Z' is zero time zone ( your getting 12:00 , because it convert to your timezone)
we can use parse like this ,
var date = new Date('2016-05-04T19:00:00.000Z');
console.log(date.getUTCHours()); // Hours - 19
console.log(date.getUTCMinutes()); //0
console.log(date.getUTCSeconds());// 0
console.log(Date.parse(date));
console.log(new Date(Date.parse(date)));
OR
Date.parse(DATE) for getting time in standard time format
UTC
As stated in a different thread about personalizing timezones to the user - I've found this to be very helpful when coming to dealing with timezones in Angular. (https://stackoverflow.com/a/35161107/3585278)
module.config(['$provide', function($provide) {
var DEFAULT_TIMEZONE = 'GMT';
$provide.decorator('dateFilter', ['$delegate', '$injector', function($delegate, $injector) {
var oldDelegate = $delegate;
var standardDateFilterInterceptor = function(date, format, timezone) {
if(angular.isUndefined(timezone)) {
timezone = DEFAULT_TIMEZONE;
}
return oldDelegate.apply(this, [date, format, timezone]);
};
return standardDateFilterInterceptor;
}]);
}]);
I suggest you use Angular moment for all date time related stuff for the frontend and moment for the controller part.
You should store all time as UTC in backend and then on frontend you can set user's timezone globally as
app.constant('angularMomentConfig', {
'timezone' : <user's timezone>
});
Render UTC time now on frontend without worrying about timezone(make sure all variables are either moment or Date object):
<td ng-bind="flight.departure_at| amDateFormat:'HH:mm'"></td>
Related
angular-pickadate works for my local time. To check global Times, I have changed my time zone to "America/Denver". Now selected date is taken one day before today's date (passed modal date), so it applies "pickadate-active" class to yesterday.
I tried passing modal date with local timezone and also with UTC timezone. I don't know why dateHelper.parseDate calls again with stripping Timezone value earlier passed, now my understanding is $locale is converting stripped date assuming it a UTC date to local date. Hence, being GMT-06:00, selected date comes to one date before.
HTML DIV - <div pickadate ng-model="vm.date" ng-model-options="{ debounce: 0 }" header="true" select="true" date-highlight-list="vm.dateList" ></div>
Controller - vm.date = moment().tz(timeZoneName).format();
can someone suggest a way to handle different timezones with angular-pickadate?? Thanks !
GIT directive URL - https://github.com/restorando/angular-pickadate
The parseDate function was giving date object as per GMT timezone, so date was becoming one day less.So I removed this condition which was directly returning GMT date for passed date strings with timezone.
if (angular.isDate(dateString) || angular.isDate(new Date(dateString))) {
new Date(dateString); }
Now it goes to next if block to format date with regex and added this condition there to handle date strings and date objects -
if(typeof dateString == 'object') {
dateString = (dateString['_d'])? dateString['_d']: dateString['_i']; // being private (_d, _i) should be avoided but only way in mine case
if(typeof dateString == 'object') // returns Object by dateString['_d'] else string
dateString = dateString.getDate() +'-'+ dateString.getMonth() +'-' +dateString.getFullYear();
}
dateParts = dateString.split(separator); // separator was "-" every time so making dateString with "-" in case it was object
i write the following coding to print the current date time
$scope.date = new Date();
and then i print the same using consol.log
console.log($scope.date);
and it is working fine
Tue Jan 24 2017 16:36:06 GMT+0530 (India Standard Time)
but now i want to change the date format and i want to print like
21-12-2016
can anybody help me here?
i used the conversion but i am unable to remember the page or the url of the page right now,
and stuck on this,
before i leave for the home today i thought of solving this issue
In controller you can do
$filter('date')(date, format, timezone)
to change the date format. And in html,
{{ date_expression | date : format : timezone}}
use this.
Like
$scope.formattedDate = $filter('date')($scope.currDate, "dd-MM-yyyy");
to print same on html
{{ currDate | date : "dd-MM-yyyy"}}
https://docs.angularjs.org/api/ng/filter/date
Following formats are supported by angular.
You can do this either in controller or in html page.
$scope.date = new Date();
The first one is :
$scope.date = $filter('date')($scope.date, 'dd-MM-yyyy');
Second one is :
{{date | date:'dd-MM-yyyy'}}
You can use the Angular date filter:
{{date | date: 'dd-MM-yyyy'}}
You can use the in-build js libraries functions i.e getDay(), getHours(), getMinutes(), getMilliseconds(). This functions will return you the corresponding date's individual components values.
e.g
var x = $scope.yourDateModelObj.getHours();
Likewise, you can get the date, month, years values.
return an integer value for hours.
Hope that helps
I have a number of .net webApi actions returning dates that are deserialised into JSON. My angular application then consumes these date strings for display\edit or as the ngModel in a variety of date directives. Many of these directives require a javascript date object and not a string representation of a date. How do serialise the date string back to javascript date for all returned webapi data?
N.B. I have tried a variety of regExs that proport to be ISO 8601 compliant, but for every one I use there are a bunch of use cases that fail. The cases I require are as follows:
should not convert non dates (string) e.g. 'http://blah/'
should not convert non dates (integer) e.g. 2015
should not convert bad dates e.g. '2009-05-19T14a39r'
should not convert partial bad date from string to date e.g. '1'
should not convert a string that looks like a year e.g. '2015'
should convert date from string to date e.g. '2015-09-09'
should convert date with time from string to date with time e.g. '2009-05-19T14:39'
should convert date with time from string to date with time including seconds e.g. '2009-05-19T14:39:23'
should convert date with time to the millisecond from string to date with time with milliseconds e.g. '2016-06-09T13:02:39.957'
should convert date with time from string to date with time in UTC e.g. '2009-05-19T14:39Z'
should not convert a date which is part of a longer string e.g. 'Should not convert 2015-12-12T00:00:00Z as this is part of a longer string'
So, firstly in order to intercept and convert all string dates to javascript dates we need angular to do the interception and replacing. For this we can use an interceptor on the httpProvider to ensure our code runs on all returned http responses before any other code is executed.
var app = angular.module('app');
app.config(configureProviders);
configureProviders.$inject = ['$httpProvider'];
function configureProviders($httpProvider) {
configureHttp($httpProvider);
}
function configureHttp(httpProvider) {
// add all http interceptors
httpProvider.interceptors.push('dateDeserialiserInterceptor');
}
ok so now we have our interceptor registered, but we need some code to make it work:
(function () {
var module = angular.module('myApp.interceptors');
module.factory('dateDeserialiserInterceptor', function () {
function convertDateStringsToDates(input) {
// Ignore things that aren't objects.
if (typeof input !== "object") return input;
for (var key in input) {
if (!input.hasOwnProperty(key)) continue;
var value = input[key];
// Check for string properties which look like dates.
if (typeof value === "string" && (moment(value, moment.ISO_8601).isValid())) {
input[key] = moment(value, moment.ISO_8601).toDate();
} else if (typeof value === "object") {
// Recurse into object
convertDateStringsToDates(value);
}
}
};
return {
response: function (response) {
convertDateStringsToDates(response);
return response;
}
};
});
})();
So the above code was originally taken off the internet somewhere and had a manual regEx comparison. The regEx was described as ISO 8601 compliant, but I found a multitude of examples where it wasn't. This now relies on an Open Source library momentJs to determine if the date is ISO 8601 compliant and to do the conversion. If the date isn't compliant the string value is simply returned. ISO 8601 is a great standard to use (as it covers a multitude of cases) and is much better than hard coding any expected particular format which may lead you down a path of 'oh...it's missed one'.
At the moment this is parsing all returned response object values for potential dates. I thought about improving this by explicitly marking the request with the response properties that we expect to be dates. That way we wouldn't have to try\parse everything (which is slow) and also run the risk that something we don't want to convert gets converted. However that approach is a little messy and would litter many requests. I like this approach for now and it seems to work. Happy for it to be improved!
Here is an Angular 2+ solution. This assumes the date from the API is in ISO format:
In your Component:
// call to your data service
this.dataService.getSomeData().map(records => {
records.map(record => {
//call to shared service date conversion function
this.dataService.covertISOFieldstoDateObjects(record);
});
return records;
}).subscribe(x => {
// processed records will now have date objects for any date properties
this.records = x;
}, error => {
...
});
In your Service:
covertISOFieldstoDateObjects(currentObj) {
const entries = Object.entries(currentObj);
for (const [key, value] of entries) {
const isDate = moment(value, moment.ISO_8601).isValid();
if (isDate) {
currentObj[key] = moment(value as string, 'YYYY-MM-DD HH:mm'); // Use this to get UTC and ignore timezone (good when you need just the date)
currentObj[key] = moment(value as string, 'YYYY-MM-DD HH:mmZ'); // Use this to include timezone adjustment
}
}
return currentObj;
}
I have a web page calling some PHP api and rendering results.
PHP queries a MySQL database and returns JSON objects that are deserialized and formatted using AngularJS directives and filters.
Problem rises as MySql dates are not directly supported by AngularJS date filter.
So I wrote this
angular.module(...)
.filter('mysqlDateToISO', function() {
return function(input) {
input = new Date(input).toISOString();
return input;
};
});
and HTML part looks like
<p>
Pubblicato il
{{arg.pubblicato_il | mysqlDateToISO
| date:"dd MMM yyyy 'alle ore' HH:mm:ss"}}
</p>
Chrome renders results properly:
Pubblicato il 25 Mar 2015 alle ore 16:01:00
Firefox instead does not:
Pubblicato il {{arg.pubblicato_il | mysqlDateToISO | date:"dd MMM yyyy
'alle ore' HH:mm:ss"}}
Firefox console shows this error
RangeError: invalid date
The error is raised from input = new Date(input).toISOString()
How can I fix it?
You could use an alternative way to parse date string, such as Moment : http://momentjs.com/ by specifying the mysql date string format, then providing the output format.
Here is an example :
moment("20111031", "YYYYMMDD").format("dd MMM YYYY [alle ore] HH:mm:ss")
Replace 20111031 with the mysql date serialization and YYYMMDD by the mysql date format.
Using moment will help to be more agnostic to browser Date implementation
More complete example :
angular.module(...)
.filter('mysqlDateToISO', function() {
return function(input) {
var result = moment(input, "YYYY-MM-DD HH:mm:ss")
.format("DD MMMM YYYY [alle ore] HH:mm:ss");
return result;
};
});
As a response from the json I am getting the UTC timezone. I need to convert it to local time.
<span class="text-muted">{{trans.txnDate}}</span>
Can anyone help on this?
I just had to solve this problem as well with dates coming from .NET Web API in the format 'yyyy-MM-ddTHH:mm:ss' (e.g. 2016-02-23T00:11:31) without the 'Z' suffix to indicate UTC time.
I created this filter that extends the angular date filter and ensures that the timezone suffix is included for UTC time.
UTC to Local Filter:
(function () {
'use strict';
angular
.module('app')
.filter('utcToLocal', utcToLocal);
function utcToLocal($filter) {
return function (utcDateString, format) {
if (!utcDateString) {
return;
}
// append 'Z' to the date string to indicate UTC time if the timezone isn't already specified
if (utcDateString.indexOf('Z') === -1 && utcDateString.indexOf('+') === -1) {
utcDateString += 'Z';
}
return $filter('date')(utcDateString, format);
};
}
})();
Example Usage:
{{product.CreatedDate | utcToLocal:"dd.MM.yyyy"}}
EDIT (2nd Jan 2017): Please refer #Jason's answer, it is better than this one since it uses custom filter to fix the date format - that's the more Angular way of doing it.
My original answer and edits:
You could use the date filter to format the date:
<span class="text-muted">{{trans.txnDate | date:'yyyy-MM-dd HH:mm:ss Z' }}</span>
This will output:
2010-10-29 09:10:23 +0530
(assuming trans.txnDate = 1288323623006;)
See this documentation of date in angularjs.org. It has quite a few examples that are very helpful!
EDIT:
In response to your comment, use the following to get the date as 17 oct 2014:
<span class="text-muted">{{trans.txnDate | date:'dd MMM yyyy' | lowercase }}</span>
Check the documentation link that I mentioned above.
EDIT2:
In response to your other comment, use the following code. The problem is that the string that you are getting is not properly formatted so the Date object is not able to recognise it. I have formatted it in the controller and then passed to the view.
function MyCtrl($scope) {
var dateString = "2014:10:17T18:30:00Z";
dateString = dateString.replace(/:/, '-'); // replaces first ":" character
dateString = dateString.replace(/:/, '-'); // replaces second ":" character
$scope.date = new Date(dateString);
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app ng-controller="MyCtrl">
{{date | date:'dd MMM yyyy' | lowercase }}
</div>
The JS code for replacement can be improved by finding a smarter way to replace the first 2 occurrences of : character.
I had the same issue. AngularJs's date filter doesn't figure out the string is UTC format, but JavaScript Date object does. So I created a simple function in the Controller:
$scope.dateOf = function(utcDateStr) {
return new Date(utcDateStr);
}
And then used something like:
{{ dateOf(trans.txnDate) | date: 'yyyy-MM-dd HH:mm:ss Z' }}
It displays the date/time in the local timezone
I had the same issue. Below Answer
{{trans.txnDate | date:'yyyy-MM-dd HH:mm:ss Z':'+0530' }}
//You can also set '+0000' or another UTX timezome