Translate a native JS to Angularjs to calculate days between two dates? - javascript

I am having trouble trying to convert or translate a native js script to calculate number of days between two dates from two scopes ('work_start' and 'work_end') but did not have any success.
Here is the code, actually it works, but an alert is fired in the console.log and I am not achieving to solve this.
$scope.$watchGroup(['work_start', 'work_end'], function() {
var date1 = $scope.work_start;
var date2 = $scope.work_end;
// First we split the values to arrays date1[0] is the year, [1] the month and [2] the day
date1 = date1.split('-');
date2 = date2.split('-');
// Now we convert the array to a Date object, which has several helpful methods
date1 = new Date(date1[0], date1[1], date1[2]);
date2 = new Date(date2[0], date2[1], date2[2]);
// We use the getTime() method and get the unixtime (in milliseconds, but we want seconds, therefore we divide it through 1000)
date1_unixtime = parseInt(date1.getTime() / 1000);
date2_unixtime = parseInt(date2.getTime() / 1000);
// This is the calculated difference in seconds
var timeDifference = date2_unixtime - date1_unixtime;
// in Hours
var timeDifferenceInHours = timeDifference / 60 / 60;
// and finaly, in days :)
var timeDifferenceInDays = timeDifferenceInHours / 24;
// alert(timeDifferenceInDays);
$scope.total_days = timeDifferenceInDays;
});
And this is the alert I am receiving:
angular.js:13283 TypeError: Cannot read property 'split' of null
at app.js:3997
at c (angular.js:16419)
at m.$eval (angular.js:16884)
at m.$digest (angular.js:16700)
at m.$apply (angular.js:16992)
at g (angular.js:11313)
at y (angular.js:11511)
at XMLHttpRequest.t.onload (angular.js:11452)(anonymous function) # angular.js:13283(anonymous function) # angular.js:9996m.$digest # angular.js:16702m.$apply # angular.js:16992g # angular.js:11313y # angular.js:11511t.onload # angular.js:11452
I changed some things but this is the far I can get. Any help will be welcome

Cannot read property 'split' of null
This means you're trying to use the split function on something that is not a String. So where are you using the split function?
date1 = date1.split('-');
date2 = date2.split('-');
So where are date1/2 defined?
var date1 = $scope.work_start;
var date2 = $scope.work_end;
So where are $scope.work_start/end defined? Not sure, but probably in html. To simply fix this issue, do something like this:
if(date1 === null || date2 === null){
alert("no dates given")
} else {
date1 = date1.split('-');
date2 = date2.split('-');
... // rest of your code
}
Updating this section based on the discussion below...
Dates can be a pain in JS. A newly initialized date object is simply the number of milliseconds since January 1st, 1970 (UTC). If you're going to play with dates and times, look into a js library that makes Dates easier to work with like Moment or Sugar.
$watchGroup watches those two dates and runs the 'days between' functionality if either changes. This is fine, however you must compensate for a range of issues, such as
the user changes work_start before work_end, and work_start is after work_end
the user enters a date that is not in the correct format
and a bunch of other stuff that can come up. You might want to think about incorporating a button to allow the user to update the dates after they're finished editing both. This will also allow your form to error-check the input, and not allow a submission if it's not in the correct format.
HTML
<div ng-controller="workCont">
<input ng-model="$scope.work_start"></input>
<input ng-model="$scope.work_end"></input>
<button ng-click="$scope.getDaysBetween()">Get Days Between</button>
<p>Days Between: {{$scope.daysBetween}}</p>
</div>
JS
var workApp = angular.module('workApp', []);
workApp.controller('workCont', function workCont($scope) {
$scope.work_start = new Date();
$scope.work_end = new Date();
$scope.daysBetween = 0;
$scope.getDaysBetween = function(){
var date1 = $scope.work_start
var date2 = $scope.work_end
var timeDiff = Math.abs(date2.getTime() - date1.getTime());
var diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24));
$scope.daysBetween = diffDays
}
});
Thanks to "Get difference between 2 dates in javascript?" for the getDaysBetween logic.

Related

How to make countdown where it looks to the future, so when my date in the year is passed it should look to the next year

