I have built a counter that counts (both up and down) the date. I only want to have the counter function run down, and once it hits the current date or later to stop running altogether. Right now it alerts saying the date is reached but continues counting even though it has reached the date.
Here is the JSFiddle for the counter.
Here is the Boolean
if(tDate == eDate) {
alert('Today is the event!');
return false;
// clearTimeout( countDown.prototype.update() );
} else {
counter();
}
Here is the whole code
$(document).ready(function() {
var monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var d = new Date();
var month = monthNames[d.getMonth()];
var day = d.getUTCDate();
var year = d.getUTCFullYear();
var eMonth = $("#d-month").html();
var eDay = $("#d-day").html();
var eYear = $("#d-year").html();
var tDate = month + " " + day + " " + year;
var eDate = eMonth + " " + eDay + " " + eYear;
alert("today's date: " + tDate + " event's date: " + eDate);
if(tDate == eDate) {
alert('Today is the event!');
return false;
// clearTimeout( countDown.prototype.update() );
} else {
counter();
}
function counter() {
function countDown(initDate, id) {
this.counterDate = new Date(initDate);
this.update();
}
countDown.prototype.calculateUnit=function(secDiff, unitSeconds){
var tmp = Math.abs((tmp = secDiff/unitSeconds)) < 1? 0 : tmp;
return Math.abs(tmp < 0 ? Math.ceil(tmp) : Math.floor(tmp));
}
countDown.prototype.calculate=function(){
var secDiff = Math.abs(Math.round(((new Date()) - this.counterDate)/1000));
this.days = this.calculateUnit(secDiff,86400);
this.hours = this.calculateUnit((secDiff-(this.days*86400)),3600);
this.mins = this.calculateUnit((secDiff-(this.days*86400)-(this.hours*3600)),60);
this.secs = this.calculateUnit((secDiff-(this.days*86400)-(this.hours*3600)-(this.mins*60)),1);
}
countDown.prototype.update=function(){
this.calculate();
$("#countdown-day").html(this.days + (this.days == 1));
$("#countdown-hour").html(this.hours + (this.hours == 1));
$("#countdown-min").html(this.mins + (this.mins == 1));
$("#countdown-sec").html(this.secs + (this.secs == 1));
var self = this;
setTimeout(function(){self.update();}, (1000));
}
function counterInit() {
var month = $("#d-month").html();
var day = $("#d-day").html();
var year = $("#d-year").html();
var time = $("#d-time").html();
new countDown( month + day + "," + year + time);
// new countDown('May 9, 2015, 00:00:00', 'counter'); }
}
counterInit();
}
});
I tried your fiddle and I can tell you there are some blank spaces at the end of each string which makes them differ between each other.
So If you just add these lines it will work
tDate = jQuery.trim(tDate);
eDate = jQuery.trim(eDate);
Here's your fiddle updated
http://jsfiddle.net/c5qkm5gL/
Edit:
I forgot to mention that I changed '.html()' to '.text()', this way you get the plain text instead of the html content.
As an advice, for debugging use console.log instead of an alert.
Related
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);
I have this function, that gives the user the correct amount of buttons depending on the month. So if the user loads the page, Februari will show up, and 28 buttons aswell. If the user changes to March, there will be 31 buttons. The user is able to click on the button, and the corresponding button will be added to the mySql database. So if the user chooses Februari, and the button 3, the value in the database will say 2018-02-03. The problem is, and what I need help with, is if the user changes the month on the page, it does not change the value in the database. The month value in the database is always the current month of the year. Tried different solutions but nothing works. The value of the month is in a h2 with the id "displayingMonth".
Function:
function drawTable(daysInMonth) {
var cellsToDraw = daysInMonth;
var table = document.getElementById("table");
var dateObj = new Date();
var month = dateObj.getMonth()+1;
var day = dateObj.getDate();
var year = dateObj.getFullYear();
newdate = year + "-" + month;
table.innerHTML = "";
for (r = 0; r < (daysInMonth / 7); r++) {
var newRow = document.createElement("tr");
table.appendChild(newRow);
for (c = 0; c < 31 && cellsToDraw > 0; c++) {
v = c +1;
//var newCell = document.createElement("td");
var newCell = document.createElement("input");
newCell.setAttribute("type", "radio");
newCell.setAttribute("name", "day");
newCell.setAttribute("value", newdate + "-" + v);
newRow.appendChild(newCell);
newCell.innerHTML =
cellsToDraw--;
}
}
}
to get the month displayed:
function daysInMonth(month, year) {
var days;
switch (month) {
case 1:
var leapYear = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
days = leapYear ? 29 : 28;
break;
case 3:
case 5:
case 8:
case 10:
days = 30;
break;
default:
days = 31;
}
return days;
}
To get the month:
window.onload = function() {
var month = new Date();
var index = month.getMonth();
var months = ["Januari", "Februari", "March", "April", "May", "June", "July", "Augusti", "September", "October", "November", "December"];
document.getElementById("todayField").innerHTML = months[month.getMonth()];
// Draws a table for the current month
drawTable(daysInMonth(index, 2018));
}
to get the next month
function next() {
var months = ["Januari", "Februari", "March", "April", "May", "June", "July", "Augusti", "September", "October", "November", "December"];
var weeks = ["Sunday", "Monday", "Tuseday", "Wednesday", "Thursday", "Friday", "Saturday"];
var nextMonth = index + 1 > 11 ? 0 : index + 1;
index = nextMonth;
document.getElementById("displayingMonth").innerHTML = months[nextMonth];
drawTable(daysInMonth(index, 2018));
}
HTML
<input id="newCell"type="hidden"name="day" value="">
All help is appriciated!
Alright, some slight adjustments here. This is highly specific to your code, so bear with the changes. The issue lies with the use of var dateObj = new Date(); and then pulling the month from it to add to each 'day' radio input a user chooses.
Each input is using the 'current date' for that, and thus pulls the wrong month for what its passing.
Instead, you'll need to push the selected month date into the drawTable function, so it can build properly from that. And example of such would be:
function drawTable(daysInMonth,selectedMonth) {
...
// selectedMonth has the proper index for the Date() function
// setting 2018 here, because your code isnt inc years yet
var dateObj = new Date(2018, selectedMonth, 1, 0, 0, 0, 0);
...
}
window.onload = function() {
...
drawTable(daysInMonth(index, 2018), month.getMonth());
}
function next() {
// you may want to deal with looping to the next year here too
...
drawTable(daysInMonth(index, 2018), nextMonth);// nextMonth holds proper index
}
I think I should note that this passes the "month index", because new Date() takes a month index of 0 - 11. So passing it straight from a .getMonth() is the most compatible (no need to add +1 or -1 to them).
Here is also full chunk of your code with many changes applied to reduce some complexity and allow for years to roll as next month loops. There are a lot of changes in here, but mainly, it relies a lot more on the Date() object. No need for the daysInMonth() function you have.
// set as global
var showDate = new Date();
var months = ["Januari", "Februari", "March", "April", "May", "June",
"July", "Augusti", "September", "October", "November", "December"];
var weeks = ["Sunday","Monday","Tuseday","Wednesday","Thursday","Friday","Saturday"];
function drawTable(forDate) {
var daysInMonth = new Date(forDate.getFullYear(),forDate.getMonth()+1,0).getDate();
// ^^^ magic way to get number of days!
var cellsToDraw = daysInMonth;
// for a zero-padded non-index YYYY-MM prefix value:
var newdate = forDate.getFullYear() +"-"+ ("0"+ (forDate.getMonth() + 1)).slice(-2);
var table = document.getElementById("table");
table.innerHTML = "";
for (var r = 0; r < (daysInMonth / 7); r++) {
var newRow = document.createElement("tr");
table.appendChild(newRow);
for (var c = 0; c < 31 && cellsToDraw > 0; c++) {
// for a zero-padded day to tack onto newdate
var day = ("0" + (c + 1)).slice(-2);
var newCell = document.createElement("input");
newCell.setAttribute("type", "radio");
newCell.setAttribute("name", "day");
newCell.setAttribute("value", newdate + "-" + day);// makes YYYY-MM-DD
newRow.appendChild(newCell);
newCell.innerHTML = '';
cellsToDraw--;
}
}
}
window.onload = function() {
document.getElementById("todayField").innerHTML = months[showDate.getMonth()];
drawTable( showDate );
};
function next() {
if (showDate.getMonth() == 11) {
showDate.setMonth( 0 );
showDate.setFullYear( showDate.getFullYear()+1 );
} else {
showDate.setMonth( showDate.getMonth()+1 );
}
document.getElementById("displayingMonth").innerHTML = months[showDate.getMonth()];
drawTable( showDate );
}
function prev() {
if (showDate.getMonth() === 0) {
showDate.setMonth( 11 );
showDate.setFullYear( showDate.getFullYear()-1 );
} else {
showDate.setMonth( showDate.getMonth()-1 );
}
document.getElementById("displayingMonth").innerHTML = months[showDate.getMonth()];
drawTable( showDate );
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Formatting a date in javascript
I know other possible formats in JavaScript Date object but I did not get on how to format the date to MM/dd/yyyy HH:mm:ss format.
Please let me know if you come across such problem.
[Addendum 12/2022]: Here's a library to format dates using Intl.DateTimeFormat.
Try something like this
var d = new Date,
dformat = [d.getMonth()+1,
d.getDate(),
d.getFullYear()].join('/')+' '+
[d.getHours(),
d.getMinutes(),
d.getSeconds()].join(':');
If you want leading zero's for values < 10, use this number extension
Number.prototype.padLeft = function(base,chr){
var len = (String(base || 10).length - String(this).length)+1;
return len > 0? new Array(len).join(chr || '0')+this : this;
}
// usage
//=> 3..padLeft() => '03'
//=> 3..padLeft(100,'-') => '--3'
Applied to the previous code:
var d = new Date,
dformat = [(d.getMonth()+1).padLeft(),
d.getDate().padLeft(),
d.getFullYear()].join('/') +' ' +
[d.getHours().padLeft(),
d.getMinutes().padLeft(),
d.getSeconds().padLeft()].join(':');
//=> dformat => '05/17/2012 10:52:21'
See this code in jsfiddle
[edit 2019] Using ES20xx, you can use a template literal and the new padStart string extension.
const dt = new Date();
const padL = (nr, len = 2, chr = `0`) => `${nr}`.padStart(2, chr);
console.log(`${
padL(dt.getMonth()+1)}/${
padL(dt.getDate())}/${
dt.getFullYear()} ${
padL(dt.getHours())}:${
padL(dt.getMinutes())}:${
padL(dt.getSeconds())}`
);
See also
You can always format a date by extracting the parts and combine them using string functions in desired order:
var date = new Date();
var dateStr =
("00" + (date.getMonth() + 1)).slice(-2) + "/" +
("00" + date.getDate()).slice(-2) + "/" +
date.getFullYear() + " " +
("00" + date.getHours()).slice(-2) + ":" +
("00" + date.getMinutes()).slice(-2) + ":" +
("00" + date.getSeconds()).slice(-2);
console.log(dateStr);
var d = new Date();
var curr_date = d.getDate();
var curr_month = d.getMonth();
var curr_year = d.getFullYear();
document.write(curr_date + "-" + curr_month + "-" + curr_year);
using this you can format date.
you can change the appearance in the way you want then
for more info you can visit here
var d = new Date();
// calling the function
formatDate(d,4);
function formatDate(dateObj,format)
{
var monthNames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ];
var curr_date = dateObj.getDate();
var curr_month = dateObj.getMonth();
curr_month = curr_month + 1;
var curr_year = dateObj.getFullYear();
var curr_min = dateObj.getMinutes();
var curr_hr= dateObj.getHours();
var curr_sc= dateObj.getSeconds();
if(curr_month.toString().length == 1)
curr_month = '0' + curr_month;
if(curr_date.toString().length == 1)
curr_date = '0' + curr_date;
if(curr_hr.toString().length == 1)
curr_hr = '0' + curr_hr;
if(curr_min.toString().length == 1)
curr_min = '0' + curr_min;
if(format ==1)//dd-mm-yyyy
{
return curr_date + "-"+curr_month+ "-"+curr_year;
}
else if(format ==2)//yyyy-mm-dd
{
return curr_year + "-"+curr_month+ "-"+curr_date;
}
else if(format ==3)//dd/mm/yyyy
{
return curr_date + "/"+curr_month+ "/"+curr_year;
}
else if(format ==4)// MM/dd/yyyy HH:mm:ss
{
return curr_month+"/"+curr_date +"/"+curr_year+ " "+curr_hr+":"+curr_min+":"+curr_sc;
}
}
I have a function that works out the past 3 months and displays the name by using an array.
I've just realised that when the new year comes round, for January, February & March, it won't be able to get the correct month.
I want to be able to do this without having to add in a hack (which is the only way I've seen to do this)
function getMonths()
{
var today = new Date();
var month = 0;
var currMonth = month-3;
var monthArray = new Array("January","February","March","April","May","June",
"July","August","September","October","November","December");
var menuMonths = new Array();
var count = 4;
var buffer = 10;
while(count >0)
{
var month = monthArray[currMonth];
alert(currMonth);
menuMonths.push(month);
currMonth = currMonth +1;
count = count -1;
}
return menuMonths;
}
Modulus is your friend. Try:
function getMonths()
{
var today = new Date();
var month = 1;
var monthArray = new Array("January","February","March","April","May","June",
"July","August","September","October","November","December");
var menuMonths = new Array();
for(var count = 3; count >= 0; count--)
menuMonths.push(monthArray[((12 + month - count) % 12)]);
return menuMonths;
}
alert(getMonths());
This little addition to your while-loop will ensure that currMonth is always a valid index of your monthArray:
while(count >0)
{
if (currMonth < 0)
currMonth += 12;
if (currMonth >=12 )
currMonth -= 12;
var month = monthArray[currMonth];
menuMonths.push(month);
currMonth = currMonth +1;
count = count -1;
}
working example: http://jsfiddle.net/RWhN4/
This is a bit hackish, but it should do what you want.
To figure out which month was 3 months ago you could do the following:
var d = new Date();
d.setMonth(d.getMonth() - 3);
var monthIndex = d.getMonth() //(0-11)
Let standard javascript methods do the calculations for you.
Here is your function updated to use the javascript methods to do the calculations for you:
function getMonths() {
var date = new Date();
//subttract 3 months
date.setMonth(0 - 3);
var monthArray = new Array("January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December");
var menuMonths = new Array();
var count = 4;
var buffer = 10;
while (count > 0) {
var month = monthArray[date.getMonth()];
alert(month);
menuMonths.push(month);
date.setMonth(date.getMonth() + 1);
count -= 1;
}
return menuMonths;
}
I did something similar to what you guys did, but I did it for the Trailing Twelve Months basically, in it's form format I used the following code:
$(".monthly_usage").val('');
var monthArray = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
var today = new Date();
var month = today.getMonth();
var year = today.getFullYear();
var output = "Enter Trailing Twelve Months Usage<br/><center><table border=1 cellpadding=10 cellspacing=0><thead><th>Month - Year</th><th>Usage</th></thead><tbody>";
for(var i = 0; i < 12; i++) {
output += "<tr><td>" + monthArray[today.getMonth()] + " " + year + "</td><td><input type=text class=monthly_usage name=usage[]></td></tr>";
var month = today.setMonth(today.getMonth() - 1);
var year = today.getFullYear();
}
output += "</tbody></table>"+
"<button id=submit_ttm>Submit Monthly Usage</button></center>";
return output;
function lastMonths(count,month,order) {
var arr = [];
//defaults
month = typeof month !== 'undefined' ? month : new Date().getMonth();
count = typeof count !== 'undefined' ? count : 3;
order = typeof order !== 'undefined' ? order : "asc";
while (count-- > 0) {
month = (--month < 0) ? 11 : month;
arr.push(["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"][month]);
}
return ( order === "asc" ) ? arr.reverse() : arr;
}
the function has defaults for the number of months to show, the start month, and the order
demo
I have JS code in both the body and head portions of my page. If I wanted to have them be in an external .js file, how would I move them over and then call them back onto the page?
Head -
<script language="Javascript">
setInterval("settime()", 1000);
function settime () {
var curtime = new Date();
var curhour = curtime.getHours();
var curmin = curtime.getMinutes();
var cursec = curtime.getSeconds();
var time = "";
if(curhour == 0) curhour = 12;
time = (curhour > 12 ? curhour - 12 : curhour) + ":" +
(curmin < 10 ? "0" : "") + curmin + ":" +
(cursec < 10 ? "0" : "") + cursec + " " +
(curhour > 12 ? "pm" : "am");
document.date.clock.value = time;
}
</script>
Body -
<script language="JS" type="text/javascript">
var monthArray = new Array("January", "February", "March", "April", "May",
"June", "July", "August", "September",
"October", "November", "December");
var today = new Date();
var todayMonth = today.getMonth();
var todayDate = today.getDate();
var todayYear = today.getFullYear();
document.write(monthArray[todayMonth] + " " + todayDate + ", " + todayYear);
</script>
Move your JS code into an external file (say, my.js) and include it within your page as :
<script type="text/javascript" src="my.js"></script>
Of course, the above assumes that my.js lies in the same folder/directory as your page. you'll need to adjust the src value as per the location of you JS file.