This question already has answers here:
Adding two numbers concatenates them instead of calculating the sum
(24 answers)
Closed 5 months ago.
I have a problem when summing dates in JavaScript. When I run a function to write the current month and the following 12 months, I can see that it retrieves all the month/year dates correct (I also added the number of days of each month).
But after, on changing the selection of the month, I want to display the number of days of the selected month. When I select Feb2022 it gives me 29 days, when actually it has 28 days (also written in the selection option)
How can JavaScript give me unconsistent values for similar functions?
//const today = new Date();
const monthNames = ["January","February","March","April","May","June","July","August","September","October","November","December"];
function writemonth(x) {
var text = "";
var today = new Date();
var dateObj = new Date(today.getFullYear(), today.getMonth()+x, 0);
var tdays = dateObj.getDate();
return tdays;
}
function writemonths() {
var text = "";
var today = new Date();
for (let i = 1; i <= 12; i++) {
var dateObj = new Date(today.getFullYear(), today.getMonth()+i, 0);
var monthNumber = dateObj.getMonth();
var year = dateObj.getFullYear();
var tdays = dateObj.getDate();
var monthName = monthNames[monthNumber];
text += "<option value='"+i+"'>" + monthName + " " + year +" " + tdays +"</option>";
}
return text;
}
//Let's start by writing the basic layout elements
document.getElementById("availability-calendar").innerHTML = "<select id='months' onchange='refresh();'><option value='0'>Loading...</option></select><div id='month'>"+writemonth(1)+"</div>";
document.getElementById("months").innerHTML = writemonths();
function refresh() {
var e = document.getElementById("months").value;
alert(e);
document.getElementById("month").innerHTML = writemonth(e);
}
<div id="availability-calendar"></div>
Its the issue with the writemonth function.
Expression var dateObj = new Date(today.getFullYear(), today.getMonth() + x, 0); is making string concatenation at today.getMonth() + x because today.getMonth() is a number and x is a string. On addition this will perform string concatenation. To fix this you have to convert x to number before addition, just by adding a + symbol in fromt of x like
var dateObj = new Date(today.getFullYear(), today.getMonth() + +x, 0);
Working fiddle
//const today = new Date();
const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
function writemonth(x) {
var text = "";
var today = new Date();
var dateObj = new Date(today.getFullYear(), today.getMonth() + +x, 0);
var tdays = dateObj.getDate();
return tdays;
}
function writemonths() {
var text = "";
var today = new Date();
for (let i = 1; i <= 12; i++) {
var dateObj = new Date(today.getFullYear(), today.getMonth() + i, 0);
var monthNumber = dateObj.getMonth();
var year = dateObj.getFullYear();
var tdays = dateObj.getDate();
var monthName = monthNames[monthNumber];
text += "<option value='" + i + "'>" + monthName + " " + year + " " + tdays + "</option>";
}
return text;
}
//Let's start by writing the basic layout elements
document.getElementById("availability-calendar").innerHTML = "<select id='months' onchange='refresh();'><option value='0'>Loading...</option></select><div id='month'>" + writemonth(1) + "</div>";
document.getElementById("months").innerHTML = writemonths();
function refresh() {
var e = document.getElementById("months").value;
// alert(e);
console.log(e);
document.getElementById("month").innerHTML = writemonth(e);
}
<div id="availability-calendar"></div>
Digging a little deeper into your issue
Your function writemonth is recieving parameters as string. Because you have provided the value of each option as a string inside the function writemonths with below statement
text += "<option value='" + i + "'>" + monthName + " " + year + " " + tdays + "</option>"
So inside your writemonth function the value for each option will be recieved as a string. So the expression today.getMonth() + x provides string as the result.
The issue is not just with February option. The year is generated wrong for all options. In case of February option, the writemonth function recieves parameter as "6". So the expression today.getMonth() + x will provide "86" as the result.
Because todays month september returns getMonth() result 8 (As of today 13-September-2021 on which answer was posted). So the expression var dateObj = new Date(today.getFullYear(), today.getMonth() + x, 0); will return a date February 29 2028.
This is because the month value "86" adds 7 years to the year because 86/12 gives quotient than 7 and reminder 2. So all the result generated will be 7 years ahead. For 2028, Febrary has 29 days and all other months days wont varry. Because here only the year is getting incremented by 7, not the month.
Please see the value of date in the below fiddle. A little surprised with the year?
function writemonth(x) {
var text = "";
var today = new Date();
var dateObj = new Date(today.getFullYear(), today.getMonth() + x, 0);
console.log(dateObj);
var tdays = dateObj.getDate();
return tdays;
}
writemonth("6")
+ Symbol is multitasking
Adding a number to a number with + generate a number as the result.
Example
const num1 = 10;
const num2 = 20;
const result = num1 + num2;
console.log(result);
console.log(typeof result);
Adding a string to another string with + will generate a string as the result.
Example
const str1 = "John";
const str2 = "Doe";
const result = str1 + str2;
console.log(result);
console.log(typeof result);
If a number is added to a string with +, then JavaScript provides a string as the response.
In JavaScript, the + operator is used for both numeric addition and
string concatenation. When you "add" a number to a string the
interpreter converts your number to a string and concatenates both
together.
Example
const num1 = 10;
const str1 = "Name";
const result = num1 + str1;
console.log(result);
console.log(typeof result);
Related
I'm trying to create a function that creates a dynamic date range based on the date supplied in a string.
What I've done so far:
Capture date in the string I'm looking to change;
Check to see if that date is a Thursday (if so the range will need to account for the weekend)
What I need to do:
Find a way to get the second date in the range to account for the weekend;
Find a way to make sure that the second date takes into account the last day of the month.
Apologies for old syntax, GTM doesn't like anything using ES6 so I'm a little constrained on this project.
Note I am using DD/MM/YYYY
var regex = /[\d\/\d\/\d]/g;
var text = document.querySelector('.shipmentLineTitle b');
var originalDate = text.innerText.match(regex, "");
if (originalDate.length > 10) {
originalDate.pop();
originalDate.join('');
}
var ogDateString = originalDate.join('');
var dayNumber = originalDate.splice(0, 2).join('');
var monthNumber = originalDate.splice(1, 2).join('');
var yearNumber = originalDate.splice(2, 4).join('');
// if originalDate is a thursday (5) dynamicString will need to be a Monday (1).
var date = new Date(yearNumber, monthNumber -1, dayNumber);
var dynamicDateString = "";
if (date.getDay == 5) {
var newDate = new Date(date) + (86400000 * 3);
var dd = newDate.getDate();
var mm = newDate.getMonth() +1;
var yy = newDate.getFullYear();
dymamicDateString = dd + '/' + mm + '/' + yy;
} else {
var newDate = new Date(date) + 86400000;
var dd = newDate.getDate();
var mm = newDate.getMonth() +1;
var yy = newDate.getFullYear();
dynamicDateString = dd + '/' + mm + '/' + yy;
}
var newContent = 'Delivery will be made between ' + ogDateString + ' - ' + dynamicDateString + '. An accurate delivery date will be provided after you place your order.';
text.innerText = newContent;
<span class="shipmentLineTitle">Delivery details: <b>your delivery will arrive on 09/10/2020 (1 delivery)</b></span>
Thursday is day 4
Here is a simpler script
var textField = document.querySelector('.shipmentLineTitle b'),
text = textField.innerText,
originalDate = text.match(/\d{2}\/\d{2}\/\d{4}/)[0].split("/"),
dayNumber = +originalDate[0],
monthNumber = +originalDate[1],
yearNumber = +originalDate[2],
date = new Date(yearNumber, monthNumber - 1, dayNumber, 15, 0, 0, 0),
aDay = 86400000,
newDate = new Date(date),
day = date.getDay(),
daysToAdd = 1; // Sunday to Wednesday
// if originalDate is a Thursday (4) or Saturday (6), dynamicString will need to be a Monday (1).
if (day === 4) daysToAdd = 4; // Thursday - delivery Monday
else if (day === 6) daysToAdd = 2; // Saturday
newDate.setDate(newDate.getDate() + daysToAdd);
var dd = newDate.getDate(),
mm = newDate.getMonth() + 1,
yy = newDate.getFullYear(),
dynamicDateString = dd + '/' + mm + '/' + yy,
newContent = text + ' - ' + dynamicDateString + '</b>. An accurate delivery date will be provided after you place your order.';
textField.innerHTML = newContent;
<span class="shipmentLineTitle">Delivery details: <b>your delivery will arrive on 08/10/2020 (1 delivery)</b></span>
I would suggest to user moment.js a very good date library to manipulate dates. It has lot of function to add/substract dates, hours, days etc.
There is https://www.npmjs.com/package/moment-business-days which servers exactly what you need
I have this code where I convert the current date to this format 2020-08-20 . But how do I alter it to give me the date 10 days from today and 10 days before today.
eg today is 2020-08-20 I am trying to get 10 days from today 2020-08-30
This is my code
const dateConverter = (dateIn) => {
var year = dateIn.getFullYear();
var month = dateIn.getMonth() + 1; // getMonth() is zero-based
var day = dateIn.getDate();
return year + "-" + month.toString().padStart(2, "0") + "-" + day.toString().padStart(2, "0");
}
var today = new Date();
console.log(dateConverter(today));
It's a little bit tricky. First set the hours from the date to 12 for avoiding problems with summer/wintertime-changing. Then use getDate add 10 for the extra days and setDate with the new value. Now you have a value in milliseconds, generate out of this a new date to get an dateobject. For the second date subtract 20 days because the original date was changed by the action before and do all other the same.
Format the output for the dates with getFullYear, getMonth and getDate
. Because month is handled in JS from 0 to 11 add 1 month. Months and days could be 1-digit but you want it 2 digits, so add before the string "0" and get the last 2 chars of it with slice.
Do the format for both dates and return them as array.
const dateConverter = (dateIn) => {
dateIn.setHours(12);
let dateIn10days = new Date(dateIn.setDate(dateIn.getDate() + 10));
let dateFor10days = new Date(dateIn.setDate(dateIn.getDate() - 20));
let strIn10Days = dateIn10days.getFullYear() + '-' + ('0' +(dateIn10days.getMonth()+1)).slice(-2) + '-' + ('0' + dateIn10days.getDate()).slice(-2);
let strFor10Days = dateFor10days.getFullYear() + '-' + ('0' +(dateFor10days.getMonth()+1)).slice(-2) + '-' + ('0' + dateFor10days.getDate()).slice(-2);
return [strFor10Days, strIn10Days];
}
let today = new Date();
console.log(dateConverter(today));
Try this
const dateConverter = (dateIn) => {
var year = dateIn.getFullYear();
var month = dateIn.getMonth() + 1; // getMonth() is zero-based
var day = dateIn.getDate();
return year + "-" + month.toString().padStart(2, "0") + "-" + day.toString().padStart(2, "0");
}
var today = new Date();
var numberOfDaysToAdd = 10;
var tenDaysPlus = today.setDate(today.getDate() + numberOfDaysToAdd);
console.log(dateConverter(today));
var today = new Date();
var numberOfDaysToSubtract = 10;
var tenDaysMinus = today.setDate(today.getDate() - numberOfDaysToSubtract);
console.log(dateConverter(today));
I would suggest you to use the moment library but you still want plain javascript
const convert = (date) => {
const pastDate = new Date(date)
pastDate.setDate(pastDate.getDate() - 10);
const futureDate = new Date(date)
futureDate.setDate(futureDate.getDate() + 10);
return { pastDate, futureDate }
}
call convert function with any date.
This code will help you
Reference JavaScript calculating date from today date to 7 days before
for after 10 days just just convert the - to +
const dateConverter = (dateIn) => {
var dates ={};
var days = 10; // Days you want to subtract
for(let i=0;i<days;i++){
var date = dateIn;
var last = new Date(date.getTime() - (i * 24 * 60 * 60 * 1000));
var day = last.getDate();
var month= last.getMonth()+1;
var year= last.getFullYear();
dates[i] = year + "-" + month.toString().padStart(2, "0") + "-" + day.toString().padStart(2, "0");
}
return dates
}
var today = new Date();
console.log(dateConverter(today));
I've been messing around that before as well.
But on this Stack Overflow you can find a really good answer:
Add days to JavaScript Date
Date.prototype.addDays = function(days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() + days);
return date;
}
var date = new Date();
alert(date.addDays(5));
This is the code taken from that post.
For subtracting days, just replace the "+ days" with "- days"
Hope this solved your problem!
You can convert all the dates to timestamp and then simply calculate with them:
const dateTimestamp = new Date("2020-10-10").getTime()
const milisecondsInADay = 60*60*24*1000
const milisecondsInTenDays = milisecondsInADay * 10
const beforeDate = new Date(dateTimestamp - milisecondsInTenDays)
const afterDate = new Date(dateTimestamp + milisecondsInTenDays)
console.log("before", beforeDate)
console.log("after", afterDate)
console.log("initially", new Date(dateTimestamp))
I want to show the difference between today and selected date time to show the remained time.
I used the solution mentioned in stack overflow. But I have problem about today!
When the selected day is today, or before, I mean, when the difference (diffDays) is not positive, I get wrong result. How can I manage this?
$("#ServiceTime").change(
function (e) {
var firstDate = $(this).val();
var secondDate = new Date();
var diffDays = firstDate.getTime() - secondDate.getTime();
var date = new Date(diffDays);
var str = '';
str += date.getUTCDate()-1 + " days and ";
str += date.getUTCHours() + " hours and ";
str += date.getUTCMinutes() + " minutes";
str += "remained...";
$("#remainedHourToService").html(str);
});
UPDATED:
I can not use abs by itself, if user select two past day, again he will see '1 day and 58 minutes and... ' but I want '0 days and 0 minutes.... remained'.
Just use Math.abs() to get absolute value.
$("#ServiceTime").change(function (e) {
var firstDate = $(this).val();
var second
Date = new Date();
var diffDays = Math.abs(firstDate.getTime() - secondDate.getTime());
var date = new Date(diffDays);
var str = '';
str += date.getUTCDate()-1 + " days and ";
str += date.getUTCHours() + " hours and ";
str += date.getUTCMinutes() + " minutes";
str += "has remained...";
$("#remainedHourToService").html(str);
});
UPDATE:
Easy to solve that issue. :)
$("#ServiceTime").change(function (e) {
var firstDate = $(this).val();
var second
Date = new Date();
var diff = firstDate.getTime()-secondDate.getTime();
var str2 = "";
if(diff > 0)
str2 = "have remained...";
else
str2 = "have passed...";
var diffDays = Math.abs(diff);
var date = new Date(diffDays);
var str = '';
str += date.getUTCDate()-1 + " days and ";
str += date.getUTCHours() + " hours and ";
str += date.getUTCMinutes() + " minutes";
str += str2;
$("#remainedHourToService").html(str);
});
Objective: Setup the date in the array at the end of the block to read: yyyymmdd including the zeros. (example data build: numDaysAPITimes = [20150403]). What I got is not getting the month correctly and the numDaysAPITimes array is storing only the year for some reason.
var totalPrecipSinceDate;
var numDaysAPITimes = [];
var userDataDatePick = document.getElementById('dateRngPick').value;
if (userDataDatePick >=1)
{
for (var i = 0; i <= (userDataDatePick-1); i++) //place user userData-1 where i <= input
{
var myDate = new Date(); //http://stackoverflow.com/questions/7693170/javascript-convert-from-epoch-string-to-date-object
var epoch = myDate.getTime();
var unixEpoch = Math.round(epoch/1000)
var backDateEpochTime = Math.round(unixEpoch - (86400 * i)); //Get each day (UNIX seconds)
var d = new Date(backDateEpochTime); //Convert to UTC
var curr_date = d.getDate();
var curr_month = d.getMonth() + 1; //Months are zero based
var curr_year = d.getFullYear();
numDaysAPITimes[i] = (curr_year + curr_month + curr_date);
}
}
else
{
alert("You have not entered a valid number for the date.");
numDaysAPITimes.length = 0;
}
a couple things:
your date info is getting added together as numbers, that why it seems the year is only going through. One way to handle that would be to use the toString() method.
you'll probably want leading zeroes on the day and month, which you can achieve by prepending a 0 and then doing a slice -2.
That would looks like This JSFiddle, or:
var totalPrecipSinceDate;
var numDaysAPITimes = [];
var userDataDatePick = 2;//document.getElementById('dateRngPick').value;
if (userDataDatePick >=1)
{
for (var i = 0; i <= (userDataDatePick-1); i++) //place user userData-1 where i <= input
{
var myDate = new Date(); //http://stackoverflow.com/questions/7693170/javascript-convert-from-epoch-string-to-date-object
var epoch = myDate.getTime();
var unixEpoch = Math.round(epoch/1000)
var backDateEpochTime = Math.round(unixEpoch - (86400 * i)); //Get each day (UNIX seconds)
var d = new Date((1000*backDateEpochTime)); //Convert to UTC
var curr_date = ("0" + d.getDate()).slice(-2)
var curr_month = ("0"+ (d.getMonth() + 1)).slice(-2); //Months are zero based
var curr_year = d.getFullYear();
console.log(d.getMonth());
numDaysAPITimes[i] = (curr_year.toString() + curr_month.toString() + curr_date.toString());
}
}
else
{
alert("You have not entered a valid number for the date.");
numDaysAPITimes.length = 0;
}
console.log(numDaysAPITimes)
I need to retrieve nth weekday of the current date in js. like 1st Sunday, 2nd Sunday
var d=new Date();
var weekDay=d.getDay();
here weekDay gives me 4 that means its Wednesday(3rd Wednesday). So far its good.
from weekDay i can say that its wednesday.
how to calcuate the "3rd" index of this wednesday?
Thank you
What du you actually mean? To get the dates you could use Date(). Like for instance creating a variable "today" and setting it to be todays date.
var today = new Date();
In a greater context you could go as far as showing everything from weekdays, date, year etc etc! I'll provide a code bit below. The code shows a dynamic clock/date in HTML.
You can format this the way you want, and choose which variables to show! This is btw the same code as found here: Other thread/question
<!DOCTYPE html>
<html>
<head>
<script>
function startTime() {
var today=new Date();
var day = today.getDate();
var month = today.getMonth();
var year = today.getFullYear();
var h=today.getHours();
var m=today.getMinutes();
var s=today.getSeconds();
m = checkTime(m);
s = checkTime(s);
document.getElementById('txt').innerHTML = "Date: " + day + "/" + month + "/" + year + " " + "Clock: " + h+":"+m+":"+s;
var t = setTimeout(function(){startTime()},500);
}
function checkTime(i) {
if (i<10) {i = "0" + i}; // add zero in front of numbers < 10
return i;
}
</script>
</head>
<body onload="startTime()">
<div id="txt"></div>
</body>
</html>
Is this what you mean?
Something like this
function getNth(dat) {
var days = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday','saturday'],
nth = ['st', 'nd', 'rd', 'th', 'th'],
d = dat ? dat instanceof Date ? dat : new Date(dat) : new Date(),
date = d.getDate(),
day = d.getDay(),
n = Math.ceil(date / 7);
return n + nth[n-1] + ' ' + days[day];
}
document.body.innerHTML = '' +
'today ....: ' + getNth() + '<br>' +
'1/31/2015 : ' + getNth('1/31/2015') + '<br>' +
'1/16/2015 : ' + getNth('1/16/2015');
body {font-family: monospace}
As per my understanding you want what date will be 1st, 2nd sunday/Monday from today. If it is that then you can use this
//consider sun=o,mon=1,....,sat:6
function getWeekday(n,day)
{
var today = new Date();
var presentDay = today.getDay();
var presentTime = today.getTime();
if(day < presentDay)
{
day = day +6;
}
var diff = day - present day;
var daysAfter = (n-1)*7 + diff;
var timeAfter = presentTime+daysAfter*86400000;
var next date = new Date(timeAfter);
}
// if you want to get 1st sunday from today just call this
var sunday1 = getWeekday(1,0)
// to get second monday from today
var monday2 = getWeekday(2,1)