Check if this Monday is last Monday in a month - c#

I use this code from another question:
private bool NthDayOfMonth(DateTime date, DayOfWeek dow, int n){
int d = date.Day;
return date.DayOfWeek == dow && (d-1)/7 == (n-1);
}
It works fine. But it not checks a last day ( for me it's when n = 5). How to modify it?
Thanks.

The method below checks the given date is the last date of week of month.
private bool IsLastOfMonth(DateTime date)
{
var oneWeekAfter = date.AddDays(7);
return oneWeekAfter.Month != date.Month;
}
So there is new method, it just checks mondays
private bool IsLastMonday(DateTime date)
{
if (date.DayOfWeek != DayOfWeek.Monday)
return false; // it is not monday
// the next monday is...
var oneWeekAfter = date.AddDays(7);
// and is it in same month?, if it is, that means its not last monday
return oneWeekAfter.Month != date.Month;
}

Lets take March 30,
d = 30,
(date.DayOfWeek == DayOfWeek.Friday) == true,
(30-1)=29, 29/7 = 4
4 == (5-1)
So it works
To only check if DayOfWeek is last in mothth you can use
return date.AddDays(7).Month != date.Month;

Related

how to get the get first Sunday of the month using date format?

Hi I need to check a condition for the first Sunday of the month for a date formatted as YYYYMMDD
var calDate = data.value; // example 20210502 is sunday
if (first Sunday of the month)
{
do this
}
else
{
do that
}
I need to check the above condition for the first Sunday of the month
Split your problem in two:
parse the string to a DateTime object
var date = DateTime.ParseExact(calDate, "yyyyMMdd", null);
Check if the DateTime object refers to the first sunday in a month. For this, it must obviously be a Sunday and the day part must be in the range 1 to 7:
var isFirstSunday = date.DayOfWeek == DayOfWeek.Sunday && date.Day <= 7;
Thsi function can return true or false if the date is first Sunday of the month or not
private static bool IsFirstSunday(DateTime date)
{
int i = 1;
while (i!=7)
{
if (date.Day==i && date.DayOfWeek == DayOfWeek.Sunday)
{
return true;
}
i++;
}
return false;
}
And use the result in your if condition
//First sunday
var date = DateTime.Parse("2021-05-02 11:27 AM");
var result = IsFirstSunday(date);
//Second sunday
date = DateTime.Parse("2021-05-09 11:27 AM");
result = IsFirstSunday(date);
//Non sunday
date = DateTime.Parse("2021-05-04 11:27 AM");
result = IsFirstSunday(date);
public static DateTime GetFirstSundayOfMonth(DateTime givenDate)
{
DateTime firstDayNextMonth = givenDate.AddDays(-givenDate.Day + 1).AddMonths(1);
int diff = 7 - (int)firstDayNextMonth.DayOfWeek;
return firstDayNextMonth.AddDays(diff);
}

How can I get total number of days in selected month with/without the weekends in WPF?

I am hoping to find a way to get the total number of days in a month with and without the weekends using LINQ in my ViewModel. For example, September would count for 20 days without weekends and 30 days with the weekends.
I also have a datepicker binding to MDate and I have no idea were to start.
Can someone please suggest an easy method? I am just an amateur.
private DateTime _mDate = DateTime.Now;
public DateTime MDate
{
get { return _mDate; }
set
{
if (value == _mDate)
{
return;
}
else
{
_mDate = value;
OnPropertyChanged("MDate");
SetDaysInMonth();
}
}
}
private void SetDaysInMonth()
{
???
}
Thank you.
DateTime.DayOfWeek method could come handy, and this answer by Ani shows how to get all days in a given month.
borrowing from the answer mentioned above:
public static List<DateTime> GetDates(int year, int month)
{
var dates = new List<DateTime>();
// Loop from the first day of the month until we hit the next month, moving forward a day at a time
for (var date = new DateTime(year, month, 1); date.Month == month; date = date.AddDays(1))
{
if(date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday)
{
dates.Add(date);
}
}
return dates;
}
int count = Enumerable.Range(1, DateTime.DaysInMonth(2017, 10)) // year and month
.Select(day => new DateTime(2017, 10, day)) // year and month
.Where(d => d.DayOfWeek != DayOfWeek.Sunday && d.DayOfWeek != DayOfWeek.Saturday) // check each day for weekend
.ToList().Count;
Hope you need only the no of working days in a month
Find the number of days in month then enumerate and excluded Saturday and Sunday.
private static void SetDaysInMonth(DateTime mDate)
{
int numberOfBusinessDays = Enumerable.Range(1, DateTime.DaysInMonth(mDate.Year, mDate.Month))
.Select(day => new DateTime(2017, mDate.Month, day))
.Count(d => d.DayOfWeek != DayOfWeek.Sunday && d.DayOfWeek != DayOfWeek.Saturday);
}

How do I determine if a date lies between current week dates?

In C#,
How we are check certain date with in week dates?
Eg: 6/02/2014
Current Weeks: 02/02/2014 - 08/02/2014
so this dates are with in above week....
Use this for check (last parameter is optional if you want always 1 week from fromDate, you don't need use last parameter):
public static bool DateInside(DateTime checkDate,
DateTime fromDate, DateTime? lastDate = null)
{
DateTime toDate = lastDate != null ? lastDate.Value : fromDate.AddDays(6d);
return checkDate >= fromDate && checkDate <= toDate;
}
To call use:
bool isDateInside = DateInside(new DateTime(2014, 02, 06),
new DateTime(2014, 02, 02)); // return true
And search first :) Answer is also here: How to check whether C# DateTime is within a range
If you want to check if the dates are inside the same week, then you can use this:
public static bool DateInsideOneWeek(DateTime checkDate, DateTime referenceDate)
{
// get first day of week from your actual culture info,
DayOfWeek firstWeekDay = System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek;
// or you can set exactly what you want: firstWeekDay = DayOfWeek.Monday;
// calculate first day of week from your reference date
DateTime startDateOfWeek = referenceDate;
while(startDateOfWeek.DayOfWeek != firstWeekDay)
{ startDateOfWeek = startDateOfWeek.AddDays(-1d); }
// fist day of week is find, then find last day of reference week
DateTime endDateOfWeek = startDateOfWeek.AddDays(6d);
// and check if checkDate is inside this period
return checkDate >= startDateOfWeek && checkDate <= endDateOfWeek;
}
Actual week in my culture info start with monday, February 3th 2014 (so for me is week between February 3th and February 9th). If I check any date with reference date (second parameter) as today (2014-Feb-06) I get this results:
For 2014-Feb-02 (Sunday before this week): false
For 2014-Feb-03 (Monday inside this week): true
For 2014-Feb-06 (Today inside this week): true
For 2014-Feb-09 (Sunday inside this week): true
For 2014-Feb-10 (Monday next week): false
You can call this method to check if one date is inside the same week as referentional like this:
DateInsideOneWeek(new DateTime(2014, 02, 02), new DateTime(2014, 02, 06));
You can find current week start and end dates with this code:
DateTime startDateOfWeek = DateTime.Now.Date; // start with actual date
while(startDateOfWeek.DayOfWeek != DayOfWeek.Monday) // set first day of week in your country
{ startDateOfWeek = startDateOfWeek.AddDays(-1d); } // after this while loop you get first day of actual week
DateTime endDateOfWeek = startDateOfWeek.AddDays(6d); // you just find last week day
Is this you wanted?
hmm
public bool isBetween(DateTime input, DateTime date1, DateTime date2)
{
if (input > date1 && input < date2)
return true;
else
return false;
}
?
input= your date
date1 & date2 = start and end of a week
How about:
bool inRange = (date >= lowerDate && date <= upperDate);
Here's another solution :)
public static class DateExtensions
{
private static void Swap<T>(ref T one, ref T two)
{
var temp = one;
one = two;
two = temp;
}
public static bool IsFromSameWeek(this DateTime first, DateTime second, DayOfWeek firstDayOfWeek = DayOfWeek.Monday)
{
// sort dates
if (first > second)
{
Swap(ref first, ref second);
}
var daysDiff = (second - first).TotalDays;
if (daysDiff >= 7)
{
return false;
}
const int TotalDaysInWeek = 7;
var adjustedDayOfWeekFirst = (int)first.DayOfWeek + (first.DayOfWeek < firstDayOfWeek ? TotalDaysInWeek : 0);
var adjustedDayOfWeekSecond = (int)second.DayOfWeek + (second.DayOfWeek < firstDayOfWeek ? TotalDaysInWeek : 0);
return adjustedDayOfWeekSecond >= adjustedDayOfWeekFirst;
}
}
Upd: it appears to have at least twice better performance than #Atiris solution :)

Run through loop for week and don't select weekends

So the user can select 2 different dates, a start date and an end date from 2 calendars, when they click add the dates between&including the dates selected will be added to the Database, each date as a separate record.
This works fine however I don't want weekends to be added to the Database.
I've updated the UI of datepicker http://www.kelvinluck.com/assets/jquery/datePicker/v2/demo/datePickerCustomCellRender.html
but if a user selects fri-mon for example fri,sat,sun and mon will be added to the Database.
I've tried to only run the code if datyofweek is not saturday or sunday
public ActionResult listHolidays(Holiday holiday, int? PersonId, string HolidayDate, string endDate)
{
DateTime startDates = Convert.ToDateTime(HolidayDate),
endDates = Convert.ToDateTime(endDate);
while (startDates <= endDates)
{
if (startDates.DayOfWeek != DayOfWeek.Saturday || startDates.DayOfWeek != DayOfWeek.Sunday)
{
Holiday holiday1 = new Holiday();
holiday1.PersonId = PersonId.Value;
holiday1.HolidayDate = startDates;
db.Holidays.AddObject(holiday1);
db.SaveChanges();
startDates = startDates.AddDays(1);
}
}
return RedirectToAction("Index");
}
any help?
Thanks
You need to use AND instead of OR:
if (startDates.DayOfWeek != DayOfWeek.Saturday && startDates.DayOfWeek != DayOfWeek.Sunday)
Your current condition will always be true. If startDates is DayOfWeek.Saturday, it is not DayOfWeek.Sunday and vice versa.
After that, you need to put the startDates = startDates.AddDays(1); outside the if.
Otherwise, you would have an endless loop, because as soon as startDates is DayOfWeek.Saturday, it will no longer be incremented.
Change
if (startDates.DayOfWeek != DayOfWeek.Saturday || startDates.DayOfWeek != DayOfWeek.Sunday)
To
if (startDates.DayOfWeek != DayOfWeek.Saturday && startDates.DayOfWeek != DayOfWeek.Sunday)
You'll then need to move this line
startDates = startDates.AddDays(1);
To outside of the if block (otherwise the startDates variable will never change if the date is a weekend date).
If statement is wrong and day increment in wrong place.
while (startDates <= endDates)
{
if (startDates.DayOfWeek != DayOfWeek.Saturday **&&** startDates.DayOfWeek != DayOfWeek.Sunday)
{
Holiday holiday1 = new Holiday();
holiday1.PersonId = PersonId.Value;
holiday1.HolidayDate = startDates;
db.Holidays.AddObject(holiday1);
db.SaveChanges();
}
**startDates = startDates.AddDays(1);**
}
Just as an alternative solution for you for calculating how many week days you have selected
List<DateTime> allDates = New List<DateTime>();
for (DateTime date = startingDate; date <= endingDate; date = date.AddDays(1))
allDates.Add(date);
var days = allDates.Where(x => x.IsWeekday()).Count();
Using the following DateTime extension.
public static class DateTimeExtensions
{
public static bool IsWeekday(this DateTime dt)
{
return dt.DayOfWeek != DayOfWeek.Sunday && dt.DayOfWeek != DayOfWeek.Saturday;
}
}
As per my comment, you can extend this to an IsWorkday if it is for a holiday system and encorporate some logic for checking if the day is a bank holiday.

How to add a number of days to a Date while skipping weekends and other holidays

Given a Date. How can I add a number of days to it while skipping weekends and other holidays coming between the range?
List <DateTime> holidays = new List<DateTime>()
{
new DateTime(2012, 01, 03),
new DateTime(2012, 01, 26)
};
dateTimeReview.Value = CalculateFutureDate(dateTimeStart.Value, 7,holidays);
static DateTime CalculateFutureDate(DateTime fromDate, int numberofWorkDays, ICollection<DateTime> holidays)
{
var futureDate = fromDate;
for (var i = 0; i < numberofWorkDays; i++ )
{
if (futureDate.DayOfWeek == DayOfWeek.Saturday
|| futureDate.DayOfWeek == DayOfWeek.Sunday
|| (holidays != null && holidays.Contains(futureDate)))
{
futureDate = futureDate.AddDays(1); // Increase FutureDate by one because of condition
futureDate = futureDate.AddDays(1); // Add a working day
}
}
return futureDate;
}
To skip holidays you will first need to create your own list of holidays. Holidays are different in every country and also subject to other factors.
Then you should add days one by one in a loop with a check if the added day is not a weekend day and does not occur in the list of holidays, until the given number of days has been added.
Unfortunately, there is no easier way to do this.
I tried the code above and didn't work. The returned date will somehow includes the holidays and weekends as well. I also want to check that the returned date to be on Workdays only.
So, below are my modified codes.
Basically it will calculate the number of workdays to be added and if the end date falls on holidays/weekends, shift the date to the next day.
Do take note that this is on an assumption that the start date is not on weekends/holidays.
static DateTime CalculateFutureDate(DateTime fromDate, int numberofWorkDays,
ICollection<DateTime> holidays)
{
var futureDate = fromDate;
for (var i = 0; i < numberofWorkDays; i++ )
{
if (futureDate.DayOfWeek == DayOfWeek.Saturday
|| futureDate.DayOfWeek == DayOfWeek.Sunday
|| (holidays != null && holidays.Contains(futureDate)))
{
futureDate = futureDate.AddDays(1);
numberofWorkDays++;
}
else
{
futureDate = futureDate.AddDays(1);
}
}
while(futureDate.DayOfWeek == DayOfWeek.Saturday
|| futureDate.DayOfWeek == DayOfWeek.Sunday
|| (holidays != null && holidays.Contains(futureDate)))
{
futureDate = futureDate.AddDays(1);
}
return futureDate;
}
I've built something similar to check for Office Hours:
public static DateTime AddBusinessHours(DateTime date, long hours)
{
int i = 0;
DateTime tmpDate = date;
do
{
tmpDate = tmpDate.AddHours(1);
if (!IsWeekend(tmpDate) && !IsHoliday(tmpDate) && IsOfficeHours(tmpDate))
i++;
}
while (i < hours);
return tmpDate;
}
public static bool IsWeekend(DateTime date)
{
return (date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday);
}
public static bool IsHoliday(DateTime date)
{
//All dates in the holiday calendar are without hours and minutes.
//With the normal date object, the Contains does not work.
DateTime tmp = new DateTime(date.Year, date.Month, date.Day);
HolidayCalendar calendar = HolidayCalendar.Instance;
return (calendar.Dates.Contains(tmp));
}
public static bool IsOfficeHours(DateTime date)
{
return (date.Hour >= 8 && date.Hour < 20); //Office Hours are between 8AM and 8PM
}
But as mentioned above, you need to run your own holiday calendar.
public static DateTime AddBusinessDays(DateTime pActualDate, int pNumberofWorkDays)
{
ICollection<DateTime> holidays = GetAllHolidays();
int i = default(int);
while (i < pNumberofWorkDays)
{
pActualDate = pActualDate.AddDays(1);
if (pActualDate.DayOfWeek == DayOfWeek.Saturday || pActualDate.DayOfWeek == DayOfWeek.Sunday
|| (holidays != null && holidays.Contains(pActualDate))) { }
else
{ i++; }
}
return pActualDate;
}
private static ICollection<DateTime> GetAllHolidays()
{
ICollection<DateTime> holidays = GetPublicHolidays().Select(s => s.Holidays).ToList();
HashSet<DateTime> finalHolidays = new HashSet<DateTime>();
//if sunday holiday then the following monday will be holiday
bool isMonday = GetCalendar().Any(s => s.Type == "KR" && s.IsMonday);
foreach (var hol in holidays)
{
if (hol.DayOfWeek == DayOfWeek.Sunday && isMonday)
{
//adding monday following day holiday to the list
finalHolidays.Add(hol.AddDays(1));
}
}
//exclude weekends from the holiday list
var excludeWeekends = holidays.Where(s => s.DayOfWeek == DayOfWeek.Sunday || s.DayOfWeek == DayOfWeek.Saturday);
//adding monday to the existing holiday collection
finalHolidays.UnionWith(holidays.Except(excludeWeekends));
return finalHolidays;
}

Categories

Resources