Check if Date is in Range - javascript

I have a date range suppose 2000-01-01 to 2021-06-01. I want to check whether a particular month with a given year falls in this range or not (E.g., month = March and year = 2021) using JavaScript.

Create a reusable function isDateInRange that accepts your three date Strings arguments.
Than you can simply compare your Date Objects using the needed operands:
const isDateInRange = (date, from, to) => {
const d = new Date(date);
const f = new Date(from);
const t = new Date(to);
return (d >= f && d < t);
};
console.log(isDateInRange("2001-01-31", "2000-01-01", "2021-06-01")) // true
console.log(isDateInRange("2050-01-01", "2000-01-01", "2021-06-01")) // false

Here is a solution passing month and year (not a date) as you requested.
const lowerRange = new Date('2000-01-01');
const upperRange = new Date('2021-06-01');
// If month and year are numbers
const monthYearInRange = (year, month) => {
if (typeof month !== 'number') throw new Error('Month should be number');
if (typeof year !== 'number') throw new Error('Year should be number');
// We do this to make sure it is 2 chars.
const mth = month < 10 ? `0${month}` : month;
// Set it to first of the month
const checkVal = new Date(`${year}-${mth}-01`);
if (isNaN(checkVal)) throw new Error(`Year: ${year} and Month: ${month} are not valid.`);
return checkVal <= upperRange && checkVal >= lowerRange;
}
console.log(monthYearInRange(2000, 2)); // true
console.log(monthYearInRange(2030, 2)); // false
console.log(monthYearInRange(2021, 6)); // true
console.log(monthYearInRange(2021, 10)); // false
Just a note on this solution - because ultimately we convert the year/month into a date, when doing this we have to instantiate the date using the ISO format YYYY-MM-DD. If checkVal gets instantiated with a month that is a single character (1 instead of 01) it will still work in most cases - but you will get edge cases breaking because the Date() constructor will add timezone values to the date.
Update: Added NaN check - per #RobG

I tried the following approach and it worked:
function isBetween(n, a, b) {
return (n - a) * (n - b) <= 0
}
var startDate = '2021-03-15';
var endDate = '2021-06-01';
var checkFor = '2021-05-31';
D_1 = startDate.split("-");
D_2 = endDate.split("-");
D_3 = checkFor.split("-");
//console.log(D_1+" "+D_2+" "+D_3);
var startNumber = D_1[0]*100 + D_1[1];
var endNumber = D_2[0]*100 + D_2[1];
var checkNumber = D_3[0]*100 + D_3[1];
var check = isBetween(checkNumber, startNumber, endNumber);
console.log(check);

Related

Getting date range based on date and hour

