How to compare month and year in JavaScript? [duplicate] - javascript

This question already has answers here:
Compare two dates with JavaScript
(43 answers)
Closed 7 months ago.
i need to compare date.like input date is greater than current next month.using normal date in JavaScript.
//comparison_date is date which is current date + one month
// 14/07/2022 + One Month
input_date : 14/07/2022
comparison_date : 14/08/2022
if(input_date> comparison_date){
// false
}
input_date : 14/08/2022
comparison_date : 14/08/2022
if(input_date> comparison_date){
// false
}
input_date : 14/09/2022
comparison_date : 14/08/2022
if(input_date> comparison_date){
// true
}
input_date : 22/12/2022
comparison_date : 14/01/2023
if(input_date> comparison_date){
// false
}

you can do something like this
const toDate = dateString => {
const [day, month, year] = dateString.split('/')
return new Date(`${year}-${month}-01 00:00:00`)
}
console.log(toDate('14/07/2022') > toDate('14/08/2022'))
console.log(toDate('14/08/2022') > toDate('14/08/2022'))
console.log(toDate('14/09/2022') > toDate('14/08/2022'))
console.log(toDate('22/12/2022') > toDate('14/01/2023'))
if you just need to compare year and month you can also do something more simple like this
const toYearMonth = stringDate => {
const [_, month, year] = stringDate.split('/')
return Number(`${year}${month}`)
}
console.log(toYearMonth('14/07/2022') > toYearMonth('14/08/2022'))
console.log(toYearMonth('14/08/2022') > toYearMonth('14/08/2022'))
console.log(toYearMonth('14/09/2022') > toYearMonth('14/08/2022'))
console.log(toYearMonth('22/12/2022') > toYearMonth('14/01/2023'))

Text doesn't compare datewise, you need to convert to a timestamp and compare the values, the Date class would do this for you
const date1 = new Date("2022-07-14");
const date2 = new Date("2022-08-14");
console.log(date1.getTime() > date2.getTime());
console.log(date1.getTime() => date2.getTime());
console.log(date1.getTime() < date2.getTime());
console.log(date1.getTime() >= date2.getTime());
console.log(date1.getTime() == date2.getTime());
assuming you want the current date + one month you can do
current = new Date();
nextMonth = current.setMonth(current.getMonth()+1);//note this changes the value of "current"
however depending on the type of compare you want you may need to customise the compare, ie date one is midnight case 2 is midnight and a microsecond is this greater than or equal? depends on your situation
note: you appear to be using the en-GB date format which is a pain try to use ISO yyyy-mm-dd, it simplifies many things

Related

Sort Data and Time String in Javascript [duplicate]

