I have an array of time objects created like this:
let event = new Date()
These events are created overtime, for example:
first event created*
2 seconds later another event created
5 seconds later another event
3 seconds later another is created etc...
So each time object has the corresponding time at which it was created.
The events where obviously created in the past, and there is afirst event.
and they are all stored in an array like: [event1, event2, event3...]
The events are the object the function new Date() returns.
How can I shift all these events so that they start in the future?
By the future I mean for example whenever an event is executed, a click etc...
How can i shift their time equally to that all events go in the same order, but start in the future.
Is like a recording, being played back.
Thanks
While Date handling is one of the pretty bad parts of JS1, this short of shifting is relatively simple. We just calculate new timestamps based on the difference between the first date in the list and the current one, and add that difference to our new start time, then create a Date from that timestamp:
const shiftEvents = (start, events) =>
events .map (e => new Date (e - events[0] + start .getTime ()))
const events = [new Date ('2022-03-09T22:51:03.507'), new Date ('2022-03-09T22:51:05.492'), new Date ('2022-03-09T22:51:10.604'), new Date ('2022-03-09T22:51:13.551')]
console .log (shiftEvents (new Date ('2022-03-16T22:59:18.219'), events))
1 There is something better on the horizon in the Temporal proposal.
var events = [...];
var firstEvent = events[0];
var now = new Date();
var oldestEventAge = now.getTime() - firstEvent.getTime();
var hour = 1000 * 60 * 60;
for (let e of events) {
e.setTime(e.getTime() + oldestEventAge + hour);
}
Here we get the first event and calculate how many milliseconds have occurred between now and it. i.e. how old is it.
Then we define 1 hour in milliseconds. This is how far we are pushing the first event into the future.
Then for each event we add to its current time in milliseconds the age of the oldest event plus one hour.
This will result in the oldest event being 1 hour in the future and all subsequent events being the same distance from the oldest event and also in the future.
Obviously change the value of hour to be however far you want the first event to be in the future.
Related
I am creating a countdown for an event and the server gives me the number of seconds left till this event. It works fine in the same time zone America/New_York but I am not sure how to achieve this for a different time zone. I guess I have to add/subtract a number of seconds based on user't time zone. I am taking into account that the number of seconds returned by the server will always be in EST. Can someone advise?
So far I have this but I'm getting an error:
let serverZoneTime = new moment().tz.zone("America/New_York").offset(now);
let currentZoneTime = moment.tz.guess().offset(now);
console.log((EstTzOffset - currentTz));
First of all, if this is an event at 6pm on a certain day I would get the exact timestamp or UTC time for that event start time. Below I'm using a fake timestamp.
This is important because the people viewing your event could change from EST to DST between "now" (which you are using above) and 6pm on the event day.
It sounds like you already have the countdown working but it is just the timezone issues you are dealing with so I'll skip the countdown logic.
const moment = require('moment-timezone');
// Get User's Timezone
const userTimezone = moment.tz.guess(); // this has to be on the client not server
const serverTimezone = "America/New_York";
// Get the exact timestamp of the event date apply the server timezone to it.
const serverEventTime = moment(34534534534, 'x').tz(serverTimezone);
// Take the server time and convert it to the users time
const userEventTime = serverEventTime.clone().tz(userTimezone);
// From here you can format the time however you want
const formattedUserEventTime = userEventTime.format('YYYY-MM-DD HH:mm:ss');
// Or format to a timestamp
const userEventTimestamp = userEventTime.format('x');
For a countdown you'll want the time now as well, which follows the same logic as above:
const serverTimeNow = moment().tz(serverTimezone);
const userTimeNow = serverTimeNow.clone().tz(userTimezone);
// Get timestamp so we can do easier math with the time
const userNowTimestamp = userTimeNow.format('x');
Now all we have to do is subtract now time from the event time to get the difference and repeat every second using a setInterval() perhaps.
const millisecondsToEvent = userEventTimestamp - userNowtimestamp;
const secondsToEvent = millisecondsToEvent / 1000;
Hopefully that's useful to someone (just realized that this was two years old).
I don't know JavaScript (I know a little Java) but I want to write a simple script that deletes my school classes events when there is a vacation event but it simply doesn't work... What is the problem?
function vacations()
{
var school_calendar = CalendarApp.getCalendarsByName("Timetable")[0].getEvents(new Date("September 1, 2016"),new Date("June 20, 2017"));
var vacations = CalendarApp.getCalendarsByName("Vacations")[0].getEvents(new Date("September 1, 2016"),new Date("June 20, 2017"));
for (var i = 0; i < vacations.length; i++)
{
var vacation = vacations[i];
for (var j = 0; j < school_calendar.length; j++)
{
var school_class = school_calendar[j];
if(vacation.getAllDayStartDate() == school_class.getStartTime())
{
school_class.deleteEvent();
}
}
}
}
Comparing a Date vacation.getAllDayStartDate()with a Date school_class.getStartTime() can work if you compare them like:
vacation.getAllDayStartDate().getTime() === school_class.getStartTime().getTime()
However, one contains a date with a time set at midnight:
getAllDayStartDate()
Gets the date on which this all-day calendar event begins. (If this is
not an all-day event, then this method will throw an exception.) The
returned Date will represent midnight at the beginning of the day on
which the event starts in the script's time zone. To use the
calendar's time zone instead, call getStartTime().
And the other contains a date and time:
getStartTime()
Gets the date and time at which this calendar event begins. For
non–all-day events, this will be the instant in time at which the
event was defined to start. For all-day events, which only store a
start date (not a date and time), this will be midnight at the
beginning of the day on which the event starts in the calendar's time
zone. This allows meaningful comparison of start times for all types
of events; however, it will not necessarily preserve the original
day-of-year unmodified.
For all-day events, getAllDayStartDate() should almost always be
called in preference to this method.
Make sure you compare the right formats, and use the debugger or Logger to see what is going in in the code.
I have a function and it represent a date that is 2 weeks off from start date, counted by each passing Thursday, but excludes the Thursday of the week the date was made.
function GetThursdayIn2Weeks(date)
{
var day = date.getDay();
// Add 2 weeks.
var newDate = new Date(date.setTime(date.getTime() + (14 * 86400000)));
// Adjust for Thursday.
var adjust = 4 - day;
if (adjust <= 0) // Might need to be changed - See comments!
adjust +=7;
// Apply Thursday adjustment.
newDate = new Date(newDate.setTime(newDate.getTime() + (adjust * 86400000)));
return newDate;
}
How would I make this set off a different function every day that passed, starting a week after the beginning of the process, remind me about the due date coming up, but before the end of the date of the process?
You can use setTimeout() to execute a reminder after a set time. However, the problem is that your javascript environment will probably not keep running for such long times, be it node.js or your browser.
I would suggest those mechanisms :
store your target date in localstorage after calculating it with your given code
define a function that will use setTimeout() to define the next occurrence of the reminder for a given target date
when the page is loaded, use that function for each date stored in the localstorage
when a date is added to the localstorage, or a given target date reachs one of its reminders, call the function for this specific date
The mentioned function should set a timer for the first day that is at the same time greater than the current date, greater than the day 1 week before the target date, and lower than the target date.
Here is an 'hopefully) working JSFiddle.
I have a function that I want to call within a random range in Node. So, for instance, I would like it to be executed once between 2 and 12 hours, then again once between 2 and 12 hours, and so on. However, this interval should not be fixed, so I need that interval to be recalculated at the end of every call.
If possible, I'd also like to limit the days of the week that this can execute, so not on Saturdays and Sundays as an example.
I've tried looking into later.js, which does the second part very well, but I can't seem to find a way to incrementally randomize the interval. Does anyone know how to accomplish this?
I must admit to not being an later.js expert but isn't custom time periods what you are after?
At the end of the cycle,
Use new Date(y, m, d, h) constructor to construct the first applicable time and last applicable time (use now = new Date(); y = now.getYear(); ... to extract the components you will need
Convert them to timestamps
Generate random integer between the two timestamps
setTimeout(process, new Date(randomTimestamp - new Date())
I need to use JavaScript to display the next event on a recurring weekly basis on a website. Let's say we start an event every 10am every Saturday - I'll need it to display that the next event begins on "Saturday, (Month) (Date) at 10am".
The only thing that I need to be dynamic on the website is the date of the next event (both month and date).
Idea 1: One way I started thinking about it I would need to and have some sort of a starting reference calendar date from where the schedule starts, and then some pattern of n-days to calculate the upcoming dates from that starting point and compare those against todays date, then display the result of the next in the sequence
Idea 2: Instead of using a pattern of N-days to calculate from a hard-coded reference point, what if I coded the day of the week the event occurs and check against that, calculating the date by comparing the days of the week and adding to todays date (would have to account for rollovers at 28/30/31 days and a way to account for which months max out at which number)
Maybe I'm way off-base in my thinking, but any help here would be appreciated. I'm learning JavaScript and coming from an HTML+CSS background using jQuery plugins if that helps frame your answer in a way I'll grasp.
Here is a rough solution that may work. It's just general code that you will need to debug but I think it's a good starting point! Date() is a built-in JavaScript object.
var today = new Date();
//var dd = today.getDate(); *just some sample functions of Date()*
//var mm = today.getMonth()+1; *January is 0!*
if(today.getDay() == 6) alert('it is saturday');
// today.getDate() < 8 *this can be used to check where in the month a day falls
// if you want only first, second, third, etc., Saturday
Please let me know if this helps at all!
You could use rSchedule for this (a javascript recurrence library which I maintain).
Example:
Let's say we start an event every 10am every Saturday
import { Schedule } from '#rschedule/rschedule';
import { StandardDateAdapter } from '#rschedule/standard-date-adapter';
const schedule = new Schedule({
rrules: [{
frequency: 'WEEKLY',
// the hypothetical start datetime of your recurring event
start: new Date(2019, 5, 15, 10),
}],
dateAdapter: StandardDateAdapter,
});
The only thing that I need to be dynamic on the website is the date of the next event (both month and date).
// get standard javascript iterator for occurrences starting after now
const iterator = schedule.occurrences({
start: new Date()
})
// the next date
const nextDate = iterator.next().value;
// or iterate over all future occurrences
for (const date of iterator) {
// do stuff...
}