I am trying to get individual dates ("2022-10-10") and hours ("2022-10-10T09") between an interval in UTC. I could get the individual dates by the following -
function getDatesInRange(startDate, endDate) {
const date = new Date(startDate.getTime());
const dates = [];
while (date <= endDate) {
const day = new Date(date).toISOString().split(':')[0].split('T')[0];
dates.push(day);
date.setDate(date.getDate() + 1);
}
return dates;
}
console.log(getDatesInRange(new Date('2022-10-10T20:50:59.938Z'), new Date('2022-10-15T23:50:59.938Z')));
Hence, the above returns - ["2022-10-10", "2022-10-11", "2022-10-12", "2022-10-13", "2022-10-14", "2022-10-15"]
I also want to return the hours of the start and end date and the rest should be dates. So i want to get in return - ["2022-10-10T20", "2022-10-10T21", "2022-10-10T22", "2022-10-10T23" "2022-10-11", "2022-10-12", "2022-10-13", "2022-10-14", "2022-10-15T00", "2022-10-15T01"]
Here is what i have as of now -
function getHoursInRange(startDate, endDate) {
let startDatePlusOne = new Date(startDate);
startDatePlusOne.setDate(startDatePlusOne.getDate() + 1);
let endDateMinusOne = new Date(endDate);
endDateMinusOne.setDate(endDateMinusOne.getDate() - 1);
const date = new Date(startDate.getTime());
console.log("Start date :", date);
let dates = getDatesInRange(startDatePlusOne, endDateMinusOne);
console.log("Only days : ", dates);
startDatePlusOne.setHours(0);
while (date < startDatePlusOne) {
const day = new Date(date).toISOString().split(':')[0];
dates.push(day);
date.setHours(date.getHours() + 1);
}
endDateMinusOne.setHours(23);
const edate = endDateMinusOne.getTime();
while (edate < endDate) {
const day = new Date(edate).toISOString().split(':')[0];
dates.push(day);
date.setHours(date.getHours() + 1);
}
return dates
}
For this use case, i am getting the days back excluding the start and end dates. But for getting each hour of start and end date it gets stuck somehow. Somehow i feel there is a better way to do this. Any ideas ?
You can do it a simpler way by incrementing the timestamp by 30 minutes at a time, and keeping a note of all non-duplicate hour strings and date strings:
function getDatesInRange(startDate, endDate) {
let h = new Set(), d = new Set(), t = [];
for(let i=startDate.getTime(); i<endDate.getTime(); i+=1000*1800) t.push(i);
[...t, endDate.getTime()].forEach(i=>{
let s = new Date(i).toISOString();
[[s.split(':')[0], h], [s.split('T')[0], d]].forEach(([s,r])=>r.add(s));
});
let firstDate = [...d.values()][0], lastDate = [...d.values()].pop();
return d.size===1 ? [...h.values()] : [
...[...h.values()].filter(v=>v.startsWith(firstDate)),
...[...d.values()].filter(v=>v!==firstDate && v!==lastDate),
...[...h.values()].filter(v=>v.startsWith(lastDate))];
}
console.log(getDatesInRange(
new Date('2022-10-10T20:50:59.938Z'), new Date('2022-10-15T23:50:59.938Z')));
dateRange constructs an array of Date objects corresponding to the supplied range, inclusive.
dayToString takes a date and creates an array of strings, one for each hour of the day between the specified UTC hour range, inclusive.
dateRangeToStrings accepts an array of dates and constructs an array of strings according to the rules laid-out in the question.
const twoDigit = (n) => String(n).padStart(2, '0')
const toISODateString = (date) => `${date.getUTCFullYear()}-${twoDigit(date.getUTCMonth() + 1)}-${twoDigit(date.getUTCDate())}`
const dateRange = (start, end, curr = new Date(start)) => {
const dates = []
while (curr <= end) {
dates.push(new Date(Date.UTC(curr.getUTCFullYear(), curr.getUTCMonth(), curr.getUTCDate())))
curr.setUTCDate(curr.getUTCDate() + 1)
}
return dates
}
const dayToString = (date, startUTCHour = 0, endUTCHour = 23) =>
Object.keys([...Array(24)])
.slice(startUTCHour, endUTCHour + 1)
.map((h)=>`${toISODateString(date)}T${twoDigit(h)}`)
const dateRangeToStrings = (arr, startUTCHour, endUTCHour) => {
const beginning = dayToString(arr[0], startUTCHour)
const middle = arr.slice(1, -1).map(toISODateString)
const end = dayToString(arr[arr.length - 1], 0, endUTCHour)
return beginning.concat(middle, end)
}
const getDatesInRange = (start, end) =>
dateRangeToStrings(dateRange(start, end),
start.getUTCHours(),
end.getUTCHours())
console.log(getDatesInRange(new Date('2022-10-10T20:50:59.938Z'),
new Date('2022-10-15T23:50:59.938Z')))

How to compare javascript dates (strings) with a specific format

I have two dates in a specific format (strings). I need to verify if the current date is lower than the max allowed date:
var date_current = '03_25_2022';
var date_max = '03_30_2022';
The format will always be m_d_Y. Since these are technically strings, what would be the best way to compare them as dates?
I'm using this function but I'm not sure of the approach:
function compareDates(d1, d2){
var parts = d1.split('_');
var d1 = Number(parts[1] + parts[2] + parts[0]);
parts = d2.split('_');
var d2 = Number(parts[1] + parts[2] + parts[0]);
return d1 <= d2;
}
You can first convert these string into date object and then compare their timestamp as follow:
function strToDate(str) {
const splits = str.split('_');
if (splits.length !== 3) {
throw Error("Invalid date");
}
return new Date(splits[2], parseInt(splits[0]) - 1, splits[1]);
}
let dateCurrent = strToDate('03_25_2022');
let dateMax = strToDate('03_30_2022');
console.log(dateMax.getTime() > dateCurrent.getTime())

Check if date/time is BETWEEN two other date/times Javascript

