date error for date class google appscript - javascript

The problem that i am having here is that when i minus back to then end of the month, instead of going back to the 29 or 28 of last month the program starts to minus months instead of days. Bellow is my full code and below that is the output it produces in the google spread sheet.
function trying(){
var date = new Date();
var datechange = new Date();
var array = new Array(7);
for (var i = 0; i < 7; i++) {
array[i] = new Array(0);
}
for ( var i = 0; i < 7; i++){
days = i + 8
datechange.setDate(date.getDate() - days);
var tabName = Utilities.formatDate(datechange, 'MST', 'yyyy-MM-dd').toString();
array[i][0] = tabName;
}
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Want");
sheet.getRange("B2:B8").setValues(array);
}
This are the dates that are produced.
05/07/2012
04/07/2012
03/07/2012
02/07/2012
01/07/2012
30/06/2012
30/05/2012

You have to define datechange inside your loop, and not outside:
var date = new Date();
for ( var i = 0; i < 30; i++){
days = i + 8
var datechange = new Date();
datechange.setDate(date.getDate() - i);
console.log(datechange);
}

Date.getDate() returns the date (1-31) - so what you are doing is not correct.
Instead try this:
var ONE_DAY = 24 * 60 * 60 * 1000; //in milliseconds
for ( var i = 0; i < 7; i++){
days = i + 8
datechange.setDate(date.getTime() - (days * ONE_DAY));
var tabName = Utilities.formatDate(datechange, 'MST', 'yyyy-MM-dd').toString();
array[i][0] = tabName;
}

This is how JavaScript dates work. See here for full details.

Related

How to get current week date in javascript?

I have a problem getting the current week date in javascript. I wrote the following code to get the current week's date, It was working well but it seems it sometimes returns the next week's date. I could not understand where is the problem.
any help would be appreciated.
This is my code:
let curr = new Date();
let week = [];
for (let i = 1; i <= 7; i++) {
let first = curr.getDate() - curr.getDay() + i;
let day = new Date(curr.setDate(first)).toISOString().slice(0, 10);
week.push(day);
};
console.log(week)
The output:
['2022-06-13', '2022-06-14', '2022-06-15', '2022-06-16', '2022-06-17', '2022-06-18', '2022-06-19']
but today's date is 6/12/2022, but the above date started from 13/06/2022
Source:
here
When you do +i you are adding numbers 1 to 7 to your first variable. Now since the week starts from Sunday=0, you do not need to add an offset.
Just iterate loop from 0 to 6:
let curr = new Date(new Date().getTime() - (7 * 24 * 60 * 60 * 1000));
let week = [];
for (let i = 0; i < 7; i++) {
let first = curr.getDate() - curr.getDay() + i;
let day = new Date(curr.setDate(first)).toISOString().slice(0, 10);
week.push(day);
};
console.log(week)
[Edit] : If you want to get from 7 days ago, you can change how you initialize your curr variable.
From this :
let curr = new Date();
to this:
let curr = new Date(new Date().getTime() - (7 * 24 * 60 * 60 * 1000));
I use the getTime() method to get the epoch of today's date and subtract exactly the milliseconds passed in 7 days (or 1 week).
If I understand your question correctly, you must take into consideration when current day is sunday to get current week first day (monday).
let curr = new Date();
let week = [];
for (let i = 1; i <= 7; i++) {
let first = curr.getDate() - curr.getDay() + i;
if (curr.getDay() === 0){
first = curr.getDate() - 6;
}
let day = new Date(curr.setDate(first)).toISOString().slice(0, 10);
week.push(day);
};
console.log(week)
Start the for loop from 0
Like so
let curr = new Date();
let week = [];
for (let i = 0; i < 7; i++) {
let first = curr.getDate() - curr.getDay() + I;
let day = new Date(curr.setDate(first)).toISOString().slice(0, 10);
week.push(day);
};
console.log(week)
Remember, if you start from 1 and add 1 to the current date it will return tomorrow, and if you add 0 to today it retustns this date.
You can use moment.js library
let week = [];
let firstDayOfWeek = moment().startOf('week');
for (let i = 0; i < 7; i++) {
week.push(moment(firstDayOfWeek).add(i, 'd'));
};
console.log(week)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>

Cannot read property 'length' error in JS

