Comparision between two dates - javascript

I have a calender and has following two scenarios:
case - 1
current_month = 8 (aug)
end_month = 10 (oct)
current_year = 2017
end_year = 2017
case - 2
current_month = 8 (aug)
end_month = 2 (feb)
current_year = 2017
end_year = 2018
When I click next month it should move only until "end_month". What should be the condition to satisfy both the cases:
if(condition)
alert("Move to next month");
else
alert("condition fail");
I have tried comparing start and end date objects, But I'm able to move one more month extra, which should not happen.
I have used the following conditions:
cal_date = Tue Aug 01 2017 23:58:33 GMT+0530 (India Standard Time)
$scope.edate = Wed Nov 15 2017 00:00:00 GMT+0530 (India Standard Time)
if (cal_date.getMonth() > $scope.edate.getMonth() + 1 || cal_date.getMonth() == $scope.edate.getMonth() || $scope.edate.getFullYear() <= new Date().getFullYear())
if (cal_date.getMonth() > $scope.edate.getMonth() || cal_date.getMonth() == $scope.edate.getMonth())
if (cal_date.getTime() < new Date(new Date($scope.edate) - 1)) {
if (cal_date < $scope.edate) {

Personally I would create Date objects:
var current = new Date(year,month)
var end = new Date(year,month)
and then test:
if ( current<end )
That would probably be the simplest approach.

Related

How can I get the Year and Month between the begin and end day? [duplicate]

This question already has answers here:
Getting list of dates between two dates not returning correctly JS
(3 answers)
Closed 5 years ago.
I have two days.(start and end days)
How can I get the year and month between the two days?
For example:
start day: Wed Jun 01 2016 00:00:00 GMT+0900 (JST)
end day : Sat Apr 01 2017 00:00:00 GMT+0900 (JST)
result :['06/2016','07/2016','08/2016','09/2016','10/2016','11/2016','12/2016','01/2017','02/2017','03/2017','04/2017']
Using the moment.js library:
function getDates(startDate, stopDate) {
var dateArray = [];
var currentDate = moment(startDate);
var stopDate = moment(stopDate);
while (currentDate <= stopDate) {
dateArray.push( moment(currentDate).format('YYYY-MM-DD') )
currentDate = moment(currentDate).add(1, 'days');
}
return dateArray;
}
Remember to change the format to use according to your date format.
If you can't (or don't want to) use the momentjs library, you can do something like:
var start = new Date("Wed Jun 01 2016 00:00:00"),
end = new Date("Sat Apr 01 2017 00:00:00"),
currentDate = new Date(start.getTime()),
between = [];
while (currentDate <= end) {
between.push(new Date(currentDate));
currentDate.setDate(currentDate.getDate() + 1);
}

How can I convert a 8 digit number to date format

I have a 5 digit number stored in a variable. The next step is to convert the number to a date. for example
var x = 20151506;
The above number has to be converted to:
Thu June 15 2015 06:35:50
Please note that you must first specify the time in your original date value for it to be formatted and included correctly in your output. Thus the following will not provide the time element as you're looking for.
Referencing this SO answer:
function parse(str) {
var y = str.substr(0,4),
m = str.substr(6,2) - 1,
d = str.substr(4,2);
var D = new Date(y,m,d);
return (D.getFullYear() == y && D.getMonth() == m && D.getDate() == d) ? D : 'invalid date';
}
Usage:
parse('20151506');
Output:
Mon Jun 15 2015 00:00:00 GMT-0500 (Central Daylight Time)
or in your case
parse(x.toString());
Output:
Mon Jun 15 2015 00:00:00 GMT-0500 (Central Daylight Time)
Code snippet provided below:
var x = 20151506;
function parse(str) {
var y = str.substr(0,4),
m = str.substr(6,2) - 1,
d = str.substr(4,2);
var D = new Date(y,m,d);
return (D.getFullYear() == y && D.getMonth() == m && D.getDate() == d) ? D : 'invalid date';
}
//document.write (parse('20151506'));
document.write (parse(x.toString()));
To convert that "number" in to a Date you'll have to split it into the relevant year month day (hours, minutes and seconds appear to be missing).
var x = 20151506;
var month = x % 100;
var day = Math.floor(x % 10000 / 100);
var year = Math.floor(x / 10000);
var date = new Date(year, month - 1, day)
This will give you the value of date in whateve your local timezone is - Mon Jun 15 2015 00:00:00 GMT+0100 (GMT Daylight Time).
Not sure where you get the your time part from?

moment JS get number of weeks in a month

I am trying to calculate number of weeks in a month using moment js. But I am getting wrong results for some months like May 2015 and August 2015.
I am using this code.
var start = moment().startOf('month').format('DD');
var end = moment().endOf('month').format('DD');
var weeks = (end-start+1)/7;
weeks = Math.ceil(weeks);
Is there any prebuilt method in moment JS for getting number of weeks.
I have created this gist that finds all the weeks in a given month and year. By calculated the length of calendar, you will know the number of weeks.
https://gist.github.com/guillaumepiot/095b5e02b4ca22680a50
# year and month are variables
year = 2015
month = 7 # August (0 indexed)
startDate = moment([year, month])
# Get the first and last day of the month
firstDay = moment(startDate).startOf('month')
endDay = moment(startDate).endOf('month')
# Create a range for the month we can iterate through
monthRange = moment.range(firstDay, endDay)
# Get all the weeks during the current month
weeks = []
monthRange.by('days', (moment)->
if moment.week() not in weeks
weeks.push(moment.week())
)
# Create a range for each week
calendar = []
for week in weeks
# Create a range for that week between 1st and 7th day
firstWeekDay = moment().week(week).day(1)
lastWeekDay = moment().week(week).day(7)
weekRange = moment.range(firstWeekDay, lastWeekDay)
# Add to the calendar
calendar.push(weekRange)
console.log calendar
Can be easily done using raw javascript:
function getNumWeeksForMonth(year,month){
date = new Date(year,month-1,1);
day = date.getDay();
numDaysInMonth = new Date(year, month, 0).getDate();
return Math.ceil((numDaysInMonth + day) / 7);
}
You get the day index of the first day, add it to the number of days to compensate for the number of days lost in the first week, divide by 7 and use ceil to add 1 for the simplest overflow in the next week
It display the list of weeks in a month with 'moment.js'.
It has been written in typescript with angular 6+.
Install moment with 'npm i moment'
Inside the ts file.
weeks_in_month() {
let year = 2019; // change year
let month = 4; // change month here
let startDate = moment([year, month - 1])
let endDate = moment(startDate).endOf('month');
var dates = [];
var weeks = [];
var per_week = [];
var difference = endDate.diff(startDate, 'days');
per_week.push(startDate.toDate())
let index = 0;
let last_week = false;
while (startDate.add(1, 'days').diff(endDate) < 0) {
if (startDate.day() != 0) {
per_week.push(startDate.toDate())
}
else {
if ((startDate.clone().add(7, 'days').month() == (month - 1))) {
weeks.push(per_week)
per_week = []
per_week.push(startDate.toDate())
}
else if (Math.abs(index - difference) > 0) {
if (!last_week) {
weeks.push(per_week);
per_week = [];
}
last_week = true;
per_week.push(startDate.toDate());
}
}
index += 1;
if ((last_week == true && Math.abs(index - difference) == 0) ||
(Math.abs(index - difference) == 0 && per_week.length == 1)) {
weeks.push(per_week)
}
dates.push(startDate.clone().toDate());
}
console.log(weeks);
}
Result:
Array of date moments.
[Array(6), Array(7), Array(7), Array(7), Array(3)]
0: (6) [Mon Apr 01 2019 00:00:00 GMT+0530 (India Standard Time),
Tue Apr 02 2019 00:00:00 GMT+0530 (India Standard Time),
Wed Apr 03 2019 00:00:00 GMT+0530 (India Standard Time),
Thu Apr 04 2019 00:00:00 GMT+0530 (India Standard Time),
Fri Apr 05 2019 00:00:00 GMT+0530 (India Standard Time),
Sat Apr 06 2019 00:00:00 GMT+0530 (India Standard Time)]
1: (7) [Sun Apr 07 2019 00:00:00 GMT+0530 (India Standard Time),
Mon Apr 08 2019 00:00:00 GMT+0530 (India Standard Time),
Tue Apr 09 2019 00:00:00 GMT+0530 (India Standard Time),
Wed Apr 10 2019 00:00:00 GMT+0530 (India Standard Time),
Thu Apr 11 2019 00:00:00 GMT+0530 (India Standard Time),
Fri Apr 12 2019 00:00:00 GMT+0530 (India Standard Time),
Sat Apr 13 2019 00:00:00 GMT+0530 (India Standard Time)]
2: (7) [Sun Apr 14 2019 00:00:00 GMT+0530 (India Standard Time),
Mon Apr 15 2019 00:00:00 GMT+0530 (India Standard Time),
Tue Apr 16 2019 00:00:00 GMT+0530 (India Standard Time),
Wed Apr 17 2019 00:00:00 GMT+0530 (India Standard Time),
Thu Apr 18 2019 00:00:00 GMT+0530 (India Standard Time),
Fri Apr 19 2019 00:00:00 GMT+0530 (India Standard Time),
Sat Apr 20 2019 00:00:00 GMT+0530 (India Standard Time)]
3: (7) [Sun Apr 21 2019 00:00:00 GMT+0530 (India Standard Time),
Mon Apr 22 2019 00:00:00 GMT+0530 (India Standard Time),
Tue Apr 23 2019 00:00:00 GMT+0530 (India Standard Time),
Wed Apr 24 2019 00:00:00 GMT+0530 (India Standard Time),
Thu Apr 25 2019 00:00:00 GMT+0530 (India Standard Time),
Fri Apr 26 2019 00:00:00 GMT+0530 (India Standard Time),
Sat Apr 27 2019 00:00:00 GMT+0530 (India Standard Time)]
4: (3) [Sun Apr 28 2019 00:00:00 GMT+0530 (India Standard Time),
Mon Apr 29 2019 00:00:00 GMT+0530 (India Standard Time),
Tue Apr 30 2019 00:00:00 GMT+0530 (India Standard Time)]
EDIT:
NEW and hopefully very correct implementation:
function calcWeeksInMonth(date: Moment) {
const dateFirst = moment(date).date(1);
const dateLast = moment(date).date(date.daysInMonth());
const startWeek = dateFirst.isoWeek();
const endWeek = dateLast.isoWeek();
if (endWeek < startWeek) {
// Yearly overlaps, month is either DEC or JAN
if (dateFirst.month() === 0) {
// January
return endWeek + 1;
} else {
// December
if (dateLast.isoWeekday() === 7) {
// Sunday is last day of year
return endWeek - startWeek + 1;
} else {
// Sunday is NOT last day of year
return dateFirst.isoWeeksInYear() - startWeek + 1;
}
}
} else {
return endWeek - startWeek + 1;
}
}
Outputs the following values for the following dates:
calcWeeksInMonth(moment("2016-12-01")); // 5
calcWeeksInMonth(moment("2017-01-01")); // 6
calcWeeksInMonth(moment("2017-02-01")); // 5
calcWeeksInMonth(moment("2017-03-01")); // 5
calcWeeksInMonth(moment("2017-04-01")); // 5
calcWeeksInMonth(moment("2017-05-01")); // 5
calcWeeksInMonth(moment("2017-06-01")); // 5
calcWeeksInMonth(moment("2017-07-01")); // 6
calcWeeksInMonth(moment("2017-08-01")); // 5
calcWeeksInMonth(moment("2017-09-01")); // 5
calcWeeksInMonth(moment("2017-10-01")); // 6
calcWeeksInMonth(moment("2017-11-01")); // 5
calcWeeksInMonth(moment("2017-12-01")); // 5
calcWeeksInMonth(moment("2018-01-01")); // 5
OLD and very incorrect implementation:
calcWeeksInMonth(date) {
const dateFirst = moment(date).date(1)
const dateLast = moment(date).date(date.daysInMonth())
const startWeek = dateFirst.week()
const endWeek = dateLast.week()
if (endWeek < startWeek) {
return dateFirst.weeksInYear() - startWeek + 1 + endWeek
} else {
return endWeek - startWeek + 1
}
}
This seems to output correct results, feedback welcome if there is something I missed!
function getWeekNums(momentObj) {
var clonedMoment = moment(momentObj), first, last;
// get week number for first day of month
first = clonedMoment.startOf('month').week();
// get week number for last day of month
last = clonedMoment.endOf('month').week();
// In case last week is in next year
if( first > last) {
last = first + last;
}
return last - first + 1;
}
javaScript version here
var year = 2021
var month = 6
var startDate = moment([year, month])
//Get the first and last day of the month
var firstDay = moment(startDate).startOf('month')
var endDay = moment(startDate).endOf('month')
//Create a range for the month we can iterate through
var monthRange = moment.range(firstDay, endDay)
//Get all the weeks during the current month
var weeks = []
var indexOf = [].indexOf;
monthRange.by('days', function (moment) {
var ref;
if (ref = moment.week(), indexOf.call(weeks, ref) < 0) {
return weeks.push(moment.week());
}
});
var calendar, firstWeekDay, i, lastWeekDay, len, week, weekRange;
calendar = [];
for (i = 0, len = weeks.length; i < len; i++) {
week = weeks[i];
// Create a range for that week between 1st and 7th day
firstWeekDay = moment().week(week).day(0);
lastWeekDay = moment().week(week).day(6);
weekRange = moment.range(firstWeekDay, lastWeekDay);
// Add to the calendar
calendar.push(weekRange);
}
This is the best way out , works well
moment.relativeTime.dd = function (number) {
// round to the closest number of weeks
var weeks = Math.round(number / 7);
if (number < 7) {
// if less than a week, use days
return number + " days";
} else {
// pluralize weeks
return weeks + " week" + (weeks === 1 ? "" : "s");
}
}
Source:How to get duration in weeks with Moment.js?
I have not seen a solution that works in all circumstances. I tried all of these but they all are flawed in one way or another. Ditto with several moment.js github threads. This was my crack at it:
getNumberOfWeeksInMonth = (momentDate) => {
const monthStartWeekNumber = momentDate.startOf('month').week();
const distinctWeeks = {
[monthStartWeekNumber]: true
};
let startOfMonth = momentDate.clone().startOf('month');
let endOfMonth = momentDate.clone().endOf('month');
// this is an 'inclusive' range -> iterates through all days of a month
for (let day = startOfMonth.clone(); !day.isAfter(endOfMonth); day.add(1, 'days')) {
distinctWeeks[day.week()] = true
}
return Object.keys(distinctWeeks).length;
}
function weeksInMonth(date = null){
let firstDay = moment(date).startOf('month');
let endDay = moment(date).endOf('month');
let weeks = [];
for (let i = firstDay.week(); i <= endDay.week(); i++){
weeks.push(i)
}
return weeks;
}
Here is a simple way of doing it (based on a solution posted above):
const calcWeeksInMonth = (momentDate) => {
const dateFirst = moment(momentDate).date(1)
const dateLast = moment(momentDate).date(momentDate.daysInMonth())
const startWeek = dateFirst.isoWeek()
const endWeek = dateLast.isoWeek()
if (endWeek < startWeek) {
// cater to end of year (dec/jan)
return dateFirst.weeksInYear() - startWeek + 1 + endWeek
} else {
return endWeek - startWeek + 1
}
}
As far as I can tell, it works correctly for any date thrown at it, but feedback is always welcome!
Throwing this into the mix
import moment from "moment";
export const calcWeeksInMonth = date => {
let weekMonthEnds = moment(date)
.date(moment(date).daysInMonth())
.week();
let weekMonthStarts = moment(date)
.date(1)
.week();
return weekMonthEnds < weekMonthStarts
? moment(date).isoWeeksInYear() - weekMonthStarts + 1
: weekMonthEnds - weekMonthStarts + 1;
};
var month = moment().month();
var startOfMonth = month.startOf("month");
var endOfMonth = month.endOf("month");
var startWeekNumber = startOfMonth.isoWeek();
var endWeekNumber = endOfMonth.isoWeek();
var numberOfWeeks = (endWeekNumber - startWeekNumber + 1);
console.log(numberOfWeeks);
If you have selectedDate value that is give you opportunity to detect which month is active now:
private calculateNumberOfWeeks(): number {
const end = moment(this.selectedDate).endOf('month');
const startDay = moment(this.selectedDate)
.startOf('month')
.day();
const endDay = end.day();
const endDate = end.date();
return (startDay - 1 + endDate + (endDay === 0 ? 0 : 7 - endDay)) / 7;
}
/UPDATE/
Solution below did not take in consideration jump to the new year.
Here is the improved solution.
const getNumberOfWeeksInAMonth = (currentMoment: moment.Moment) => {
const currentMomentCopy = cloneDeep(currentMoment)
const startOfMonth = currentMomentCopy.startOf('month')
const startOfISOWeek = startOfMonth.startOf('isoWeek')
let numberOfWeeks = 0;
do {
numberOfWeeks++
MomentManager.addWeek(startOfISOWeek)
} while (currentMoment.month() === startOfISOWeek.month())
return numberOfWeeks;
}
I have found another solution with momentjs.
const getNumberOfWeeksInMonth = (moment: moment.Moment) => {
const startWeek = moment.startOf('month').isoWeek()
const endWeek = moment.endOf('month').isoWeek()
return endWeek - startWeek + 1
}

How to compare the date part alone from a date time value

I have two variables namely
date1 = Mon Nov 25 2013 00:00:00 GMT+0530 (IST)
date2 = Mon Nov 25 2013 14:13:55 GMT+0530 (IST)
When I compare the two dates I get that date2 is greater which I need is correct. But I do not want to check the time part of the two dates I have. How could I get the date part alone from these two dates and compare it?
var today = new Date(); //Mon Nov 25 2013 14:13:55 GMT+0530 (IST)
d = new Date(my_value); //Mon Nov 25 2013 00:00:00 GMT+0530 (IST)
if(d>=today){ //I need to check the date parts alone.
alert(d is greater than or equal to current date);
}
Try clearing the time using Date.setHours:
dateObj.setHours(hoursValue[, minutesValue[, secondsValue[, msValue]]])
Example Code:
var today = new Date();
today.setHours(0, 0, 0, 0);
d = new Date(my_value);
d.setHours(0, 0, 0, 0);
if(d >= today){
alert(d is greater than or equal to current date);
}
The best way would be to modify the accepted answer's if statement as follows
if(d.setHours(0,0,0,0) >= today.setHours(0,0,0,0))
In this way, you can easily check for equality as well because the return type for setHours() is integer.
Try:
var today = new Date(); //Mon Nov 25 2013 14:13:55 GMT+0530 (IST)
var d = new Date(my_value); //Mon Nov 25 2013 00:00:00 GMT+0530 (IST)
var todayDateOnly = new Date(today.getFullYear(),today.getMonth(),today.getDate()); //This will write a Date with time set to 00:00:00 so you kind of have date only
var dDateOnly = new Date(d.getFullYear(),d.getMonth(),d.getDate());
if(dDateOnly>=todayDateOnly){
alert(d is greater than or equal to current date);
}
var StartDate = $("#StartDate").val();
var EndDate = $("#EndDate").val();
if ((( EndDate - StartDate)/ (86400000*7))<0)
{
alert("Start Date Must Be Earlier Than End Date"); $("#StartDate").focus();
error = true;
return false;
}

Writing a complicated if statement in js

I have a list of years with id, from date and to date as follows:
id from_date to_date
1 2013-02-12 2013-02-22
2 2013-03-01 2013-03-28
3 2013-03-29 2013-04-15
and so on
I am having problems with overlapping dates if condition. I want to edit from_date of id 2 to a date in between 2013-02-22 and 2013-03-01 or to_date of period 1 to a date in between 2013-02-22 and 2013-03-01, but it only allows 1 as per my code below.
Here is a snippet of my code:
function validate(id){
//id is passed as a parameter to the function
from_date = document.getElementById('from_date_' + id);
to_date= document.getElementById('to_date_' + id);
var from = new Date();
var to = new Date();
// I am able to split the string, .split("-") and convert it in date format
previous_to_date = document.getElementById("to_" + id);//id is one less
next_from_date = document.getElementById("from_date_" + id);//id is one more
current_from_date //I store it before editing the from date
current_to_date //Similarly for current from date
//from_date and to_date are the edited dates by the user
if (from_date > to_date){ alert("This date is invalid"); return false; }
//now to check for overlapping dates
**//This is the condition I am having problems with**
if ((from_date < current_from_date && from_date < previous_to_date) || (to_date > current_to_date && to_date > next_from_date) && from_date > current_to_date){
alert("These dates overlap,Please select another date");
return false;
}
//successful so now we submit the form...
}
In simpler terms if there is a gap between the from date on current
period and the to date of the previous period, i should be able to
edit the change to minimize the gap to at most 1.
var to_previous = "2013-02-22"
var from = "2013-03-01"
var to_previous_millis = Date.parse(to_previous);
var from_millis = Date.parse(from);
one_day = 1000*60*60*24;
while( (from_millis - to_previous_millis) >= one_day) {
current = new Date(from_millis);
console.log(current.toUTCString());
from_millis -= one_day
}
--output:--
Fri, 01 Mar 2013 00:00:00 GMT
Thu, 28 Feb 2013 00:00:00 GMT
Wed, 27 Feb 2013 00:00:00 GMT
Tue, 26 Feb 2013 00:00:00 GMT
Mon, 25 Feb 2013 00:00:00 GMT
Sun, 24 Feb 2013 00:00:00 GMT
Sat, 23 Feb 2013 00:00:00 GMT
var attempts = [
"2013-2-28",
"2013-2-23",
"2013-2-22"
];
var len = attempts.length;
for (var i=0; i < len; ++i) {
var attempt = attempts[i];
attempt_millis = Date.parse(attempt);
if (attempt_millis >= (to_previous_millis + one_day) ) {
console.log(attempt + " : valid change");
}
else {
console.log(attempt + " : invalid change");
}
}
--output:--
2013-2-28 : valid change
2013-2-23 : valid change
2013-2-22 : invalid change

Categories