How to calculate number of business days between 2 dates with Moment.js inclusive of start and end dates - momentjs

https://www.npmjs.com/package/moment-business-days is super helpful but it doesn’t appear to be able to calculate inclusive difference between two dates.
In my example, I am trying to calculate PTO (paid time off) days.
So, if Friday, November 27th is a PTO day, then 2020-11-27 to 2020-11-27 should equal 1 day.
moment("2020-11-27").businessDiff("2020-11-27"); // => 0
I could add +1 but this will cause problems for other ranges.
For instance moment("2020-11-27").businessDiff("2020-11-27") + 1; // => 1 is now correct
But moment("2020-11-27").businessDiff("2020-11-29") + 1; // => 2, which is incorrect.
What I need is this…
2020-11-27 to 2020-11-27 equals 1 business day
2020-11-27 to 2020-11-28 also equals 1 business day because the 28th is a Saturday
Any suggestions?

You can do something like this
if(date1 === date2 && moment(date1).isBusinessDay()){
businessDay = 1;
}else {
businessDay = moment(date1).businessDiff(date2)
}

Related

How to set start of the week as Sunday and end as Saturday in Dart?

I can get start of the week as Monday using method below:
DateTime findFirstDateOfTheWeek(DateTime date) {
return date.subtract(Duration(days: date.weekday - 1));
}
and end of the week, the Sunday, as:
DateTime findLastDateOfTheWeek(DateTime date) {
return date.add(Duration(days: DateTime.daysPerWeek - date.weekday));
}
Now the requirements are, to treat Sunday as week start and Saturday as week end. I tried tweaking above method but could not get it working. Any help would be appreciated.
Thanks
Since DateTime.weekday counts from 1 (Monday) to 7 (Sunday):
date.subtract(Duration(days: date.weekday - 1))
will give us the date of the start of the week using what DateTime considers to be the first day of the week (Monday). To treat Sunday as the first day of the week instead, we can try to get the previous day from that:
date.subtract(Duration(days: date.weekday - 1)).subtract(const Duration(days: 1))
The above is algebraically equivalent to date - (weekday - 1) - 1, which can be simplified to just date - weekday. But that's not quite right because weekday ranges from [1, 7], and we never want to subtract 7 days. In that case, we want to subtract 0. The modulus operator handles that nicely, ultimately giving us:
DateTime findFirstDateOfTheWeek(DateTime date) {
return date.subtract(Duration(days: date.weekday % DateTime.daysPerWeek));
}
To get the last day of the week where Saturday is treated as the last day of the week, you can just get the first day of the week and add 6 days:
DateTime findLastDateOfTheWeek(DateTime date) {
return findFirstDateOfTheWeek(date).add(
const Duration(days: DateTime.daysPerWeek - 1));
}

How to get start of or end of week in dart