var startDateTime = '15.04.2019 00:15';
var endDateTime = '17.05.2019 18:35';
var checkDateTime = '16.04.2019 13:15';
function(checkDateTime, startDateTime, endDateTime) {
// need codes to return true or false,.
// check "checkDateTime" is between "startDateTime" to "endDateTime"
}
Try this code:
var startDateTime = getDate('15.04.2019 00:15');
var endDateTime = getDate('17.05.2019 18:35');
var checkDateTime = getDate('16.04.2019 13:15');
function isBetween(checkDateTime, startDateTime, endDateTime) {
return (checkDateTime >= startDateTime && checkDateTime <= endDateTime);
}
function toDate(str){
var [ dd, MM, yyyy, hh, mm ] = str.split(/[. :]/g);
return new Date(`${MM}/${dd}/${yyyy} ${hh}:${mm}`);
}
console.log(isBetween(checkDate,startDate,endDate));
To compare it one time falls between a time interval on the same day use: -
var startTime = "00:35";
var endTime = "18:15";
var checkTime = "13:00";
function getMinutes(timeString){
let [hh, mm] = timeString.split(":");
return parseInt(hh)*60 + parseInt(mm);
}
function isTimeBetween(checkTime,startTime,endTime){
checkTime = getMinutes(checkTime);
return (checkTime >= getMinutes(startTime) && checkTime <= getMinutes(endTime));
}
console.log(isTimeBetween(checkTime,startTime,endTime));
You can use new Date().getTime() to get the number of milliseconds since the Unix Epoch. So that you can compared the date/time with the result from this function. You can do sth like that:
return new Date(startDateTime).getTime() <= new Date(checkDateTime).getTime() <= new Date(endDateTime).getTime();
Check this out:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTime
I would suggest to check if your checkDateTime is greater than your startDateTime and less then endDateTime.
function checkDateTime(checkDateTime, startDateTime, endDateTime) {
return (new Date(startDateTime) >= new Date(checkDateTime))
&& (new Date(checkDateTime) <= new Date(endDateTime));
}
Here is yet another option which adds the method directly to the Date prototype:
var startDateTime = new Date('04/15/2019 00:15');
var endDateTime = new Date('05/17/2019 18:35');
var checkDateTime = new Date('04/16/2019 13:15');
var outOfRangeDate_EARLY = new Date('01/16/2019 13:15');
var outOfRangeDate_LATE = new Date('06/16/2019 13:15');
Date.prototype.inRange = function(startDate, endDate){
var this_ms = this.getTime();
return ( this_ms >= startDate.getTime() && this_ms <= endDate.getTime() )
}
/* Tests */
console.log('expected: true', 'actual:', checkDateTime.inRange(startDateTime, endDateTime))
console.log('expected: false', 'actual:', outOfRangeDate_EARLY.inRange(startDateTime, endDateTime))
console.log('expected: false', 'actual:', outOfRangeDate_LATE.inRange(startDateTime, endDateTime))
This way, with any date you have var someDate, you can just call someDate.inRange(startDate, endDate). Sometimes, however, messing with the native prototypes can come back to haunt you if not careful. If so, having a separate function as answered by the others is very good.
Lastly, it's very important that the date strings are formatted properly before creating the Date objects, otherwise you'll encounter Invalid Date a lot. I hope this helps.

Set last day of month on YYYYMM date format - Javascript

