I'm having trouble getting Moment in Angular to format my time like I would like. I have the date filter working here:
<h4>{{event.date | amDateFormat:'MMMM Do'}}</h4>
But when I try to use this format to print out a time, my time disappears completely out of the browser. This is what I am typing:
<div class="row">
{{event.time | amDateFormat: 'h:mm a'}}
</div>
I am using Firebase if that matters. Also, the input to get the time is the HTML5 input type=time attribute.
When you use type=time for an input, the value is stored as a string which only represents a time, such as "1:00" or "13:00". The amDateFormat filter needs a value that can be interpreted as a date which can be a Date object, a number value for a timestamp, or a properly formatted string date. The time values that you will get using type=time are not valid date strings so amDateFormat can't properly parse the value.
The easiest way to make it work is to just concatenate the value of event.date and event.time before you use the amDateFormat filter:
<div class="row">
{{event.date + ' ' + event.time | amDateFormat: 'h:mm a'}}
</div>
A better solution is to use a function where you pass in the date and time, or just the time and construct something that can be interpreted as a date, or is a date object.
<div class="row">
{{ combine(event.date,event.time) | amDateFormat: 'h:mm a'}}
</div>
simple combine function
$scope.combine = function(date,time) {
if (date && time) {
return date + ' ' + time;
} else {
return "";
}
};
I still think it's kinda hacky to have to add a date to the time like that but it works and you may even end up joining them together anyway in your data model. The best solution I believe would be to just have one event.dateAndTime object that you can use to represent both the date and time -- and you can do this using the type=datetime-local html5 type (at least in Chrome it worked for me).
<dir>Date and time: <input type="datetime-local" ng-model="event.datetime"></dir>
<h4>{{event.datetime | amDateFormat:'MMMM Do'}}</h4>
<div class="row">
event.datetime time: {{ event.datetime | amDateFormat: 'h:mm a'}}
</div>
Here's a working plunker: http://plnkr.co/edit/OERKK9ilxFwUlKLKirtl?p=preview
Related
I've got two calendars in a form. One is a starting date, and the other is the ending date. I'm using the 'ng-pick-datetime' (https://www.npmjs.com/package/ng-pick-datetime) to have a cross-browser calendar picker.
My goal is to block from date 0 (1st Jan 1970) to the date selected in the starting date calendar, in the ending date calendar picker.
So the thing here is to make sure the ending date is after the starting date.
For this, ng-pick-datetime' picker has the [disabledDates] property, which is waiting for an array of Dates that shouldn't be selectable.
What I'm trying is to bind this property to my array of forbidden dates, which is created in a function when the form is created, and also every time the ending date calendar gets focus.
I'm printing my array of forbidden dates to check if it is created correctly and if the dates included in it are between date 0 and the starting date selected. I looks like this part is working fine.
I don't get any browser console error. Just have the ending date calendar picker not blocking any date.
This is my template code:
<div class="input-control col-sm-6" [class.has-error]="startDate.invalid && startDate.dirty">
<label class="control-label" for="startDate">Starting Date *</label>
<owl-date-time
[(ngModel)]="data.startDate"
[dateFormat]="'DD-MM-YYYY'"
[inputId]="'startDate'"
[placeHolder]="'dd-mm-aaaa'"
[type]="'calendar'"
[dataType]="'date'"
[autoClose]="'true'"
id="startDate"
name="startDate"
#startDate="ngModel"
[disabled]="!paramsService.isSolicitante()"
[hideClearButton]
required>
</owl-date-time >
</div>
<div class="input-control col-sm-6" [class.has-error]="endDate.invalid && endDate.dirty">
<label class="control-label" for="endDate">Ending Date *</label>
<owl-date-time
[(ngModel)]="data.endDate"
[dateFormat]="'DD-MM-YYYY'"
[inputId]="'endDate'"
[placeHolder]="'dd-mm-aaaa'"
[type]="'calendar'"
[dataType]="'date'"
[autoClose]="'true'"
id="endDate"
name="endDate"
#endDate="ngModel"
[disabled]="!paramsService.isSolicitante()"
[hideClearButton]="!paramsService.isSolicitante()"
[disabledDates]="'forbiddenDates'"
(onFocus)="getForbiddenEndDates()"
required>
</owl-date-time >
</div>
//printing of selected date values:
<div class="col-sm-6">{{ data.startDate}}</div>
<div class="col-sm-6">{{ data.endDate}}</div>
{{ this.forbiddenDates }} //printing of the dates array to check it
And this is the component code (typescript), just the part that matters here:
forbiddenDates: Date[] = [];
ngAfterViewInit(): void { this.getForbiddenEndDates(); }
// This creates an array of Dates from the beginning of all times to the value of startDate
getForbiddenEndDates(): void {
let dateZero: Date = new Date(0);
let forbiddenDates: Date[] = [];
while (dateZero <= this.data.startDate){
forbiddenDates.push(new Date(dateZero));
dateZero.setDate(dateZero.getDate() + 1);
}
this.forbiddenDates = forbiddenDates;
}
Screenshot of the form and the forbidden dates array printed
I answer myself. It seems that this [disabledDates] template property doesn't change dynamically, so it's just for a fixed array of dates.
The solution is much simpler. Add this template property to the endDate input field:
[min]="data.startDate"
I have a number which represents the time in miliseconds since 1970 eg.
1388664300000
with:
{{ day.date | date: "dd.MM.yyyy" }}
it will render 07.05.2015 ! So far so good. Now I like to insert the same data into my input field:
<input type="date" ng-model="day.DUTY">
to let the user adjust the date.
Nothing is displayed because the input field requires an date object !
I have created a filter to change my number to date:
var DateFilter = function() {
return function(data){
date = new Date(data);
return date;
}
}
But I can't figure it out how to combine this with my input field. Maybe this isn't the right approach ? Any ideas ?
Take a look at How to bind View Date to model milliseconds with Angularjs.
As it explained; You can use the following, to change the data format dynamically during the binding:
ngModel.$parsers.push(fromUser);
ngModel.$formatters.push(toUser);
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
Actual Date coming from JSON
Need to format it as below .
Effective Date : 2010-08-31 (trim the time stamp)
End Date : 2010-08-31 (trim the time stamp)
Am using the below code for Formatting the date inside Ng-Repeat.
<li ng-repeat="product in data | startFrom:currentPage*pageSize | limitTo:pageSize"
ng-click="getAttributes(product)">
{{product.prod_start_date| date:'MM/dd/yyyy'}}
{{product.prod_end_date| date:'MM/dd/yyyy'}}
</li>
But it doesnt work still displays the same.
Should the Date be passed as new Date as shown in the below jsfiddle Example
http://jsfiddle.net/southerd/xG2t8/
Note sure how to do that inside ng-repeat.?? Kindly help me on this. Thanks in Advance
I created my own filter to address this.
The date filter cant take a string, needs a date object.
.filter('cmdate', [
'$filter', function($filter) {
return function(input, format) {
return $filter('date')(new Date(input), format);
};
}
]);
then you can do:
{{product.prod_start_date| cmdate:'MM/dd/yyyy'}}
I use moment.js for my UI date time handling (there even a nice angular-moment bower package as well)
http://momentjs.com
https://github.com/urish/angular-moment
usage:
<span>{{product.prod_start_date | amDateFormat:'MM/dd/yyyy'}}</span>
It has a bunch of other options as well with relative dates etc.
I have updated the controller that you showed in the fiddle and here is your updated filter
Here I made use of the $filter('date') which is a feature of Angular itself in order to format the date in the desired format.
Here is the controller:
function Scoper($scope,$filter) {
$scope.s = "2012-10-16T17:57:28.556094Z";
var dateObj = new Date($scope.s);
$scope.dateToShow = $filter('date')(dateObj,'yyyy-MM-dd');
console.log($scope.dateToShow);
}
I have a json file with a released field that comes back with such format:
released: "2002-01-28"
I intend to display them sorted by date (earlier first) and only showing the year. I've used the truncate module (in my example, release: 4) and so far its showing only the first 4 characters, but I haven't succeed using orderby to sort it correctly.
Any pointers?
Also, in some items the released field comes back empty, any quick way to display just a "unknown" instead of a blank space?
Thanks!
<li ng-show="versions" ng-repeat="version in versions | filter: '!file' | orderBy: version.released">
{{version.released | release:4}} - {{version.format}} - {{version.label}}
</li>
Here is a date formatting filter I use. It takes a date and converts it into whatever format you wish, in your case, 'yyyy'. Bind the raw date stamp in your template and then 'orderBy' should work fine. This is how I always do it. Oh, you might not want the replace() function... that was specific to my last project.
.filter('DateFormat', function($filter){
return function(text){
if(text !== undefined){
var tempdate = new Date(text.replace(/-/g,"/"));
return $filter('date')(tempdate, "MMM. dd, yyyy");
}
}
})
You can show unknown by doing {{version.released || 'unknown'}}.
If you only want to show the year do this {{ (version.released | date : date : 'YYYY' ) || 'unknown'}}