How to display one item in an array each week - javascript

I am trying to create a memory verse a week program. I have code to display the item, but only with a delay for however long I want the code to wait before it changes items. How can I display one item at a time in an array for one week then go on to the next item without waiting a week for the delay? This is what I have now:
<p id="wfm"></p>
var mind = [];
var i = 0;
var wfmind = document.getElementById('wfm');
function next_verse() {
wfmind.innerHTML = mind[i % mind.length];
i += 1;
}
setInterval(next_verse, 1000);

You could use the current time as the index, which counts from 1970 rather than the arbitrary time the user entered the site.
As of writing, the current timestamp is 1493684749486.
var d = new Date();
// +d === 1493684749486
To convert the current timestamp into an array index, you need to know the number of milliseconds in a week (1000*60*60*24*7), then figure out how many weeks have passed since 1970.
var index = Math.floor(+d / (1000*60*60*24*7));
// 2469 weeks have passed since 1970
// output `mind[index]` now.
For the sake of the answer here, I'm going to assume you want to change the item on Friday at 9am. The next closest Friday at 9am is 1494000000000.
d.setMilliseconds(0);
d.setSeconds(0);
d.setMinutes(0);
d.setHours(9);
d.setDate(d.getDate() + (7 + 5 - d.getDay()) % 7); // How many days away is Friday from Monday? Add that to the current date.
That is 315250514 milliseconds away. You'll setTimeout this long to kick off the next change.
When the item changes, kick off a new timeout for the following change. This is preferred over setInterval.
function displayNextItem() {
var d = new Date();
var timestamp = +d;
var index = Math.floor(timestamp / (1000*60*60*24*7));
wfmind.innerHTML = mind[index % mind.length];
d.setMilliseconds(0);
d.setSeconds(0);
d.setMinutes(0);
d.setHours(9);
d.setDate(d.getDate() + (7 + 5 - d.getDay()) % 7); // How many days away is Friday from Monday? Add that to the current date.
setTimeout(displayNextItem, +d - timestamp);
}
displayNextItem();

Related

How to determine if a Date is next week in Javascript?

What is a quick way to determine if a certain date:
is next week
is last week
is this week
etc
I am open to using Date, Moment, Date-fns, or Dayjs if any of those have a built-in method.
As of now, I am thinking of using getDay() and comparing if the date is not too far ahead and not too near to today.
Thanks,
This example is assuming you're defining "next week" as "7-14 days in the future", but you could tweak this answer to do whatever you want. This answer is intended to help understand how to perform this sort of operation on javascript Dates, not just this operation specifically.
Option 1: Determine how many days are between the target date and the current date by subtracting the current date from the target date
// store current date as "today"
var today = new Date();
// store 8 days from today as "later"
later = new Date();
later.setDate(later.getDate() + 8);
// Determine how many days are between the two dates by subtracting "today" from "later" and converting milliseconds to days
days = (later - today) / (1000 * 3600 * 24);
// Is "later" 7-14 days away?
console.log(days > 7 && days < 14); // true
Option 2: Store the start and end date and compare those to our target date
// store 8 days from today as "later"
later = new Date();
later.setDate(later.getDate() + 8);
// Store the start date
start = new Date();
start.setDate(start.getDate() + 7);
// Store the end date
end = new Date();
end.setDate(end.getDate() + 14);
// is "later" between the start and end date?
console.log(later > start && later < end); // true
One algorithm is to take both dates back to the start of the week, then get the number of weeks between the two, e.g.
// Get start of week (previous or current Monday)
function getWeekStart(d = new Date()) {
return new Date(d.getFullYear(), d.getMonth(), d.getDate() - (d.getDay() || 7) + 1);
}
// Get relative weeks difference
function getRelativeWeek(d = new Date()) {
let thisWeek = getWeekStart();
let targetWeek = getWeekStart(d);
let diffWeeks = Math.round((targetWeek - thisWeek) / (8.64e7*7));
// Convert to words
switch (true) {
case (diffWeeks < -1):
return Math.abs(diffWeeks) + ' weeks ago';
case (diffWeeks == -1):
return 'last week';
case (diffWeeks == 0):
return 'this week';
case (diffWeeks == 1):
return 'next week';
case (diffWeeks > 1):
return diffWeeks + ' weeks away';
default :
return 'dunno';
}
}
// Examples
let d = new Date();
// Current week
[new Date(+d - 25*8.64e7),
new Date(+d - 7*8.64e7),
d,
new Date(+d + 7*8.64e7),
new Date(+d + 25*8.64e7),
new Date(NaN)
].forEach(d => console.log(
d.toDateString() + ': ' + getRelativeWeek(d)
));
Note that 8.64e7*7 is approximately the number of milliseconds in a week. It may be ±3.6e6 depending on whether the week has a daylight saving boundary or not, which will cause a non–integer result after division. Rounding fixes that.

