Angular adds a day when displaying the date (dd/MM/yyyy) - angularjs

I have a datepicker where the user picks the date without choosing the time, the date is saved correctly in my data base but when I display it, it shows one day ahaid, when I looked up the issue it turns out that it's a timezone issue that lots of people face but i didn't quite understand how to fix it in my code :
<tbody>
<tr ng-repeat="ft in ftListesorted">
<td>{{ft.NomProjet}}</td>
<td>{{ft.NomTache}}</td>
<td>{{ft.Datefeuillestemps | date : 'dd/MM/yyyy' }}</td>
</tr>
</tbody>
I get the "ft.Datefeuillestemps" from my database where the default time is always set to T00:00:00.
For example here's how my date is stored in the data base : 2017-05-17 00:00:00.0000000 and this is what I get in my view : 18/05/2017 so a day is added.
How can I solve this issue ?

$scope.passdate = function (dt) {
var targetTime = new Date(dt);
var timeZoneFromDB = -7.00; //time zone value from database
//get the timezone offset from local time in minutes
var tzDifference = timeZoneFromDB * 60 + targetTime.getTimezoneOffset();
//convert the offset to milliseconds, add to targetTime, and make a new Date
var offsetTime = new Date(targetTime.getTime() + tzDifference * 60 * 1000);
$scope.ISODateString(offsetTime);
}
check this if helps

You could subtract (new Date()).getTimezoneOffset() from your object (assuming the date in the database is on GMT), but this is not perfect. You will still have issues when timezones change differently because of daylight saving time.

Related

Converting from time to timestamp in moment js?

I am using ionic time picker in my app and when a time is selected from this plugin it gives the timestamp in callback.
For ex : if time selected is 09:30 AM the timestamp in callback is 34200 and to convert this timestamp to its original value i.e 09:30 AM I am doing this
moment.unix(callback).utc().format('hh:mm A');
now I have to reverse this i.e I have time as 09:30 AM and I want to get timestamp from it as 34200 using moment js.
How can I do that.
The UNIX timestamp 34200 its basically the date 1970-01-01 09:30 AM so to convert it back you need to set the correct date since this information is lost when you format using hh:mm A.
var callback = 34200;
var asHHMM = moment.unix(callback).utc().format('hh:mm A');
var asUNIX = moment.utc(asHHMM, 'hh:mm A').year(1970).month(0).date(1).unix();
console.log(callback, asHHMM, asUNIX);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>

converting date format in angularjs controller

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

Applying AngularJS date filters with condition

I just started with AngularJS and got stuck with a problem.
I have a date field to show in a grid.
Date format should be relative format like "1 day ago, 10 mins ago...."
So for that i used timeAgo, so it formats the date correctly.
But I have a requirement like:
If the last_updated_time is less than 10 days, then show relative time like "1 day ago, 10 mins ago...." else do not apply any filter.
Here is my code snippet.
<td data-title="'Last modified'" sortable="'last_updated_time'" align='center'>
{{offer.last_updated_time | timeAgo }}
</td>
It would be great if someone can guide me how to proceed.
Use a function to get this:
$scope.getTimeAgo = function(last_updated_time ){
var today = new Date();
var days = today.diff(last_updated_time , 'days');
if(days > 10)
return last_updated_time;
else
return moment(last_updated_time).fromNow();
};
then you can use it like follow:
{{getTimeAgo(offer.last_updated_time)}}
PS: I'm using momentjs for time ago but you can apply your time ago function into the else if you want to use your filter.

Order By Date and truncate date strings in Angular

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'}}

Cakephp CakeTime DST handling

I store all dates in UTC in my database. Cakephp runs in UTC and communicates with mysql in UTC. Now i have following scenario:
debug(CakeTime::format('Y-m-d H:i', '2013-03-22 03:00', false,
new DateTimeZone('Europe/Berlin')));
//output is 2013-03-22 04:00
debug(CakeTime::format('Y-m-d H:i', '2013-04-05 03:00', false,
new DateTimeZone('Europe/Berlin')));
//output is 2013-04-05 05:00
As you can see CakeTime added 2 hours of offset in the second example, i guess that is because it considers DST (starting at 31.03.2013).
However what i am trying to do is displaying recurring events in a calendar and this event starts each second Friday at 4am - always, even in summer. Therefore the calendar may not display it to be at 5am!
/EDIT: the first example is corret. the event has to be at 4am. but also in summer
I solved the problem using these two functions for time converting.
Keep in mind that this is for recurring events, that start always at the same time of day(e.g. 4am) regardless of DST.
public function dateTimeToSever($date, $user_timezone) {
$DateTime = new DateTime($date, $user_timezone);
$dst = $DateTime->format('I');
$toServerDateTime = CakeTime::toServer($date, $user_timezone, 'Y-m-d H:i');
if ($dst) {
$toServerDateTime = date('Y-m-d H:i', strtotime($toServerDateTime . ' + 1 Hours'));
}
return $toServerDateTime;
}
public function dateTimeToUser($date, $user_timezone) {
$DateTime = new DateTime($date, new DateTimeZone('UTC'));
$DateTime->setTimezone($user_timezone);
$dst = $DateTime->format('I');
$userDateTime = CakeTime::format('Y-m-d H:i', $date, false, $user_timezone);
if ($dst) {
$userDateTime = date('Y-m-d H:i', strtotime($userDateTime . ' - 1 Hours'));
}
return $userDateTime;
}
This should work for all timezones that use positive DST. AFAIK some timezones, e.g. somewhere in North India, have some kind of negative timezone. I guess in that case the "+ 1 Hours" has to become "- 1 Hours" and vice versa.
In your example you are getting the wrong time in both cases. If you want to store all your dates in UTC then you need to make sure you store the correct UTC values for the timezone the user is in. For example, if you want a reoccurring event every Friday at 3pm in the Europe/Berlin timezone, then do the following.
// save your date like this
$date = new DateTime('2013-04-05 03:00', new DateTimeZone('Europe/Berlin'));
$utc = $date->getTimestamp();
// print them correctly like this
$utc = CakeTime::format('Y-m-d H:i', $utc, false, new DateTimeZone('Europe/Berlin'));
On caveat to this approach, if a user changes their timezone from one with DST to one without (or vice-versa), they may encounter the same problem.

Resources