I'm making a countdown but right now it only gives a response if the date hasn't passed yet. But I want that if the date is passed already that it goes to the next year.
How could I do that? I guess I need to use an "if" at my const with the date but I have no idea how to do that.
const difference = +new Date(`01/01/${year}`) - +new Date();
Hello Simon, first of all, I want to tell you (as a tip) that you don't need to convert dates to calculate the difference between them. That being said, I recommend you use date-fns for date calculations, with this library you will be able to use methods like endOfDay(date). If you still don't want to use any external library, you can use setHours method:
const now = new Date()
const endOfDay = new Date(new Date(now.toString()).setHours(23, 59, 59, 999))
const isBeforeEndOfDay = now <= endOfDay
console.log(isBeforeEndOfDay)
And to get the difference between the two dates you don't need to calculate if its the end of the day:
// To set two dates to two variables
const date1 = new Date("06/30/2019");
const date2 = new Date("07/30/2019");
// To calculate the time difference of two dates
const Difference_In_Time = date2.getTime() - date1.getTime();
// To calculate the no. of minutes between two dates
const Difference_In_Days = Difference_In_Time / (1000 * 3600 * 24);
const Difference_In_Hours = Difference_In_Days * 24
console.log(Difference_In_Days, Difference_In_Hours)
// [...]

JavaScript - check if input date is within add 7 days from current yyyy/mm/dd date, NOT js date()

I have a form submit with 2 date inputs: share_start and share_end in yyyy-mm-dd format. I use JS to validate the input and want to check whether share_end date is within 7 days from the share_start date.
Now, the tricky bit is that I don't have a JS date() dates/timestamps, but only those input dates, but when trying to add on 7 days to the input in JS all I end up with an error since JS needs to operate with date(). I cannot use any external scripts like moment.js to help with this.
Does JS have some sort of in-built function like PHPs strtotime where I can just add + 7 days or something?
Thank you
// Form Submit Validation
function validateForm() {
var share_start = '2021-05-07';
var share_end = '2021-05-15';
var share_max = share_start.setDate(date.getDate() + 6);
if (share_end > share_max) {
alert("Share End Date cannot be more than 7 days from now");
return false;
}
}
At last figured it out.... Bloody JS date conversion is really a pain without libraries such moments.js
var date1 = '2021-01-01';
var date2 = '2021-01-08';
var diffTime = Math.abs(date2 - date1);
var diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
if (diffDays > 6) {
alert("Share cannot be longer than 6 days");
return false;
}
In my particular case, I am getting the date values from a variable, which I then calculate the difference in seconds, after which I convert those seconds to days. Followed by a simple if statement where I check if the value is greater than x days, and I am good to go.

convert (date and timestamp from postgresql) to javascript time

I have two columns in the PostgreSQL table(start_date(in date format) and cancellation_date(in timestamp format)). One is in date format and another is in timestamp format. I want to get the difference between two values in the number of days. I am sending the data in javascript.
How to calculate the difference in days in javascript? for example, one value is 2010-10-14. the second value is 2010-10-16 04:05:06. the difference will be 3 days.
My problem is that I get these two values in API response as PostgreSQL(date and timestamp) format. And a simple difference is not working(start_date-cancellation_date) in javascript.
Javascript date objects can't be compared until they're converted to milliseconds.
var now = new Date(); // create new date - today
var then = new Date(now.getDate()+5); // create new date that's now + 5 days (bad variable name, sry)
var nowAdj = now.getTime(); // now adjusted to milliseconds
var thenAdj = then.getTime(); // then adjusted to milliseconds
var differenceInDays = Math.round((thenAdj - nowAdj)/(1000*60*60*24)) // Subtract now from then and multiply the results by the magic formula to return milliseconds to days.
Edit: Cleaned up a bit, "then" is still a terrible variable name ;)
You can convert the dates into new date objects and calculate the difference as follows:
var date1 = new Date("2010-10-14");
var date2 = new Date("2010-10-16 04:05:06");
var timeDiff = Math.abs(date2.getTime() - date1.getTime());
var diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24));
console.log(diffDays);

Add minutes to current time, JavaScript [duplicate]