How can I get the start of or end of a week in dart? An example is if three days ago was a Monday, and today is a Wednesday, how can I find the start of the week using dart, that is on Monday
You can get the weekday from the DateTime using https://api.dart.dev/stable/2.5.1/dart-core/DateTime/weekday.html and add/subtract this number from you date:
void main() {
final date = DateTime.parse('2019-10-08 15:43:03.887');
print('Date: $date');
print('Start of week: ${getDate(date.subtract(Duration(days: date.weekday - 1)))}');
print('End of week: ${getDate(date.add(Duration(days: DateTime.daysPerWeek - date.weekday)))}');
}
DateTime getDate(DateTime d) => DateTime(d.year, d.month, d.day);
UPDATE
Please read and upvote the answer from lrn. He knows a lot more about this stuff than me. :)
Dart DateTimes have a weekday getter which is 1 for Monday and 7 for Sunday. Using that, I would do:
DateTime mostRecentSunday(DateTime date) =>
DateTime(date.year, date.month, date.day - date.weekday % 7);
to get the most recent Sunday (which is the start of the current week if the week starts on a Sunday), and
DateTime mostRecentMonday(DateTime date) =>
DateTime(date.year, date.month, date.day - (date.weekday - 1));
for the most recent Monday (which is then the start of the current week if the week starts on a Monday).
You can generalize to
/// The [weekday] may be 0 for Sunday, 1 for Monday, etc. up to 7 for Sunday.
DateTime mostRecentWeekday(DateTime date, int weekday) =>
DateTime(date.year, date.month, date.day - (date.weekday - weekday) % 7);
If you are going to be using the results as calendar dates, I'd used DateTime.utc as the constructor instead. (Always use UTC for calendar dates, then you can do day-based arithmetic on them safely).
I'd even consider using DateTime.utc in any case because it avoids any potential issues with a daylight saving that starts at midnight (rare, but with time zones, even unlikely things tend to have happened somewhere at some point).
The way you do this will probably depend on what your app's localization is. If you want to treat Sunday as the start of the week, you would do this:
DateTime now = DateTime.now();
int currentDay = now.weekday;
DateTime firstDayOfWeek = now.subtract(Duration(days: currentDay));
If you are treating Monday as the start, then do this:
DateTime now = DateTime.now();
int currentDay = now.weekday;
DateTime firstDayOfWeek = now.subtract(Duration(days: currentDay - 1));
MaterialLocalizations
If you're using Dart in Flutter, you can use the MaterialLocalizations class to get the index of the first day of the week (0 = Sunday, 6 = Saturday). This should help you decide which method from above that you should use.
The example given for the firstDayOfWeekIndex property is a good reference:
var localizations = MaterialLocalizations.of(context);
// The name of the first day of week for the current locale.
var firstDayOfWeek = localizations.narrowWeekdays[localizations.firstDayOfWeekIndex];
The MaterialLocalizations class comes with a ton of built in methods to format and display DateTimes.
dateTime: 2021-01-26 11:21:05.429320
formatFullDate: Tuesday, January 26, 2021
formatCompactDate: 01/26/2021
formatMediumDate: Tue, Jan 26
formatShortDate: Jan 26, 2021
formatShortMonthDay: Jan 26
formatMonthYear: January 2021
formatYear: 2021
If none of these fit your needs, you can also use the DateFormat class to specify how the DateTime should be displayed. It's important to note that the DateFormat class indexes days differently where 1 = Monday and 7 = Sunday.
DateFormat.yMMMd().format(new DateTime.now()) // Jan 26, 2021
DateFormat(DateFormat.ABBR_MONTH_DAY).format(now) // Jan 26
DateFormat(DateFormat.WEEKDAY).format(now) // Tuesday
FIRST DAY OF THE WEEK
DateTime findFirstDateOfTheWeek(DateTime dateTime) {
return dateTime.subtract(Duration(days: dateTime.weekday - 1));
}
LAST DAY OF THE WEEK
DateTime findLastDateOfTheWeek(DateTime dateTime) {
return dateTime
.add(Duration(days: DateTime.daysPerWeek - dateTime.weekday));
}
LAST DAY OF THE MONTH
DateTime findLastDateOfTheMonth(DateTime dateTime) {
return DateTime(dateTime.year, dateTime.month + 1, 0);
}
FIRST DAY OF THE MONTH
DateTime findFirstDateOfTheMonth(DateTime dateTime) {
return DateTime(dateTime.year, dateTime.month, 1);
}
LAST DAY OF THE YEAR
DateTime findLastDateOfTheYear(DateTime dateTime) {
return DateTime(dateTime.year, 12, 31);
}
FIRST DAY OF THE YEAR
DateTime findFirstDateOfTheYear(DateTime dateTime) {
return DateTime(dateTime.year, 1, 1); }
Dart/Flutter – How to find the first date and the last date of a week
1. Find the first date of the week
/// Find the first date of the week which contains the provided date.
DateTime findFirstDateOfTheWeek(DateTime dateTime) {
return dateTime.subtract(Duration(days: dateTime.weekday - 1));
}
2. Find the last date of the week
/// Find last date of the week which contains provided date.
DateTime findLastDateOfTheWeek(DateTime dateTime) {
return dateTime.add(Duration(days: DateTime.daysPerWeek - dateTime.weekday));
}
Testing
void main() {
// Find first date and last date of THIS WEEK
DateTime today = DateTime.now();
print(findFirstDateOfTheWeek(today));
print(findLastDateOfTheWeek(today));
// Find first date and last date of any provided date
DateTime date = DateTime.parse('2020-11-24');
print(findFirstDateOfTheWeek(date));
print(findLastDateOfTheWeek(date));
}
// Output
2020-11-23 06:54:42.865446
2020-11-29 06:54:42.865446
2020-11-23 00:00:00.000
2020-11-29 00:00:00.000
None of the above worked for me but #JoeMuller gave an interesting piece of info on the material localizations, which led me to find out that for what i want, sunday in date.weekday should be 0 took a while to figure it out many thanks to joe and #julemand101 I have this for UK calendar starting from sunday and ending on saturday
void main() {
final date = DateTime.parse('2021-08-01');
print('Date: $date');
final weekDay = date.weekday == 7 ? 0 : date.weekday;
print('Start of week: ${getDate(date.subtract(Duration(days: weekDay)))}');
print('End of week: ${getDate(date.add(Duration(days: DateTime.daysPerWeek - weekDay - 1)))}');
}
DateTime getDate(DateTime d) => DateTime(d.year, d.month, d.day);
I have 2 function:
DateTime getStartTimeWeek([DateTime? date]) {
final currentDate = date ?? DateTime.now();
final dateTime = DateTime(currentDate.year, currentDate.month, currentDate.day);
return dateTime.subtract(Duration(days: currentDate.weekday - 1));
}
DateTime getEndTimeWeek([DateTime? date]) {
final currentDate = date ?? DateTime.now();
final dateTime = DateTime(currentDate.year, currentDate.month, currentDate.day, 23, 59, 59, 999);
return dateTime.add(Duration(days: DateTime.daysPerWeek - currentDate.weekday));
}
Below is the code which should work fine in most cases.
We can get start and end of the week like this:-
To get the first day of the week for a date use the below function.
Like Sunday (Also known as 7 in WeekDay).
Read lines of comments in code for code clarifications.
DateTime getFirstDayOfWeek({required DateTime currentDateTime}) {
// Converting date provided to UTC
// So that all things like DST don't affect subtraction and addition on date
DateTime dateTimeInUTC = DateTime.utc(
currentDateTime.year, currentDateTime.month, currentDateTime.day);
// Getting weekday for the date
// For reference Sunday weekday is 7 and Friday weekday is 5
int currentWeekDayInUTC = dateTimeInUTC.weekday;
// Getting Date for nearest Sunday from the provided date
// By going back a number of weekdays from the current date to reach Sunday
DateTime firstDayOfWeekInUTC;
// If current date is not Sunday subtract days to reach Sunday
if (currentWeekDayInUTC != DateTime.sunday) {
firstDayOfWeekInUTC =
dateTimeInUTC.subtract(Duration(days: currentWeekDayInUTC));
}
// If current date is Sunday use it as the first day of week
else {
firstDayOfWeekInUTC = dateTimeInUTC;
}
// Converting back the date for Sunday from UTC type to Local
// You can also use UTC type depending on your use case
DateTime firstDayOfWeekInLocal = DateTime(firstDayOfWeekInUTC.year,
firstDayOfWeekInUTC.month, firstDayOfWeekInUTC.day);
if (currentDateTime.isUtc) {
return firstDayOfWeekInUTC;
} else {
return firstDayOfWeekInLocal;
}
}
To get the last day of the week for a date use the below function.
Like Saturday (Also known as 6 in WeekDay).
Read lines of comments in code for code clarifications.
DateTime getLastDayOfWeek({required DateTime currentDateTime}) {
// Converting date provided to UTC
// So that all things like DST don't affect subtraction and addition on date
DateTime dateTimeInUTC = DateTime.utc(
currentDateTime.year, currentDateTime.month, currentDateTime.day);
// Getting weekday for the date
// For reference Sunday weekday is 7 and Friday weekday is 5
int currentWeekDayInUTC = dateTimeInUTC.weekday;
// Getting Date for nearest Saturday from the provided date
// By going forward a number of weekdays from the current date to reach Saturday
DateTime lastDayOfWeekInUTC;
// If current date is not Sunday add days enough to reach Saturday
if (currentWeekDayInUTC != DateTime.sunday) {
lastDayOfWeekInUTC = dateTimeInUTC
.add(Duration(days: DateTime.saturday - currentWeekDayInUTC));
}
// If current date is Sunday add days UpTo saturday
else {
lastDayOfWeekInUTC = dateTimeInUTC.add(Duration(days: DateTime.saturday));
}
// Converting back the date for Sunday from UTC type to Local
// You can also use UTC type depending on your use case
DateTime lastDayOfWeekInLocal = DateTime(lastDayOfWeekInUTC.year,
lastDayOfWeekInUTC.month, lastDayOfWeekInUTC.day);
if (currentDateTime.isUtc) {
return lastDayOfWeekInUTC;
} else {
return lastDayOfWeekInLocal;
}
}

