I am trying to get the next upcoming Time(In hours) from an array of times. The way it should work is it goes through the array of times (5:00, 10:00, etc.) and determines which will come next based on the current time. These times are in UTC.
Right now, what I've tried doing is making an array of dates on that day with those times. Depending on the time, however, this could produce an array of dates in which all of have already passed. To prevent this after checking to find the closest time, if the index is negative, it adds a day to every date in the array and then loops through it again.
Currently, my code just gives me the current time. Could anyone help me figure out how to make it work as described in the first paragraph?
My Current Code:
let dates = [new Date().setHours(5, 0, 0, 0), new Date().setHours(10, 0, 0, 0), new Date().setHours(15, 0, 0, 0), new Date().setHours(20, 0, 0, 0)]
let index = null;
for (var i = 0; i < dates.length; i++) {
if (!index || dates[i] - new Date() < index) {
index = dates[i] - new Date()
}
}
if (Math.sign(index) == -1) {
index = null;
for (var i = 0; i < dates.length; i++) {
dates[i] = dates[i] + 86400000;
}
for (var i = 0; i < dates.length; i++) {
if (!index || dates[i] - new Date() < index) {
index = dates[i] - new Date()
}
}
console.log(new Date(new Date() + index))
}
After some more research I was able to solve my question. There were many changes that needed to be made. The following code works as intented.
let dateObject = new Date();
let dates = [dateObject.setUTCHours(5, 0, 0, 0), dateObject.setUTCHours(10, 0, 0, 0), dateObject.setUTCHours(15, 0, 0, 0), dateObject.setUTCHours(20, 0, 0, 0)]
let nextDate = null;
// Get the current date and time in UTC
let now = new Date();
now.setUTCDate(now.getUTCDate());
now.setUTCHours(now.getUTCHours());
now.setUTCMinutes(now.getUTCMinutes());
now.setUTCSeconds(now.getUTCSeconds());
// Loop through the dates array
for (let date of dates) {
// Convert the date from a number to a Date object
date = new Date(date);
// If the date is later than the current date, log it and break out of the loop
if (date > now) {
nextDate = date;
break;
}
}
if (!nextDate) {
nextDate = new Date(dates[0] + 86400000);
}
console.log(nextDate);
Related
How can I achieve this sequence of date output if the user input is 04-29-2022 and the output is like this
What I want:
2022-05-14
2022-05-29
2022-06-14
2022-06-29
2022-07-14
2022-07-29
2022-08-14
2022-08-29
my code output
2022-05-13
2022-05-28
2022-06-12
2022-06-27
2022-07-12
2022-07-27
2022-08-11
2022-08-26
var dateRelease = new Date("04-29-2022")
const terms = 8
for (let i = 0; i < terms; i++) {
console.log(new Date(dateRelease.setDate(dateRelease.getDate() + 15)).toISOString().slice(0, 10))
}
Here is a function that takes the day of the month in the given date and determines which other date of the month would be needed in the output (either 15 more or 15 less). Then it generates dates alternating between those two date-of-the-month, and when it is the lesser of those two, incrementing the month. In case a date is invalid and automatically overflows into the next month, it is corrected to the last day of the intended month.
To format the date in the output, it is better to not use toISODateString as that interprets the date as a UTC Date, while new Date("2022-04-29") interprets the given string as a date in the local time zone. This can lead to surprises in some time zones. So I would suggest using toLocaleDateString with a locale that produces your desired format.
Here is the code:
function createSchedule(date, count) {
date = new Date(date);
let day = date.getDate();
let k = +(day > 15);
let days = k ? [day - 15, day] : [day, day + 15];
let result = [];
for (let i = 0; i < count; i++) {
k = 1 - k;
date.setDate(days[k]);
// When date overflows into next month, take last day of month
if (date.getDate() !== days[k]) date.setDate(0);
if (!k) date.setMonth(date.getMonth() + 1);
result.push(date.toLocaleDateString("en-SE"));
}
return result;
}
var dateRelease = new Date("2022-04-29");
var result = createSchedule(dateRelease, 25);
console.log(result);
var dateRelease = new Date("04-29-2022")
const terms = 8
for (let i = 0; i < terms; i++) {
let date = new Date(dateRelease.setDate(dateRelease.getDate() + 15)).toLocaleDateString('en-US');
let format = date.split('/').map(d => d.padStart(2 ,'0')).join('-')
console.log(format);
}
Sorry if this is a newbie question... I have this working correctly:
let date = new Date(2021, 0, 12);
dates = [];
for (let i = 0; i < 30; i++) {
date.setDate(date.getDate() + 1);
const dateString = date.toLocaleDateString();
dates.push(dateString);
}
console.log(dates);
All good. But without the new variable 'dateString', I see a funny behavior I don't quite understand. Initially I tried to do:
let date = new Date(2021, 0, 12);
let dates = [];
for (let i = 0; i < 30; i++) {
date.setDate(date.getDate() + 1);
date = date.toLocaleDateString(); // change same var instead of new var
dates.push(date);
}
console.log(dates);
This throws the following error: TypeError: date.getDate is not a function. Why should the behavior of the date object change in reverse?
Hi i have this script ( vue.js ) i can see the next 2 weeks works good i must change that i can see 2 weeks on the past ..
Thanks
methods: {
// Get all days without sunday:
dates(index) {
var week = new Array();
let current = new Date();
// Starting Monday not Sunday
current.setDate((current.getDate() - current.getDay() +1));
for (var i = 0; i < 13; i++) {
let date = new Date(current);
week.push(moment(date).format('DD.MM.YY'));
current.setDate(current.getDate() +1);
}
return week[index];
},
If you want to go back in time, you need to subtract from the current date:
methods: {
// Get all days without sunday:
dates(index) {
var week = new Array();
let current = new Date();
// Starting Monday not Sunday
current.setDate((current.getDate() - current.getDay() +1));
for (var i = 0; i < 13; i++) {
let date = new Date(current);
week.push(moment(date).format('DD.MM.YY'));
current.setDate(current.getDate() - 1); // <-- this line changed
}
return week[index];
},
Try this:
function dates(index) {
var week = new Array();
let current = moment().subtract(1, 'days');
for (var i = 0; i < 12; i++) {
week.push(current.format('DD.MM.YY'));
current = current.subtract(1, 'days')
}
console.log(week);
return week[index];
}
console.log(dates(2));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"></script>
Hello i am new to javascript , i tried a lot i cant get this format
yyyy-mm-ddT00:00:00, i want to get this format in java script to compare it with other dates in an array and then get the next valid date that will come .
also if some one can show me a function on how to compare and get the closest greater date than today .
datesarray = ['2017-12-09T00:00:00' ,'2017-12-13T00:00:00' ,'2017-12-02T00:00:00' ,'2017-12-16T00:00:00']
let diffDate = Infinity;
let now = Date.now;
for (let i = 0; i < datesarray.length; i++) {
let closest = datesarray[0];
if (closest > now && closest < diffDate)
{
diffDate = closest;
}
}
this is what i tried but its never getting into the if statement .
PS : i have other dates in an array but i did not show them here .
I think you have two separate questions here, to get an iso formatted date string you would use Date.prototype.toISOString(), but to compare dates and find the closest you would need to turn those strings into date objects and compare
let datesArray = ['2017-12-09T00:00:00' ,'2017-12-13T00:00:00' ,'2017-12-02T00:00:00' ,'2017-12-16T00:00:00'];
let diffDate = Infinity;
let now = Date.now();
for (let i = 0, len = datesArray.length; i < len; i++) {
let closest = new Date(datesArray[i]);
if (closest > now && closest < diffDate) {
diffDate = closest;
}
}
console.log(diffDate.toISOString());
Edit 1
In answer to your question, I can't duplicate your undefined problem using the code above, and to illustrate that diffDate is set correctly I moved it outside of the loop, if you run the snippet you should see the closest date print.
That being said, this might be a more concise way to handle your problem as long as modern JS syntax is workable for your issue.
const datesArray = ['2017-12-09T00:00:00' ,'2017-12-13T00:00:00' ,'2017-12-02T00:00:00' ,'2017-12-16T00:00:00'];
const dateCompare = (closest, current) => {
const t = new Date(current);
return (t > Date.now() && t < closest) ? t : closest;
}
let closest = datesArray.reduce(dateCompare, Infinity)
console.log(closest.toISOString());
Edit 2
To handle timezone precision problems if possible you want your date array to have dates in iso format 'yyyy-mm-ddThh:mm:ssZ' | '2017-12-02T00:00:00Z' if you can't edit your date array format you should make sure to append that 'Z' before creating your date: new Date(current + 'Z');
For your first question, use the ISOString() function of the Date object.
https://www.w3schools.com/jsref/jsref_toisostring.asp
For the next one, either create date object of each time, and then compare, or if you need to support equality check, convert all to milliseconds from the date object.
Use the Date() object. There are many different ways to enter the date. One is what you are using.
var dateArray = [new Date('2017-12-09T00:00:00'), new Date(2017, 11, 13), new Date(2017, 11, 2), new Date(2017, 11, 16)];
var today = new Date();
var closestDate = new Date(5000, 0, 0);
for (var i = 0; i < dateArray.length; i++) {
var curr = dateArray[i];
if(curr > today && curr < closestDate) {
closestDate = new Date(curr);
}
}
console.log(closestDate); // Prints Sat Dec 02 2017 00:00:00 GMT-0500 as of 10/19/2017
I'm trying to make a function to get all the days of the week given the current day. I had a function that i thought was working until i noticed that if the day of the week is near the end of the month, like for example February, i get weird data. Anyone know whats going on and how to fix it?
function days(current) {
var week = new Array();
// Starting Monday not Sunday
var first = ((current.getDate() - current.getDay()) + 1);
for (var i = 0; i < 7; i++) {
week.push(
new Date(current.setDate(first++))
);
}
return week;
}
var input = new Date(2017, 1, 27);
console.log('input: %s', input);
var result = days(input);
console.log(result.map(d => d.toString()));
.as-console-wrapper{min-height:100%}
If you don't want to use some kind of other library like Moment.js you can also change your function a little and then it will work. Try this:
function dates(current) {
var week= new Array();
// Starting Monday not Sunday
current.setDate((current.getDate() - current.getDay() +1));
for (var i = 0; i < 7; i++) {
week.push(
new Date(current)
);
current.setDate(current.getDate() +1);
}
return week;
}
console.log(dates(new Date(2017, 1, 27)));
You can use Moment.js library - utility library for dates/time operations
Here's examplary code to get current week's dates starting from monday:
function getThisWeekDates() {
var weekDates= [];
for (var i = 1; i <= 7; i++) {
weekDates.push(moment().day(i));
}
return weekDates;
}
var thisWeekDates = getThisWeekDates();
thisWeekDates.forEach(function(date){ console.log(date.format());});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.js"></script>
The code above prints following results to the console:
2017-03-20T21:26:27+01:00
2017-03-21T21:26:27+01:00
2017-03-22T21:26:27+01:00
2017-03-23T21:26:27+01:00
2017-03-24T21:26:27+01:00
2017-03-25T21:26:27+01:00
2017-03-26T21:26:27+02:00
I will trace your code using your example of Feb 27, 2017:
first = 27 - 1 + 1 = 27
loop:
Feb.setDate(27) = 27 feb
Feb.setDate(28) = 28 feb
Feb.setDate(29) = Not 29 days in Feb. So it sets current to 29-28 = 1st day of March
March.setDate(30) = March 30
March.setDate(31) = March 31
March.setDate(32) = Not 32 days in March. So it sets current to 31-32 = 1st of April..
April.setDate(33) = Not 33 days in April. So it sets current day 33-30 = 3rd day of May.
Please note that I used the shorthand of Month.setDate() to show the month of the current Date object when it was being called.
So the issue is with your understanding of setDate that is being used on current. It changes the month and if the value you use isn't a day in the month it adjusts the month and day appropriately. I hope this cleared things up for you.
For how to add one to a date, see Add +1 to current date. Adapted to your code, you can set current to the first day of the week then just keep adding 1 day and pushing copies to the array:
function days(current) {
var week = [];
// Starting Monday not Sunday
var first = current.getDate() - current.getDay() + 1;
current.setDate(first);
for (var i = 0; i < 7; i++) {
week.push(new Date(+current));
current.setDate(current.getDate()+1);
}
return week;
}
var input = new Date(2017, 1, 27);
console.log('input: %s', input);
var result = days(input);
console.log(result.map(d => d.toString()));
Note that this changes the date passed in (per the original code), you may want to make current a copy to avoid that.
Suppose monday starts the week, you can calculate monday and go to sunday. getDategives you the day of the week, and Sunday starts at 0. With momnday, we get just offset forward to 6 days to get sunday
mondayThisWeek(date: Date): Date {
const d = new Date(date)
const day = d.getDay()
const diff = d.getDate() - day + (day === 0 ? -6 : 1)
return new Date(d.setDate(diff))
}
const offsetDate = (base: Date, count: number): Date => {
const date = new Date(base)
date.setDate(base.getDate() + count)
return date
}
thisWeek(today: Date): TimeRange {
const monday = mondayThisWeek(today)
return {
startDate: monday,
endDate: offsetDate(monday, 6)
}
}
This can be achieved easly using moment
const getWeekDates = () => {
let weekDates = [];
for (let i = 0; i < 7; i++)
weekDates.push(moment().add(i, 'd'));
return weekDates;
};
console.log(getWeekDates());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.js"></script>