This question already has answers here:
How to add 30 minutes to a JavaScript Date object?
(29 answers)
Closed 3 years ago.
I would like to add 20 minutes to the current date. While browsing the messages already posted on this subject, I recovered a piece of code but I can not adapt it. Can you help me ?
// get the current date & time
var dateObj = Date.now();
// I do not understand what these values ​​are
dateObj += 1000 * 60 * 60 * 24 * 3;
// create a new Date object, using the adjusted time
dateObj = new Date(dateObj);
Create a prototype function on Date Object if you want to use it in various places as it will reduce redundancy of code.
Date.prototype.add20minutes = function(){
return this.setMinutes(this.getMinutes() + 20);
}
Now, you can simply call
var d = new Date();
d.add20minutes();
Use this piece of code
var date = new Date();
date.setMinutes(date.getMinutes()+20);
Don't know if setMinutes with values > 60 is defined or it works by accident. You can do it this way:
var current_ms = new Date().getTime();
var in20min = new Date(current_ms + (1000*60*20))
JavaScript Date object has a method called setMinutes
let d = new Date()
d.setMinutes(d.getMinutes() + 20)
In javascript when working with dates I like to use moment:
https://momentjs.com/
So you can do this:
moment().add(20, 'minutes');
Use this code:
var date = new Date();
var min = parseInt(date.getMinutes()+20);
date.setMinutes(min);

Am I writing this wrong or is this a bug on Date.js (date ninja)

I am trying to use datejs (date ninja or whathaveyou..) and I am getting odd results.
Here's what I output to console to test.
var d1 = Date.today();
var d2 = Date.parse(work.tax_credit_start);
var span2 = new TimeSpan(d2 - d1);
console.log('result of timespan test = ' + span2.getDays() + 'days between now and ' + Date.parse(work.tax_credit_start).toString('dd-mm-yyyy') + ' - ' + work.tax_credit_start );
I am expecting about -584 days according to date calculations in excel and other online services.
Here's what I got:
result of timespan test = -462days between now and 30-00-2010 - 30-06-2010
I have got a localisation file for datejs for New Zealand style dates too, so I am not expecting that to be an issue. Though it appears to be the issue. Also if I parse a date and then render it as a string in the same format that it was in before being parsed it should not change yeah?
Long day, maybe I just need a break.
Your thoughts/help internets?
Firstly, 30-00-2010 will be resolved as Wed Dec 30 2009 00:00:00. Is that what you really want?
Secondly, the difference in days between 30-00-2010 and 30-06-2010 is only a couple of days more than 6 months, how do you get -584 days? I get -182.
Anyway, it's not a difficult calculation. Create two date objects for the required dates, set their time to noon (so as to remove daylight saving issues across dates), subtract one from the other, divide the result by the number of milliseconds in a day (24 * 60 * 60 * 1000) and round to the nearest integer.
Here's a some quick functions to do the job:
// Iput as d/m/y or d-m-y
function dmyToDate(s) {
var bits = s.split(/[-/]/);
return new Date(bits[2], --bits[1], bits[0]);
}
// Difference between dates in days. If only one date supplied,
// today is used for endDate
// Copy startDate so don't mess it up
function daysBetweenDates(startDate, endDate) {
endDate = typeof endDate == 'string'? dmyToDate(endDate) : new Date();
startDate = typeof startDate == 'string'? dmyToDate(startDate) : new Date(startDate);
endDate.setHours(12,0,0);
startDate.setHours(12,0,0);
var diff = startDate - endDate;
var ms = 24 * 60 * 60 * 1000; // or 8.64e7
return Math.round(diff/ms);
}
The issue is definitely caused by your work.tax_credit_start string(?) value. The Datejs parser will return a null value if parsing fails.
In your sample, d1 will be subtracted from a null Date. This will return an unexpected number value. You're then passing that 'unexpected' number into the TimeSpan constructor, which will return some unexpected .days value.
Here's a working sample of your original.
Example
var d1 = Date.parse("2010-01-30");
var d2 = Date.parse("2010-06-30");
var span2 = new TimeSpan(d2 - d1);
span2.days // 150 days
I have a couple recommendations for your original sample:
If you're passing a string value into Date.parse() AND you have control over the format of that value, it would be best to pass in the ISO format of yyyy-MM-dd.
If you're expecting a Date object returned from Date.parse(), it's best to check that value against null to ensure you actually have a valid Date object.
The following demonstrates checking for a null value of d1, then setting to a default value if null.
Example
var d1 = Date.parse("30-00-2010"); // Not a valid Date
if (!d1) {
d1 = new Date();
}
console.log(d1); // will be 'now'
The above sample could be cleaned up by passing the default value right when setting the variable.
Example
var d1 = Date.parse("30-00-2010") || new Date();
console.log(d1); // will be 'now'
Hope this helps.

Categories