add and substract months using simple math

im looking for mathematical formulas to add and subtract months to/from a date. i only need to know the year and month, therefor days can be ignored.
this is the adding months pseudo code i came up with:
OldYear = 2012 // current year
OldMonth = 3 // current month
AddMonths = 0 // the months to be added
FooBar = OldMonth + AddMonths
NewYear = OldYear + FooBar / 12
NewMonth = FooBar % 12
IF NewMonth = 0
NewYear = NewYear - 1
NewMonth = 12
END IF
// set AddMonths to 0 and the result will be 2012.03
// set AddMonths to 6 and the result will be 2012.09
// set AddMonths to 9 and the result will be 2012.12
// set AddMonths to 11 and the result will be 2013.02
// set AddMonths to 23 and the result will be 2014.02
// set AddMonths to 38 and the result will be 2015.05
and it works really great, but is there an even better way? i dont really like the need for the IF NewMonth = 0 readjustments.
but my actual problem is, that i couldnt come up with a counterpart formula to substract months. i tried various things, but everything failed and its driving me insane. so any help would be much appreciated!
It is a combination of my comment in #Matt's answer, and answer of #Matt
The formula can be greatly reduced if you adopt a 0-based month scheme.
pseudocode:
year = 2012; // year 2012
month = 6; // July (NOT June)
monthToAdd = -20; // +ve/-ve means add/subtract
resultYear = (year * 12 + month + monthToAdd) /12;
resultMonth = (year * 12 + month + monthToAdd) mod 12;
// resultYear == 2010
// resultMonth == 10 , which means November
Edit: The original answer above assumed a zero-based month scheme, which seem being overlooked by some people. To avoid confusion, we can of course use more intuitive 1-based month scheme, and do the 0-base conversion during calculation (though it make the calculation slightly messier):
year = 2012; // year 2012
month = 7; // July
monthToAdd = -20; // +ve/-ve means add/subtract
resultYear = (year * 12 + (month - 1) + monthToAdd) /12;
resultMonth = ((year * 12 + (month - 1) + monthToAdd) mod 12) + 1
// resultYear == 2010
// resultMonth == 11 , which means November
One possible solution would be to multiply OldYear by 12 (thus converting it to months), adding or subtracting AddMonths or SubMonths, respectively, and then converting back to NewYear and NewMonth by using integer and modular division (depending on your programming language, you may be able to simplify this).
Full credit to Adrian Shum for building the main logic but I think there is a edge case which the code is not 100% accurate for cases where we go back the same number of months as the month we are in. For example, if we are in March and we go back 3 months we should end up at Dec (Feb, Jan and Dec) .
here is the modified version:
year = 2020;
month = 4;
monthToAdd = -1;
resultYear = (year * 12 + month + monthToAdd) /12;
resultMonth = (year * 12 + month + monthToAdd) % 12;
if month+monthToAdd == 0:
resultMonth=12
elif (abs(monthToAdd)%month)==0:
resultMonth=month
print(resultMonth)
print(resultYear)