Create date object and compare to todays date

I have an object containing time. For example x.time = 10:20:00.
I want to take the current time minus my objects time.
This is my code so far, but i get the error message ="Invalid Date":
for(var i = 0; i<x.length; i++){
nowDate = new Date();
minutesLeft = new Date(nowDate.getFullYear(), nowDate.getMonth(), nowDate.getDate() + x[i].time);
text +- "It is "+ minutesLeft[i] + " milliseconds left";
}
In order to convert your time property into a date object you can do:
var timepieces = x.time.split(':');
var date = new Date();
date.setHours(timepieces[0]);
date.setMinutes(timepieces[1]);
date.setSeconds(timepieces[2]);
Then you can directly compare the two dates by using the getTime() method of the Date object.
nowDate.getTime() === date.getTime()
nowDate.getTime() > date.getTime()
nowDate.getTime() < date.getTime()
You can also get the difference of two dates in milliseconds:
var milliseconds = nowDate.getTime() - date.getTime();
There are a bunch of problems with your code. I'll go through and hopefully catch everything.
Use var to declare your variables inside your loop. (further reading)
When you create the variable minutesLeft you are doing a bit of weird concatenation. You told us that x.time is a string such as "10:20:00" but you are (string) concatenating that with Date.prototype.getDate which returns a number in the range 1-31 (representing the day of the month). You are essentially doing this:
minutesLeft = new Date(2017,0,1910:20:00);
Which I hope you see will not create a new date. You perhaps wanted something along the lines of
minutesLeft = new Date(2017,0,19, 10, 20, 0);
Which should give you what you want (todays date set to the appropriate time defined by x.time.
text +- does not make any sense. I suspect a typo, you meant text += which will append the value on the right to the variable text. Or, perhaps text = which will assign the value, replacing what was there
"It is "+ minutesLeft[i] + " milliseconds left" using minutesLeft[i] will take a single character from a string (or an item from an array, if the value is an array). Yours is just a date object, and is not an array, so I suspect you just meant to leave off the [i] part altogether.
If you're trying to get the difference between the current date/time and your selected date/time you need to do some arithmetic with nowDate and minutesLeft. I'm assuming this is a difference you're after.
var x = [{time:"10:20:20"}];
var text = "";
for(var i = 0; i<x.length; i++){
var nowDate = new Date();
var timeSplit = x[i].time.split(":");
var minutesLeft = new Date(nowDate.getFullYear(), nowDate.getMonth(), nowDate.getDate());
minutesLeft.setHours(timeSplit[0]);
minutesLeft.setMinutes(timeSplit[1]);
minutesLeft.setSeconds(timeSplit[2]);
text += "It is "+ (nowDate-minutesLeft) + " milliseconds left";
}
console.log(text);
For example x.time = 10:20:00. I want to take the current time minus my objects time.
Your code seems quite confused, it seems you're trying to do the following:
var time = '10:20:00';
var timeParts = time.split(':');
var now = new Date();
// Current date and time
console.log(now.toString());
// Subtract the hours part of the time from the hours part of the current time
now.setHours(now.getHours() - timeParts[0]);
// Subtract the minutes part of the time from the minutes part of the current time
now.setMinutes(now.getMinutes() - timeParts[1]);
// Subtract the seconds part of the time from the seconds part of the current time
now.setSeconds(now.getSeconds() - timeParts[2]);
// Adjusted date and time
console.log(now.toString());
// You can set the time parts all in one go:
var now2 = new Date();
now2.setHours(now2.getHours() - timeParts[0],
now2.getMinutes() - timeParts[1],
now2.getSeconds() - timeParts[2]);
console.log(now2.toString());
Lastly, copying a date is as simple as:
var date1 = new Date();
var date2 = new Date(date1);

How to loop through the remaining days of the year and look for certain dates in javascript?

I have 3 people's birthdays:
Steve -> May 3
Mark -> October 20
Robbin -> December 5
How to loop through the remaining days of the year and find which person still has a birthday coming (IN THIS CASE output MARK AND ROBBIN)?
I've been able to get the remaing days of the year, but I'm not sure how to loop through the remaing days of the year
and output those people's names (the ones that will have bithdays in the next months).
This is what I have done so far:
I created a funtion to get the remaming days:
function remainingDays(date1, date2) {
// The number of milliseconds in one day
var ONE_DAY = 1000 * 60 * 60 * 24
var date1_ms = date1.getTime()
var date2_ms = date2.getTime()
var difference_ms = Math.abs(date1_ms - date2_ms)
// Convert back to days and return
return Math.round(difference_ms/ONE_DAY)
}
As you can see the function returns the number of days left. And here's the values:
var current_date = new Date()
// Store the date of the next New Year's Day
var new_years_date = new Date()
new_years_date.setYear(new_years_date.getFullYear() + 1)
new_years_date.setMonth(0)
new_years_date.setDate(1)
// Call the remainingDays function
var days_left = remainingDays(current_date, new_years_date);
if (days_left > 1) {
document.write(days_left + " days left this year")
} else {
document.write(days_left + " day left this year")
}
Please help me....Thank you in advanced!!
What about something like this? (see the jsfiddle):
var birthdays = [
{
name: 'Mark',
date: 'October 20'
},
{
name: 'Robbin',
date: 'December 5'
}
];
var upcoming = birthdays.filter(function(person) {
var date = new Date(person.date + ' 2015');
// returns a boolean "true" or "false"
return date > new Date();
});
console.log(upcoming);
It simply filters the current birthdays into a new array, upcoming, if the birthday is greater than today's date. No need to overcomplicate it.
You could make it more semantic and extensible if you so desire:
var upcoming = birthdays.filter(afterToday);
function afterToday(person) {
return new Date(person.date + ' 2015') > new Date();
}
One of the key paradigms of programming is that simpler is better. Many algorithms can do the same thing (end up with the same results), but usually the simpler algorithm is better, all else being equal.
In other words:
The algorithm can loop through every single date remaining in the year, or
The algorithm can simply check if the date is greater than today
I think the second is simpler. Also, less lines of code, and more readable.
You can set a variable for each person and check if his birthday is coming up
var Mark = new Date(2015, 9, 20);
var now = new Date()
if(Mark > now){
doSomething()
}
Don't loop,
calculate julian date (julian date of a date is the order number of the day in the year, 32 for example is the julian date of 1st of February, see https://en.wikipedia.org/wiki/Julian_day)
Calculating Jday(Julian Day) in javascript
http://javascript.about.com/library/bljuldate.htm
Then see if current julian day is bigger or smaller than any of the birthday julian days

subtracting one time from another

I have had a good search for what I'm looking for but can't seem to find exactly what I need. I'm new to jQuery and JavaScript.
All I want to do is subtract one 24 hour clock time from another to find how many hours have been allocated using JQuery or JavaScript i.e. start time: 12:00 end time: 16:00 would be 4 hours.
How would I go about doing this without having issues when going from say 12:00 till 12:00 the following day?
I am not dealing with with dates, just time.
Currently the times are stored like this as part of an object with start_time end_time:
var shift = {'location':$('#shift_location').val(),
'shift_date': $('#shift_date').val(),
'start_time':$('#shift_start_time').val(),
'end_time':$('#shift_end_time').val()
};
var shift_list = JSON.parse(localStorage.shift);
shift_list.push(shift);
localStorage.shift = JSON.stringify(shift_list);
With the given information i.e start_time and end_time there is no way you can cover multiple days. They just oscillate between 0 to 23 hours. There is no counter involved to calculate multiple days. if you need that you need two more states which will store start_date and end_date which will act as counter as pointed by #John Boker. But if you are sure that the difference never goes beyond 24 hours then we can use the parseTime from JAVASCRIPT: subtracting Time and getting its number of minutes function with our own little modifications.
function parseTime(s) {
var c = s.split(':');
return parseInt(c[0]) * 60 + parseInt(c[1]);
}
var limit = parseTime("23:59");
function getDiff(start_time, end_time){
var a = parseTime(start_time), b = parseTime(end_time);
if(b < a) // means its the next day.
return Math.round((limit - a + b)/60);
else if(b > a)
return Math.round((b - a)/60);
else if(b - a == 0)
return 24.0;
else
alert("Invalid data");
}
alert(getDiff("12:00", "11:00"));
You can use momentjs to do things with dates in javascript.
Example (moment doc, fiddle):
var start_time = "12:00";
var end_time = "16:00";
var start = moment.duration(start_time, 'h');
var end = moment.duration(end_time, 'h');
alert(end.subtract(start).hours()); // 4
Of course, because of the simplicity of the task you could always use plain javascript:
var start_time = "12:00";
var end_time = "16:00";
alert(parseInt(end_time, 10) - parseInt(start_time, 10)); // 4

Javascript repeating days counter

I need a JavaScript function that returns the number of days remaining from a particular date of every year.
I found the following code, but how can I make it repeatable for every year, instead of changing the year in the function manually?
function daysUntil(year, month, day) {
var now = new Date(),
dateEnd = new Date(year, month - 1, day), // months are zero-based
days = (dateEnd - now) / 1000/60/60/24; // convert milliseconds to days
return Math.round(days);
}
daysUntil(2013, 10, 26);
I think my question above is not clear enough, i need to show days remaining in 26th October. So this starts again every year on 27th October. I don't need a loop for that.
"how can i make it repeatable for every year, instead of changing the year in function manually?"
Well you can't do literally every year to infinity, but you can easily add a loop to get a specific range of years:
var d;
for (var y = 2013; y < 2099; y++) {
d = daysUntil(y, 10, 26);
// do something with d, e.g.,
console.log(d);
}
UPDATE: You added this detail to your question:
"I think my question above is not clear enough, i need to show days remaining in 26th October. So this starts again every year on 27th October. I don't need a loop for that."
OK, that's still not very clear, but I think you're saying that your input would be just the day and month and you want to calculate the number of days until the next time that day/month rolls around, e.g., the number of days until your next birthday. If so, perhaps something like this:
function daysUntil(month, day) {
var now = new Date(),
currentYear = now.getFullYear(),
dateEnd = new Date(currentYear, month - 1, day); // months are zero-based
if (dateEnd - now < 0) // have we already passed that date this year?
dateEnd.setFullYear(currentYear + 1);
return Math.ceil((dateEnd - now) / 1000/60/60/24);
}
console.log(daysUntil(10,11)); // 365 - results from today, Oct 11
console.log(daysUntil(10,26)); // 15
console.log(daysUntil(7,7)); // 269

Categories