I have the an array of date range and I need to get a difference between number of days in between those months and create an array.
10/05/2015 - 11/05/2015 = 30 days
11/05/2015 - 12/ 05/2015 = 31 days
[30,31....]
I have the following code for date range.
function createLedger(stDate, etDate) {
if (stDate && etDate) {
var endOfLeaseDate = moment(etDate, "MM/DD/YYYY");
var startOfLeaseDate = moment(stDate, "MM/DD/YYYY");
dateRange(startOfLeaseDate, endOfLeaseDate);
}
}
function dateRange(stDate, etDate) {
var dates = [];
var now = stDate.clone();
var day = stDate.date();
while (now.isBefore(etDate)) {
//deal with variable month end days
var monthEnd = now.clone().endOf("month");
if (now.date() < day && day <= monthEnd.date()) {
now.date(day);
}
dates.push(now.format("MM/DD/YYYY"));
now = now.clone().add({
"months": 1
});
}
return dates;
}
function daysBetween(date1, date2) {
var Diff = Math.abs(date2.getTime() - date1.getTime());
var TimeDifference = Math.round(Diff / (1000 * 3600 * 24));
return TimeDifference;
}
function RunLedgerAndPV() {
var pDate = "11/21/2018"
var stDate = "10/5/2015";
var etDate = "12/4/2019";
var dateArr = createLedger(stDate, etDate);
var dayCounts = "";
for (var x = 0; x < dateArr.length; x++) {
dayCounts += daysBetween(dateArr[x], dateArr[x + 1], ",");
}
console.log(dayCounts);
}
RunLedgerAndPV();
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
It's throwing an error at dateArr.length for some reason. Not sure what i am doing wrong here. Any help is appreciated. Thank you.
To add on to Vijay you are not returning anything in dateRange() either. Return dates array then return where you called dateRange().
Be aware this leads to more errors to do with your naming of daysBetween function when you are calling daysBetweenArrears.
EDIT
Few other errors:
You are calling getTime() on a string so this causes an error. You need to convert to a date object using new Date(date2) - new Date(date1).
Another return also missing for the Run function.
Code below:
function createLedger(stDate, etDate) {
if (stDate && etDate) {
var endOfLeaseDate = moment(etDate, "MM/DD/YYYY");
var startOfLeaseDate = moment(stDate, "MM/DD/YYYY");
return dateRange(startOfLeaseDate, endOfLeaseDate); // Added return
}
}
function dateRange(stDate, etDate) {
var dates = [];
var now = stDate.clone();
var day = stDate.date();
while (now.isBefore(etDate)) {
//deal with variable month end days
var monthEnd = now.clone().endOf("month");
if (now.date() < day && day <= monthEnd.date()) {
now.date(day);
}
dates.push(now.format("MM/DD/YYYY"));
now = now.clone().add({
"months": 1
});
}
return dates; // Added return
}
function daysBetween(date1, date2) {
var Diff = Math.abs(new Date(date2).getTime() - new Date(date1).getTime()); // Used new Date()
var TimeDifference = Math.round(Diff / (1000 * 3600 * 24));
return TimeDifference;
}
function RunLedgerAndPV() {
var pDate = "11/21/2018"
var stDate = "10/5/2015";
var etDate = "12/4/2019";
var dateArr = createLedger(stDate, etDate);
var dayCounts = "";
for (var x = 0; x < dateArr.length; x++) {
dayCounts += daysBetween(dateArr[x], dateArr[x + 1]) + ' '; // added a + ' ' to add a space to the result. Removed the ',' that you were adding in daysBetween but not using
}
return dayCounts; // Added return
}
RunLedgerAndPV(); //This wont show anything so wrap it in a console.log to see it return what you need
In your function "crrateLedger" you don't return anyting and you are assigning that in "var dateArr" hence it is set to undefined by javascript and you are trying to access property length of dateArr which is undefined

How to count the number of sundays between two dates