This question already has answers here:
Why does Date.parse give incorrect results?
(11 answers)
Closed 1 year ago.
I Know there are lot of answers out there to sort date and time. But in every answer, they sort only date or they sort only time. I can't find the answer which sorts both date and time string.
Here's the Code I tried:
var x = [ '29/09/2020 11:55:56', '04/08/2021 11:57:06', '30/09/2019 15:19:49', '04/08/2021 13:57:06' ]
x.sort((a, b) => new Date(b).getTime() - new Date(a).getTime()).reverse();
console.log(x)
Output I got:
["04/08/2021 13:57:06", "30/09/2019 15:19:49", "04/08/2021 11:57:06", "29/09/2020 11:55:56"]
Required Output:
["04/08/2021 13:57:06","04/08/2021 11:57:06", "29/09/2020 11:55:56", "30/09/2019 15:19:49", ]
I searched whole day. Please Help me with some solutions to fix this.
The problem is that Date uses a yyyy/mm/dd format instead of a dd/mm/yyyy format. So all your Date objects are Invalid Date.
P.S. If you sort but have to reverse the order afterwards, just reverse the subtractions.
if momentjs an option:
var x = [ '29/09/2020 11:55:56', '04/08/2021 11:57:06', '30/09/2019 15:19:49', '04/08/2021 13:57:06' ];
x.sort((a, b) => moment(b,"DD-MM-YYYY hh:mm:ss") - (moment(a,"DD-MM-YYYY hh:mm:ss")));
console.log(x)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
I think this is a very hard task when you try to compare date and time in strings. And would take to much time when executing. Instead i would convert date and times to timestamp format then compare. To convert a date string to a timestamp format i referred to the answer on this stackoverflow question
const dates = [ '29/09/2020 11:55:56', '04/08/2021 11:57:06', '30/09/2019 15:19:49', '04/08/2021 13:57:06' ];
dates.sort((date1,date2) => {
var dateTimeParts = date1.split(' '),
timeParts = dateTimeParts[1].split(':'),
dateParts = dateTimeParts[0].split('/'),
date1;
date1 = new Date(dateParts[2], parseInt(dateParts[1], 10) - 1, dateParts[0], timeParts[0], timeParts[1], timeParts[2]);
var dateTimeParts2 = date2.split(' '),
timeParts2 = dateTimeParts2[1].split(':'),
dateParts2 = dateTimeParts2[0].split('/'),
date2;
date2 = new Date(dateParts2[2], parseInt(dateParts2[1], 10) - 1, dateParts2[0], timeParts2[0], timeParts2[1], timeParts[2]);
return date1.getTime() / 1000 - date2.getTime() / 1000
});
console.log(dates);
Date and time are not separate in the context of a javascript Date object, internally they are just stored as millisecond offsets. But, you can't rely on Date parsing strings for you. Write a custom parser for you specific date-time strings and then then simply subtract dates.
There's no need for reverse() either, simply switch the subtraction to change direction.
const x = [ '29/09/2020 11:55:56', '04/08/2021 11:57:06', '30/09/2019 15:19:49', '04/08/2021 13:57:06' ];
const parse_date_string = (str) => {
const [date, time]= str.split(' ');
const [day, month, year] = date.split('/');
const [hr, min, sec] = time.split(':');
return [year, (month - 1), day, hr, min, sec].map(Number);
}
x.sort((a, b) => new Date(...parse_date_string(b)) - new Date(...parse_date_string(a)));
console.log(x)

Time Selector should not let me select time more than now

I have 2 textboxes. One for Date and one for time.
.
I can set maxDate: new Date but that will ake it for every date I pick up from the calendar.
I also tried
$('#datetimepickerExample').datetimepicker({
format: 'LT', stepping: 1, autoclose: true,
onClose: function (selectedDate) {
$("#ContentPlaceHolder1_Event_Date_Txt").datepicker("option", "maxDate", selectedDate);
}
});
where "ContentPlaceHolder1_Event_Date_Txt" is the Date Textbox but it doesn't work. So when I pick an earlier date I can select all the 24 hours but when I select today it should limit me to the current time.
Before trying the method I've written below, I encourage you to read the plugin documentation here. I did not read whole documentation but I wanted to point out at least a direction for you.
1 - You should get current system date and time.
You can achieve that with JavaScript GetDate() Method
function getNow() {
var e = new Date,
month = e.getMonth() + 1,
date = e.getDate(),
year = e.getFullYear();
month < 10 && (month = "0" + month.toString()), date < 10 && (date = "0" + date.toString());
var currentTime = e.getHours() + ":" + e.getMinutes();
var currentDate = month + "/" + date + "/" + year;
//currentDate
//03/27/2021
//currentTime
//11:20
}
2 - If current date equals to the date you've picked you should limit the max time input to the current time. I believe you can achieve that with the code below. As I've said I did not read the documentation for the plugin you are using.
$("#ContentPlaceHolder1_Event_Date_Txt").datepicker({
onSelectDate:function(currentTime){
$('#datetimepickerExample').datetimepicker("option", "maxTime", currentTime);
}
});
Good Luck!
Here is a relatively simple function that solves this:
const isInThePast = date => {
const now = new Date()
if (typeof date !== typeof now) return "Invalid Date"
else return date < now ? true : false
}
You can call this function on every date change event and if it returns true, set the value, if it returns false give the user some sort of warning and keep the previous value.

get an array of dates from today for datepicker with Javascript