I've a variable that has value of date in YYYYMM format. For example:
var givenDate = "201704"
How can I find out the last day of the given month and append to it. For example,
//last day of 2017 04 (April) is 30th so append value to givenDate + lastDate;
//that will be 20170430
var newFullGivenDate = "20170430";
const date = "201704";
const year = parseInt(date.substring(0, 4));
const month= parseInt(date.substring(4, 6));
const lastDay = (new Date(year, month, 0)).getUTCDate();
const newFullGivenDate = date + lastDay;
console.log(newFullGivenDate);
var givenDate = "201704";
var month = givenDate.substring(4, givenDate.length); // retrieves 04
var year = givenDate.substring(0, 4); // retrieves 2017
var d = new Date(year, month, 0);
alert(d.getDate());
Reference: MDN
To achieve expected result, use below option
last day of month - new Date(year,month ,0)
var givenDate = "201704";
var currDate = new Date(givenDate.substr(0,3),givenDate.substr(4) ,0)
var newFullGivenDate = givenDate + currDate.getDate();
console.log(newFullGivenDate)
Codepen URL for reference - https://codepen.io/nagasai/pen/OmgZMW
I would break it down into two functions:
// Get last day from year and month
let lastDayOf = (year, month) => (new Date(year, month, 0)).getDate();
// Add last day to string only if input is correct
let addLastDay = (input) => {
// In case you pass number (201705) instead of string ("201705")
if (Number.isInteger(input)) input = input.toString();
// Check if input is in correct format - 6 digit string
if (typeof input !== "string" || !input.match(/^\d{6}$/)) {
return input; // You can implement desired behavour here. I just return what came
}
const year = input.substr(0, 4);
const month = input.substr(4, 2);
return input + lastDayOf(year, month);
}
// Tests
console.assert(addLastDay("201704"), "20170430");
console.assert(addLastDay("201702"), "20170228");
console.assert(addLastDay("201202"), "20120229");
console.assert(addLastDay(201705), "20170531");
console.assert(addLastDay(20170), 20170); // Wrong input
// Interactive example
document.getElementsByTagName('button')[0].addEventListener('click', () => {
let input = document.getElementsByTagName('input')[0];
input.value = addLastDay(input.value);
});
<input type="text" value="201704"><button>Calculate</button>
If you are using moment js you can yry this:
var date = moment(newFullGivenDate ).format('YYYYMMDD');
date = date.add(-1 * parseInt(date.format('DD')), 'days').add(1, 'months');

Get Month as well as date in my variable - javascript

Hi i am trying to do a IF statement which allows the current date to be compared to the input date.. if the input date is below the current date it will be false.
I have got the date passing through my variable but it only stores the number so for example it compares day 9 to another day, which is not very reliable. I want the variable to take in the month and the year as well, meaning it can compare the ENTIRE DATE.
If there is a better way let me know.
Here is my code
if (this.element.find('#visitdate').length > 0) {
var dateParts = $('#visitdate').val().split('/');
var check = new Date(dateParts[2], dateParts[1], dateParts[0], 0,0,0,0).getDate();
var today = new Date().getDate;
if (check < today) {
_errMsg = "Please enter a furture visit date";
return false;
} else {
return true;
}
}
Your line for today's date contains an error:
var today = new Date().getDate;
should be
var today = new Date().getDate();
format as mm/dd/yyyy
var from = '08/19/2013 00:00'
var to = '08/12/2013 00:00 '
var today = new Date().getDate();
function isFromBiggerThanTo(dtmfrom, dtmto){
var from = new Date(dtmfrom).getTime();
var to = new Date(dtmto).getTime() ;
return from >= to ;
}
or using below
var x = new Date('2013-05-23');
var y = new Date('2013-05-23');
and compare
You can try this - it's working fine in my project -
Step 1
First Create javascript function as below.
Date.prototype.DaysBetween = function () {
var intMilDay = 24 * 60 * 60 * 1000;
var intMilDif = arguments[0] - this;
var intDays = Math.floor(intMilDif / intMilDay);
if (intDays.toLocaleString() == "NaN") {
return 0;
}
else {
return intDays + 1;
}
}
Step 2
-
var check = new Date(dateParts[2], dateParts[1], dateParts[0], 0,0,0,0).getDate();
var today = new Date().getDate;
var dateDiff = check .DaysBetween(today);
// it will return integer value (difference between two dates )
if(dateDiff > 0 ){ alert('Your message.......');}
You can have this much easier.
You dont need to check with getDate() property you can just compare 2 dates.
And also is not needed to initialize with hours, minutes and seconds the Date, you only need year, month and date.
Here you have your example simplified
var dateParts = $('#visitdate').val().split('/');
var check = new Date(dateParts[2], dateParts[1], dateParts[0]);
var today = new Date();
if (check < today) {
return false;
} else {
return true;
}
http://jsfiddle.net/wns3LkLv/
Try this:
var user="09/09/2014/5/30";
var arrdt= user.split("/");
var userdt = new Date(arrdt[2], arrdt[1] - 1, arrdt[0],arrdt[3],arrdt[4]);
var currdt = new Date();
if (userdt < currdt) {
alert("userdate is before current date"); //do something
}else{
alert("userdate is after current date"); //do something
}
Thanks for all your answers guys i have fixed it.
I used the getTime function instead of getDate.
Then the check variable had to have a -1 assigned to the month as it was going 1 month to high.
var check = new Date(dateParts[2], dateParts[1]-1, dateParts[0], 0,0,0,0).getTime();
Cheers

Categories