I tried the JS below:
var start = new Date("25-05-2016");
var finish = new Date("31-05-2016");
var dayMilliseconds = 1000 * 60 * 60 * 24;
var weekendDays = 0;
while (start <= finish) {
var day = start.getDay()
if (day == 0) {
weekendDays++;
}
start = new Date(+start + dayMilliseconds);
}
alert(weekendDays);
However, it gives the wrong output.
I need to get the total count of Sundays between the two dates.
You use incorrect date format.It will work if init date so:
var start = new Date("2016-05-25");
var finish = new Date("2016-05-31");
Your date format is wrong. Dates' string format is "yyyy-mm-dd". See here for more information.
Also, looping each day of the interval is very inefficient. You may try the following instead.
function getNumberOfWeekDays(start, end, dayNum){
// Sunday's num is 0 with Date.prototype.getDay.
dayNum = dayNum || 0;
// Calculate the number of days between start and end.
var daysInInterval = Math.ceil((end.getTime() - start.getTime()) / (1000 * 3600 * 24));
// Calculate the nb of days before the next target day (e.g. next Sunday after start).
var toNextTargetDay = (7 + dayNum - start.getDay()) % 7;
// Calculate the number of days from the first target day to the end.
var daysFromFirstTargetDay = Math.max(daysInInterval - toNextTargetDay, 0);
// Calculate the number of weeks (even partial) from the first target day to the end.
return Math.ceil(daysFromFirstTargetDay / 7);
}
var start = new Date("2016-05-25");
var finish = new Date("2016-05-31");
console.log("Start:", start);
console.log("Start's week day num:", start.getDay());
console.log("Finish:", finish);
console.log("Finish's week day num:", finish.getDay());
console.log("Number of Sundays:", getNumberOfWeekDays(start, finish));
Your date format and comparison condition should change like the following:
var start = new Date("2016-05-11");
var finish = new Date("2016-05-31");
var dayMilliseconds = 1000 * 60 * 60 * 24;
var weekendDays = 0;
while (start.getTime() <= finish.getTime()) {
var day = start.getDay();
if (day == 0) {
weekendDays++;
}
start = new Date(+start + dayMilliseconds);
}
alert(weekendDays);
Check Fiddle
You are using incorrect date format.
Just Change the format to:
var start = new Date(2016, 4, 25);
var finish = new Date(2016, 4, 31);
Try this function:
function CalculateWeekendDays(fromDate, toDate){
var weekendDayCount = 0;
while(fromDate < toDate){
fromDate.setDate(fromDate.getDate() + 1);
if(fromDate.getDay() === 0){
++weekendDayCount ;
}
}
return weekendDayCount ;
}
console.log(CalculateWeekendDays(new Date(2011, 6, 2), new Date(2011, 7, 2)));
This will give you number of sunday come between 2 dates
change your date format.It will work
var start = new Date("05-16-2016");
var finish = new Date("05-31-2016");
var dayMilliseconds = 1000 * 60 * 60 * 24;
var weekendDays = 0;
while (start <= finish) {
var day = start.getDay()
if (day == 0) {
weekendDays++;
}
start = new Date(+start + dayMilliseconds);
}
console.log(weekendDays);
JS date format doesn't have "dd-MM-yyyy" ,so it will invalid date format .Try recreate date is ok or just change your date format Date Format
Try this:
var start = new Date("25-05-2016");
var end = new Date("31-05-2016");
var startDate = new Date(start);
var endDate = new Date(end);
var totalSundays = 0;
for (var i = startDate; i <= endDate; ){
if (i.getDay() == 0){
totalSundays++;
}
i.setTime(i.getTime() + 1000*60*60*24);
}
console.log(totalSundays);
// Find date of sundays b/w two dates
var fromDate = new Date('2022-10-26')
var toDate = new Date('2022-11-31')
var sunday = 0
var milisec = 1000 * 60 * 60 * 24;
while (fromDate <= toDate) {
var day = fromDate.getDay()
if (day == 0) {
sunday++
console.log('Date of sunday:', fromDate)
}
fromDate = new Date(+fromDate + milisec)
}
console.log('Total no. of sundays:', sunday)

get an array of dates for the past week in format dd_mm

I need to have an array of dates for whole days of the last week, including the current day, for e.g
['05/06', '04/06', '03/06', '02/06', '01/06', '31/05', '30/05']
(format dd/mm)
how can i do this?
I know there is the Date() object, but other than that I'm stumped.
logic along the lines of:
var dates = [];
var today = new Date();
for (var i = 0; i<7; i++){
var date = today - (i+1);
dates.push(date);
}
So you want an array containing todays date and a further 6 elements, with todays date-1, todays date-2 etc...?
var dates = [];
var date = new Date();
for (var i = 0; i < 7; i++){
var tempDate = new Date();
tempDate.setDate(date.getDate()-i);
var str = tempDate.getDate() + "/" + tempDate.getMonth();
dates.push(str);
}
console.log(dates);
Output: ["5/5", "4/5", "3/5", "2/5", "1/5", "31/4", "30/4"]
If you need numbers with leading 0's, try this:
var dates = [];
var date = new Date();
for (var i = 0; i < 7; i++){
var tempDate = new Date();
tempDate.setDate(date.getDate()-i);
var str = pad(tempDate.getDate()) + "/" + pad(tempDate.getMonth());
dates.push(str);
}
console.log(dates);
function pad(n) {
return (n < 10) ? ("0" + n) : n;
}
Output: ["05/05", "04/05", "03/05", "02/05", "01/05", "31/04", "30/04"]
Check this working sample, where all days are printed out:
http://jsfiddle.net/danyu/Tu5R6/6/
This is the main logic:
for(var i=7;i>0;i--)
{
tempDate.setDate(tempDate.getDate()-1);
output+=tempDate+"<br/>";
}
Modify it to store those days into your array.

Loop through a date range with JavaScript