I am trying to write a function that returns an array of dates from today till the maximum date, so that I can restrict the date picker selection. At the moment I have the following:-
datesAfterToday: function (date) {
var dates = []
var currentDate = new Date()
var endDate = new Date(8640000000000000).getFullYear()
var addDays = function (days) {
var date = new Date(this.valueOf())
date.setDate(date.getDate() + days)
return date
}
while (currentDate <= endDate) {
dates.push(currentDate)
currentDate = addDays.call(currentDate, 1)
}
return dates
}
and then I am using Vue.js to mount it as follows :-
mounted () {
this.allowedDates = this.datesAfterToday
},
however I am only getting an array of objects instead of the proper array.
How can I get the proper array of dates so that I can bind it to the allowdates property.
Thanks for your help and time!
For starters new Date(8640000000000000).getFullYear() will set endDate to the year of that date, which is 275760. currentDate will be today's date (in milliseconds), which at the time of me writing is 1511272934156. As you can see currentDate is always greater than endDate, so your while loop never goes to the statements inside.
Another issue is that the date you picked is really far in the future and you're populating an array one day at a time. Your loop will most likely make the page freeze or crash completely. Try picking a date that's more manageable.
For instance, in the snippet below I set endDate by first initializing it to today, then setting the year to exactly one year from now. This gives me an array with roughly 365 values.
You can imagine how big this array would be if I used a year that was 273,748 years in the future.
var dates = []
var currentDate = new Date()
var endDate = new Date()
endDate.setFullYear(endDate.getFullYear()+1)
var addDays = function (days) {
var date = new Date(this.valueOf())
date.setDate(date.getDate() + days)
return date
}
while (currentDate <= endDate) {
dates.push(currentDate)
currentDate = addDays.call(currentDate, 1)
}
console.log(dates)
With all that being said, it looks like you're actually allowed to pass an object specifying the minimum and maximum values rather than an array.
https://vuetifyjs.com/components/pickers#example-6
let d = new Date() // today
let d2 = new Date()
d2.setFullYear(date.getFullYear()+1) // Next year
this.allowedDays = {
min : d.toISOString().substr(0, 10), // e.g. 2017-11-21
max : d2.toISOString().substr(0, 10)
}
Another option would be to use vuejs-datepicker For example:
<script>
var state = {
disabled: {
to: new Date(), // Disable all dates up to specific date
from: new Date(8640000000000000) // Disable all dates after specific date
}
}
</script>
<datepicker :disabled="state.disabled"></datepicker>
See Disabled Dates in the documentation.

Check if time is the same with Moment.js

How to check if time is the same for Moment objects with different dates?
For example I have object like
const endDate = moment().add(30, 'days').endOf('day');
and I want to check if some moment object is endOf day.
private isEndOfDay(dateTime: string) {
const m = moment().endOf('day');
return m.isSame(dateTime, 'minute');
}
const receivedDateFormat: string = 'YYYY-MM-DD hh:mm:ss';
this.isEndOfDay(this.endDate.format(this.receivedDateFormat))
But for this case, when I pass "minute" parameter, it will check minute, hour, day, month and year... which isn't what I want to check.
The part of the documentation that explains that behaviour is
When including a second parameter, it will match all units equal or larger. Passing in month will check month and year. Passing in day will check day, month, and year.
So, if you just want to compare the minutes, you'll need to do something like
endDate.minute() === startDate.minute()
To compare the time only, format() the dates
endDate.format('HH:mm:ss') === startDate.format('HH:mm:ss')
To compare only time part you can set a given date (year, month and day) to your input.
Please note that passing 'minute' to isSame will ignore seconds.
Here a live sample:
function isEndOfDay(dateTime) {
let m = moment().endOf('day');
let m2 = moment(dateTime);
m2.set({
y: m.year(),
M: m.month(),
D: m.date()
});
return m.isSame(m2, 'minute');
}
var endDate = moment().add(30, 'days').endOf('day');
const receivedDateFormat = 'YYYY-MM-DD hh:mm:ss';
var ret = isEndOfDay(endDate.format(this.receivedDateFormat))
console.log(ret);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
Another way to to is checking only units that matter for you:
function isEndOfDay(dateTime) {
let m = moment().endOf('day');
let m2 = moment(dateTime);
if( m.hours() === m2.hours() &&
m.minutes() === m2.minutes() &&
m.seconds() === m2.seconds() ){
return true;
}
return false;
}
var endDate = moment().add(30, 'days').endOf('day');
const receivedDateFormat = 'YYYY-MM-DD hh:mm:ss';
var ret = isEndOfDay(endDate.format(this.receivedDateFormat))
console.log(ret);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
See Get + Set section of the docs to see how to get and set units of moment objects.