Find This Weeks Monday

How do I get the date of this current week's Monday. Where Monday is the first day of the week. So if I was to look up this weeks it would return the date 1/16/2012
I am using VBScript and ASP
Many thanks in advance..
Paul
Effectively, the Weekday function returns Sunday=1, Monday=2, etc. To get the Monday of the same week, you want to subtract:
Sunday (1): 6 days
Monday (2): 0 days
Tuesday(3): 1 day
...
Saturday(7): 5 days.
Or
Days to subtract = (Weekday - 2 + 7) Mod 7
So if d is a date, the Monday of the same week can be written as:
mondayofsameweek = DateAdd("d", -((Weekday(d) + 7 - 2) Mod 7), d)
VBScript has a function called WeekDay, it return 1 - 7, not sure whether 1 is Monday though, usually you can twiddle with that.
Either way get the weekday Thursday = 4? , so then you just need to take three days off your date with thae DateAdd function
In VBScript WeekDay returns the day of the week, starting with Sunday=1 (VBScript can be quirky like that). So just subtract two (Monday=2) from that value and call DateAdd.
monday = DateAdd("d",(WeekDay(Date())-2),Date())
I know the topic is a bit old, but I figured I'd share my working solution that I think is a bit more concise.
Where dDate is your current date:
dDate = DateAdd("d", -(WeekDay(dDate, vbMonday) - 1), dDate)
The second parameters of WeekDay is the day you want the week to 'start'. For me, in the US, WeekDay corresponds the default second parameter to vbSunday. Specifying vbMonday, we just get the difference (base 1) between our current weekday and Monday.
Subtract 1 and add the inverse to your current date should obtain your result.
Example:
WeekDay(2018-03-20, vbMonday) = -((2) - 1) = DateAdd("d", -1, 2018-03-20)