Given two Date() objects, where one is less than the other, how do I loop every day between the dates?
for(loopDate = startDate; loopDate < endDate; loopDate += 1)
{
}
Would this sort of loop work? But how can I add one day to the loop counter?
Thanks!
Here's a way to do it by making use of the way adding one day causes the date to roll over to the next month if necessary, and without messing around with milliseconds. Daylight savings aren't an issue either.
var now = new Date();
var daysOfYear = [];
for (var d = new Date(2012, 0, 1); d <= now; d.setDate(d.getDate() + 1)) {
daysOfYear.push(new Date(d));
}
Note that if you want to store the date, you'll need to make a new one (as above with new Date(d)), or else you'll end up with every stored date being the final value of d in the loop.
Based on Tom GullenĀ“s answer.
var start = new Date("02/05/2013");
var end = new Date("02/10/2013");
var loop = new Date(start);
while(loop <= end){
alert(loop);
var newDate = loop.setDate(loop.getDate() + 1);
loop = new Date(newDate);
}
I think I found an even simpler answer, if you allow yourself to use Moment.js:
// cycle through last five days, today included
// you could also cycle through any dates you want, mostly for
// making this snippet not time aware
const currentMoment = moment().subtract(4, 'days');
const endMoment = moment().add(1, 'days');
while (currentMoment.isBefore(endMoment, 'day')) {
console.log(`Loop at ${currentMoment.format('YYYY-MM-DD')}`);
currentMoment.add(1, 'days');
}
<script src="https://cdn.jsdelivr.net/npm/moment#2/moment.min.js"></script>
If startDate and endDate are indeed date objects you could convert them to number of milliseconds since midnight Jan 1, 1970, like this:
var startTime = startDate.getTime(), endTime = endDate.getTime();
Then you could loop from one to another incrementing loopTime by 86400000 (1000*60*60*24) - number of milliseconds in one day:
for(loopTime = startTime; loopTime < endTime; loopTime += 86400000)
{
var loopDay=new Date(loopTime)
//use loopDay as you wish
}
Here simple working code, worked for me
var from = new Date(2012,0,1);
var to = new Date(2012,1,20);
// loop for every day
for (var day = from; day <= to; day.setDate(day.getDate() + 1)) {
// your day is here
console.log(day)
}
var start = new Date("2014-05-01"); //yyyy-mm-dd
var end = new Date("2014-05-05"); //yyyy-mm-dd
while(start <= end){
var mm = ((start.getMonth()+1)>=10)?(start.getMonth()+1):'0'+(start.getMonth()+1);
var dd = ((start.getDate())>=10)? (start.getDate()) : '0' + (start.getDate());
var yyyy = start.getFullYear();
var date = dd+"/"+mm+"/"+yyyy; //yyyy-mm-dd
alert(date);
start = new Date(start.setDate(start.getDate() + 1)); //date increase by 1
}
As a function,
function getDatesFromDateRange(from, to) {
const dates = [];
for (let date = from; date <= to; date.setDate(date.getDate() + 1)) {
const cloned = new Date(date.valueOf());
dates.push(cloned);
}
return dates;
}
const start = new Date(2019, 11, 31);
const end = new Date(2020, 1, 1);
const datesArray = getDatesFromDateRange(start, end);
console.dir(datesArray);
Based on Tabare's Answer,
I had to add one more day at the end, since the cycle is cut before
var start = new Date("02/05/2013");
var end = new Date("02/10/2013");
var newend = end.setDate(end.getDate()+1);
var end = new Date(newend);
while(start < end){
alert(start);
var newDate = start.setDate(start.getDate() + 1);
start = new Date(newDate);
}
Didn't want to store the result in an array, so maybe using yield?
/**
* #param {object} params
* #param {Date} params.from
* #param {Date} params.to
* #param {number | undefined} params.incrementBy
* #yields {Date}
*/
function* iterateDate(params) {
const increaseBy = Math.abs(params.incrementBy ?? 1);
for(let current = params.from; current.getTime() <= params.to.getTime(); current.setDate(current.getDate() + increaseBy)) {
yield new Date(current);
}
}
for (const d of iterateDate({from: new Date(2021,0,1), to: new Date(2021,0,31), incrementBy: 1})) {
console.log(d.toISOString());
}
If you want an efficient way with milliseconds:
var daysOfYear = [];
for (var d = begin; d <= end; d = d + 86400000) {
daysOfYear.push(new Date(d));
}
Let us assume you got the start date and end date from the UI and stored it in the scope variable in the controller.
Then declare an array which will get reset on every function call so that on the next call for the function the new data can be stored.
var dayLabel = [];
Remember to use new Date(your starting variable) because if you dont use the new date and directly assign it to variable the setDate function will change the origional variable value in each iteration`
for (var d = new Date($scope.startDate); d <= $scope.endDate; d.setDate(d.getDate() + 1)) {
dayLabel.push(new Date(d));
}
Based on Jayarjo's answer:
var loopDate = new Date();
loopDate.setTime(datFrom.valueOf());
while (loopDate.valueOf() < datTo.valueOf() + 86400000) {
alert(loopDay);
loopDate.setTime(loopDate.valueOf() + 86400000);
}

Categories