Checking between date ranges javascript

I am working on a system at the moment, that has rules based around dates ranges,
a user can submit a form, I need to check to date inputs fit within 1 of 3 dates ranges. Basically the 2 dates need to be within 1 of the 3 following rules,
01/01 - 30/04
01/05 - 30/09
01/10 - 31/12,
I need to workout what month the start date has and what month the end date has basically, and if the end date is outside of the it's range log it.
So basically, if a user submitted 01/01/2017 as a start date and 10/02/2017 as an end date, that would be a valid input, but if a user entered 01/01/2017 as a start date, and 01/06/2017 as end date that would be invalid as the date spans more than one date range.
Is it possible to check this kind of thing with javascript? I have gone through various scenarios, but the ranges in arrays and checking against array values, but I keep getting myself in a mess.
You can simply check if a date is in range with getTime()
JSBin
const isDateInRage = (startDate, endDate) => (dateToCheck) => {
return dateToCheck >= startDate && dateToCheck <= endDate
}
const isInRangeOne = isDateInRage('2016-01-01', '2016-04-30')
console.log('inRange', isInRangeOne('2016-01-02'))
console.log('outtOfRange', isInRangeOne('2016-07-02'))
Try this
// parse string 'XX/XX/XXXX' to create date object
function parseDate(str) {
var mdy = str.split('/');
return new Date(mdy[2], mdy[0]-1, mdy[1]);
}
function daysBetween(date1, date2) {
return Math.round((parseDate(date1)-parseDate(date2)) / (1000*60*60*24));
}
if(daysBetween('01/01/2017', '01/06/2017') > 1) {
// Your code here
}
Consider a function to test the start and end dates for each of the ranges and return true as soon as it fits in one of them. You'll need to correctly parse the strings, and also use the year from either the start or end date and apply it to the ranges.
The function below uses the start date and returns true if the start and end fit in one of the ranges, and false otherwise. If either the supplied start or end dates are invalid, it throws an error.
// Parse date in yyyy-mm-dd format as local date
function parseYMD(s) {
var b = s.split(/\D/);
var d = new Date(b[0], --b[1], b[2]);
return d && d.getMonth() == b[1]? d : new Date(NaN);
}
// Check start and end date are within one of the valid ranges
var checkInRange = (function () {
// Bespoke parser
function parsePart(p, y) {
p = p.split(/\D/);
return new Date(y, p[1]-1, p[0]);
}
// Valid ranges as d/m, year is taken from start date
var validRanges = ['01/01 - 30/04','01/05 - 30/09','01/10 - 31/12'];
return function (startDate, endDate) {
var dStart = parseYMD(startDate);
var dEnd = parseYMD(endDate);
// Throw error if input dates aren't valid
if (isNaN(dStart) || isNaN(dEnd)) {
throw new Error('start or end date is invalid')
}
var year = dStart.getFullYear();
// Return true if range is within valid ranges
return validRanges.some(function(range) {
var r = range.split(' - ').map(function(s){return parsePart(s, year)});
return dStart >= r[0] && dEnd <= r[1];
});
}
})();
// Some tests
[['2016-01-01','2016-04-30'],['2016-03-30','2016-04-30'],['2017-04-30','2017-05-01']].
forEach(function(dates) {
console.log('Start and end: ' + dates[0] + ' - ' + dates[1] +
'\nValid range?: ' + checkInRange(dates[0],dates[1]));
});
Do not use the Date constructor (or Date.parse) to parse strings. Their behaviour is largely implementation dependent. An ISO 8601 format date will be parsed as UTC, which is OK in this context as long as all of the strings are parsed identically, however if they aren't, users will

Categories