How to calculate the number of weeks in a month

I want to calculate the total no of weeks in current month. Starting from Sunday or Monday.
Is it possible to do in Qt
I would say this problem is not specific to Qt, but Qt can help you with the QDate class.
With this class you can get the current month :
QDate CurrentDate = QDate::currentDate();
The number of days of a given month :
CurrentDate.daysInMonth();
For the number of week calculation, it depends if you only want the number of full weeks in a month, or the number of weeks, taking partial weeks into account.
For the latter, here is how I would do it (considering the week starts on monday) :
const DAYS_IN_WEEK = 7;
QDate CurrentDate = QDate::currentDate();
int DaysInMonth = CurrentDate.daysInMonth();
QDate FirstDayOfMonth = CurrentDate;
FirstDayOfMonth.setDate(CurrentDate.year(), CurrentDate.month(), 1);
int WeekCount = DaysInMonth / DAYS_IN_WEEK;
int DaysLeft = DaysInMonth % DAYS_IN_WEEK;
if (DaysLeft > 0) {
WeekCount++;
// Check if the remaining days are split on two weeks
if (FirstDayOfMonth.dayOfWeek() + DaysLeft - 1 > DAYS_IN_WEEK)
WeekCount++;
}
This code has not been fully tested and is not garanteed to work !
floor(Number of Days / 7)
QDate::weekNumber can give you the number of the week in the year.
Here is an example of how to use it to obtain the number of weeks in a month, including those shorter than seven days:
QDate dateCurrent = QDate::currentDate();
int year = dateCurrent.year(), month = dateCurrent.month(),
daysInMonth = dateCurrent.daysInMonth(), weeksInMonth;
weeksInMonth = QDate(year, month, daysInMonth).weekNumber()
- QDate(year, month, 1).weekNumber() + 1;
Some months have 4 weeks and others have 5. Qt states that:
In accordance with ISO 8601, weeks start on Monday and the first Thursday of a year is always in week 1 of that year. Most years have 52 weeks, but some have 53.
For that matter my first Thursday in a month is the starting point when counting the number of weeks in a month. The function below works for me:
int myClass::weeksInMonth(QDate cdate)
{
QDate sDte = QDate(cdate.year(),cdate.month(),1);
QDate eDte = QDate(cdate.year(),cdate.month(),cdate.daysInMonth());
int wks = 0;
for(QDate stD = sDte; stD <= eDte; stD = stD.addDays(1)){
if(stD.dayOfWeek() == Qt::Thursday)++wks;
}
return wks;
}
Here's a function that wraps the top answer for PyQt5. However the ISO 8601 definition for week 01 is the week with the first Thursday of the Gregorian year; this solution will give a negative number of weeks on dec and jan on certain years..
def weeksInMonth(date: QDate):
year = date.year(), month = date.month()
daysInMonth = date.daysInMonth()
return QDate(year, month, daysInMonth).weekNumber()[0] - QDate(year, month, 1).weekNumber()[0] + 1

Resources