Calendar selection based on working days using C# - c#

I have to selected the based dates for days calculation based on Working days (eg: 5.0, 5.5, 6.0).
when i select based on 5.5 days, I would like to calculate automatically.
Kindly help me to solve this issues.
private void SelectionChanged(SelectionChangedEventArgs obj)
{
if(Settings.WorkingDay == "5.0")
{
// Code is working fine
}
else if(Settings.WorkingDay == "5.5")
{
startDate = SelectedRange.StartDate.Date;
endDate = SelectedRange.EndDate.Date;
startDate.AddDays(1);
int days = 0;
for (DateTime date = startDate; date <= endDate; date = date.AddDays(1))
{
if (startDate.DayOfWeek != DayOfWeek.Sunday)
{
days++;
}
startDate = startDate.AddDays(1);
}
if(startDate.DayOfWeek != DayOfWeek.Saturday && endDate.DayOfWeek != DayOfWeek.Saturday)
{
Quantity = (days) - (Convert.ToDecimal(0.5));
}
else if(startDate.DayOfWeek != DayOfWeek.Saturday)
{
Quantity = (days);
}
Debug.WriteLine(Quantity.ToString());
}
else if(Settings.WorkingDay == "6.0")
{
// Code is working fine
}
}

try this
double qty = 0.0;
for (DateTime date = startDate; date <= endDate; date = date.AddDays(1))
{
if (date.DayOfWeek == DayOfWeek.Sunday)
{
// do nothing
}
elseif (date.DayOfWeek == DayOfWeek.Saturday)
{
qty += 0.5;
}
else
{
qty ++ 1;
}
}

Related

Get the Friday and Saturday night of each day

The problem is that I need to find each Saturday and Friday night and charge them $140 on Friday or Saturday. Should I use a while loop?
DateTime ArrivalDate = DateTime.Parse(txtArrivalDate.Text);
DateTime DepartureDate = DateTime.Parse(txtDepartureDate.Text);
TimeSpan numberOfNights = DepartureDate.Subtract(ArrivalDate);
decimal nights = numberOfNights.Days;
txtNights.Text = nights.ToString();
//txtTotalPrice
decimal pricePerNight = 120.00m;
decimal totalNight = nights * pricePerNight;
txtTotalPrice.Text = "$" + totalNight.ToString();
txtAvgPrice.Text = "$" + pricePerNight.ToString();
// finds the fridays
decimal morePricePerNight = 140.00m;
int i = 0;
// while loop
while (ArrivalDate.DayOfWeek != DayOfWeek.Friday)
{
ArrivalDate = ArrivalDate.AddDays(1);
}
while (DepartureDate.DayOfWeek != DayOfWeek.Friday)
{
DepartureDate = DepartureDate.AddDays(1);
}
Why not to use just a one while loop?
I guess you can write the following code:
var date = DepartureDate;
while (date < ArrivalDate)
{
if (date.DayOfWeek == DayOfWeek.Friday || date.DayOfWeek == DayOfWeek.Saturday)
{
totalNight += 140.00m;
}
date = date.AddDays(1);
}

pairing and calculating the hours of checkTypes

Continuing from here, I have a table named Attendancelogs which has all the sorted logs CHeckTypes In and Out accordingly. (Thanks to #StephenMuecke the previous question was pretty much resolved) However, what I am trying to achieve next is to make a pairList of all the In and Out in a particular period (StartDate and EndDate) and then calculate the total hours of the employee.
Different Cases, already been taken care of in the previous question
I have two method, one called getSingleDevicePairs(int EnrollNumber, DateTime StartDate, DateTime EndDate) which creates the pairList and the second method getTimeSpentEachDay(List<Pair> pairList) which calculates the total hours of each day.
Pair.cs
public class Pair {
public int id { get; set; }
public int RegisterationId { get; set; }
public int EmpID { get; set; }
public DateTime InnDateTime { get; set; }
public DateTime OutDateTime { get; set; }
}
public List<Pair> getSingleDevicePairs(int EnrollNumber, DateTime StartDate, DateTime EndDate) {
DateTime today = DateTime.Now;
List<Pair> pairList = new List<Pair>();
var logs = db.AttendanceLogs.Where(x => x.RegisterationId == EnrollNumber && x.Date >= StartDate &&
x.Date <= EndDate && x.isIgnore != true && (x.CheckType == "In" || x.CheckType == "Out")).Distinct().ToList();
int loopEnd = 0;
bool oddLogs = false;
if (logs.Count % 2 == 0) {
loopEnd = logs.Count;
} else {
loopEnd = logs.Count - 1;
oddLogs = true;
}
bool inn = true;
if (loopEnd > 1) {
Pair pair = new Pair();
for (int v = 0; v < loopEnd; v++) {
if (inn) {
pair.InnDateTime = logs[v].DateTime;
inn = false;
} else {
pair.OutDateTime = logs[v].DateTime;
inn = true;
pairList.Add(pair);
pair = new Pair();
}
}
}
Bogus bogus = new Bogus();
DateTime bogusDate = new DateTime();
if (oddLogs) {
bogus.MachineNum = logs[logs.Count - 1].DeviceID;
bogus.RegisterationId = logs[logs.Count - 1].RegisterationId;
bogus.DateTime = logs[logs.Count - 1].DateTime;
bogusDate = logs[logs.Count - 1].DateTime;
}
return pairList;
}
^I changed the above method with different approach, since the above approach would mess up with Case 1 shown in the link above.
public List<Pair> getSingleDevicePairs(int EnrollNumber, DateTime StartDate, DateTime EndDate) {
DateTime today = DateTime.Now;
List<Pair> pairList = new List<Pair>();
var logs = db.AttendanceLogs.Where(x => x.RegisterationId == EnrollNumber && x.Date >= StartDate &&
x.Date <= EndDate && x.isIgnore != true && (x.CheckType == "In" || x.CheckType == "Out")).Distinct().ToList();
bool isCheck = false;
Pair pair = new Pair();
DateTime previous = logs.FirstOrDefault().DateTime;
foreach (var log in logs) {
if (!isCheck) {
pair.InnDateTime = log.DateTime;
isCheck = true;
} else {
pair.OutDateTime = log.DateTime;
isCheck = false;
}
pairList.Add(pair);
pair = new Pair();
}
return pairList;
}
^This approach again will fail at Case 1 as it is sequentially adding In and Out in the pairList.
public List<DateAndTime> getTimeSpentEachDay(List<Pair> pairList) {
List<DateAndTime> list = new List<DateAndTime>();
if (pairList.Count > 0) {
for (int i = 0; i < pairList.Count; i++) {
TimeSpan span = TimeSpan.Zero;
// bool flag = false;
int result = -1;
do {
span = span + (pairList[i].OutDateTime - pairList[i].InnDateTime);
result = -1;
if (i < pairList.Count - 1) {
DateTime p = (DateTime)pairList[i].InnDateTime;
DateTime q = (DateTime)pairList[i + 1].InnDateTime;
result = DateTime.Compare(p.Date, q.Date);
}
if (result == 0) {
i++;
// flag = true;
}
} while (result == 0);
//if (i == pairList.Count - 1)
//{
// span = span + (pairList[i].OutDateTime - pairList[i].InnDateTime) ?? TimeSpan.Zero;
//}
DateAndTime dnt = new DateAndTime();
dnt.date = ((DateTime)pairList[i].InnDateTime).ToString("yyyy-MM-dd");
dnt.Time = span;
list.Add(dnt);
}
}
return list.ToList();
}
I am trying to get total hours for each pair as well as a way to take the odd In's together which I can display on the calendar.
Below is an image of the calendar view for an employee which displays only the paired hours, I even want to show a In that would indicate the employee that he either forgot to check out or a missing entry was made.
*Lets say he had a checkin for 9th April of around 08:00 PM that had no Check out on that day and also in the NightersLimit (12 AM - 7 AM) then there should be a single line displayed on the calendar which can only happen if I bring the bogus record for a day from previous method.
There is nothing wrong with the getTimeSpentEachDay(); just a little changes in the getSingleDevicePairs(); method, your first approach fails since it eliminates the last entry of the logs in case of an odd number and your second approach fails since it is not taking account of the sequence the logs are stored in the table.
public List<Pair> getSingleDevicePairs(int EnrollNumber, DateTime StartDate, DateTime EndDate, int? missingEntry)
{
var logs = db.AttendanceLogs.Where(x => x.RegisterationId == EnrollNumber &&
x.Date >= StartDate && x.Date <= EndDate && x.isIgnore != true
&& (x.CheckType == "In" || x.CheckType == "Out")).Distinct().ToList();
if (logs.Count > 0)
{
bool isCheck = false;
Pair pair = new Pair();
DateTime previous = logs.FirstOrDefault().DateTime;
foreach (var log in logs)
{
if (!isCheck)
{
if (log.CheckType == "In")
{
pair.InnDateTime = log.DateTime;
isCheck = true;
}
}
else
{
if (log.CheckType == "Out")
{
pair.OutDateTime = log.DateTime;
isCheck = false;
pairList.Add(pair);
pair = new Pair();
}
if (pair.OutDateTime == DateTime.MinValue)
{
pair.InnDateTime = log.DateTime;
}
}
}
}
return pairList;
}
This completes the pair only when there is an Out for an In.

C# check if current date is 1, 2 or 3 of the month, ignore weekend and additional List<DateTime>

I need to check if DateTime.Now is in the first 3 business days of each month (from Mon - Fri). I also need to provide a List<DateTime> with national holidays and these should be handled accordingly.
If DateTime.Now is Saturday and is 1 of the month, first 3 business days are Monday, Tuesday, Wednesday (3, 4, 5 of the month).
public bool IsBusinessDay()
{
DateTime now = DateTime.Now;
DateTime fbd = new DateTime();
DateTime sbd = new DateTime();
DateTime tbd = new DateTime();
DateTime fm = new DateTime(now.Year, now.Month, 1);
DateTime sm = new DateTime(now.Year, now.Month, 2);
DateTime tm = new DateTime(now.Year, now.Month, 3);
// first business day
if (fm.DayOfWeek == DayOfWeek.Sunday)
{
fbd = fm.AddDays(1);
}
else if (fm.DayOfWeek == DayOfWeek.Saturday)
{
fbd = fm.AddDays(2);
}
else
{
fbd = fm;
}
//second business day
if (sm.DayOfWeek == DayOfWeek.Sunday)
{
sbd = sm.AddDays(1);
}
else if (sm.DayOfWeek == DayOfWeek.Saturday)
{
sbd = sm.AddDays(2);
}
else
{
sbd = sm;
}
//third business day
if (tm.DayOfWeek == DayOfWeek.Sunday)
{
tbd = tm.AddDays(1);
}
else if (tm.DayOfWeek == DayOfWeek.Saturday)
{
tbd = tm.AddDays(2);
}
else
{
tbd = tm;
}
if (now == fdb || now == sbd || now == tbd)
{
return true;
}
return false;
}
Is this a good approach? How can I add a List<DateTime> with holidays and check that the current date is not holiday?
I have a feeling I'm over thinking this, and thinking it in a bad way. I don't know why but same feeling tells me there is an easier way to do it.
This should do what you want. You'll have to supply the set of holidays.
public static bool IsFirstThreeBusinessDays(DateTime date, HashSet<DateTime> holidays)
{
DateTime dt = new DateTime(date.Year, date.Month, 1);
int businessDaysSeen = 0;
while (businessDaysSeen < 3)
{
if (dt.DayOfWeek != DayOfWeek.Saturday &&
dt.DayOfWeek != DayOfWeek.Sunday &&
!holidays.Contains(dt))
{
if (dt == date.Date)
{
return true;
}
businessDaysSeen++;
}
dt = dt.AddDays(1);
}
return false;
}
You can also do this using LINQ.
public static bool IsFirstThreeBusinessDays(DateTime date, HashSet<DateTime> holidays)
{
var query =
Enumerable.Range(1, DateTime.DaysInMonth(date.Year, date.Month))
.Select(o => new DateTime(date.Year, date.Month, o))
.Where(o => o.DayOfWeek != DayOfWeek.Saturday && o.DayOfWeek != DayOfWeek.Sunday
&& !holidays.Contains(o))
.Take(3);
return query.Contains(date);
}
EDIT: I didn't read the question carefully enough, although parts of my old answer are still applicable. The approach I would take here is to create a method that enumerates the business days of the month, then take 3 from that.
Here's how:
public static IEnumerable<DateTime> BusinessDaysOfMonth(DateTime time)
{
var month = new DateTime(time.Year, time.Month, 1);
var nextMonth = month.AddMonths(1);
var current = month;
while(current < nextMonth)
{
if (IsWeekday(current) && !IsHoliday(current))
{
yield return current;
}
current = current.AddDays(1);
}
}
(note that some methods are taken from below). Then, all you need where you want to use this is:
// Get first three business days
var firstThreeBizDays = BusinessDaysOfMonth(DateTime.Now).Take(3);
// Check if today is one of them
var result = firstThreeBizDays.Contains(DateTime.Today);
OLD ANSWER:
Ok, so it looks like there's three conditions you need to ensure. They are:
It is the 1st, 2nd, or 3rd day of the month
It is not Saturday or Sunday
The current date is not contained in some set of dates representing holidays
This translates fairly straightforwardly to code:
public static bool IsFirstThreeDays(DateTime time) => time.Day < 4;
public static bool IsWeekday(DateTime time)
{
var dow = time.DayOfWeek;
return dow != DayOfWeek.Saturday && dow != DayOfWeek.Sunday;
}
public bool IsHoliday(DateTime time)
{
ISet<DateTime> holidays = ??; // Decide whether this is a member or an arg
return holidays.Contains(time.Date);
}
Note that the holidays set needs to contain the Day component of any DateTime from each holiday.
Now your method is presumably just:
public static bool IsDayWhatYouWant()
{
var now = DateTime.UtcNow;
return IsFirstThreeDays(now) && IsWeekday(now) && !IsHoliday(now);
}

Why won't my Monthcalendar accept today's date?

This question might sound very vague but I do not know how to phrase it in a better fashion.
I've been working on a month calendar that checks if the 2 selected dates are correct. There is 1 calender that uses to following code to figure out who called the event (The startdate textbox or enddate textbox)
MaskedTextBox b = (MaskedTextBox)sender;
currentSelectedDateBox = b.Name;
The startdate must be sooner than the enddate, both startdate and enddate can't be a date that already has a reservation(it shows a reservation by making the date bold), and the selected period can not have a reservation in it.
This is all working fine, although I have one problem: When I open the calendar and click on today, it closes, meaning the user has selected a date, although no date shows up and when I try to print the selected date: it won't print anything. If I select a different date, though, it will print that date, meaning that all dates can be selected except today.
If I click on a different day and then select today, it will work. This is really weird and I'm stuck.
Here's my code:
private void monthCalendar_DateChanged(object sender, DateRangeEventArgs e)
{
ErrorStartDateLabel.Visible = false;
ErrorEndDateLabel.Visible = false;
startdateLabel.ForeColor = Color.Black;
enddateLabel.ForeColor = Color.Black;
string day = monthCalendar.SelectionStart.Day.ToString();
string month = monthCalendar.SelectionStart.Month.ToString();
if (day.Length == 1) //part of the stringbuilder
{
day = "0" + day;
}
if (month.Length == 1) //part of the stringbuilder
{
month = "0" + month;
}
string date = day + "-" + month + "-" + monthCalendar.SelectionStart.Year.ToString(); //Date selected
if (startdateTextbox.Name == currentSelectedDateBox) //If the StartDate Calendar has been selected
{
startdateTextbox.Text = date;
startdate = monthCalendar.SelectionStart.Date;
}
else if (enddateTextbox.Name == currentSelectedDateBox)//If the EndDate Calendar has been selected
{
enddateTextbox.Text = date;
enddate = monthCalendar.SelectionStart.Date;
secondDateChecked = true;
}
if (secondDateChecked) //if the enddate textbox has data
{
if (enddate < startdate) //if enddate is smaller than the startdate
{
enddateTextbox.Text = "";
ErrorEndDateLabel.Text = "Uw gekozen huurperiode klopt niet!";
ErrorEndDateLabel.ForeColor = Color.Red;
enddateLabel.ForeColor = Color.Red;
ErrorEndDateLabel.Visible = true;
}
}
if (carHasReservation == true) //If there is a reservation
{
foreach (var bolddate in bolddates) //loop through all bolded dates
{
if (startdate == bolddate || enddate == bolddate)//if the startdate OR enddate is a bolded date
{
if (startdate == bolddate)
{
startdateTextbox.Text = "";
ErrorStartDateLabel.Text = "Deze startdatum is al gereserveerd!";
ErrorStartDateLabel.ForeColor = Color.Red;
ErrorStartDateLabel.Visible = true;
}
else
{
enddateTextbox.Text = "";
ErrorEndDateLabel.Text = "Deze einddatum is al gereserveerd!";
ErrorEndDateLabel.ForeColor = Color.Red;
ErrorEndDateLabel.Visible = true;
}
}
if (startdate <= enddate)
{
TimeSpan tisp = enddate - startdate;
int dateDiffer = tisp.Days;
for (int i = 0; i <= dateDiffer; i++) //Count the amount of days between the startdate and the enddate. For every day, check if one of those days is a bolded(reservation) date
{
if (startdate.AddDays(i) == bolddate)
{
reservationCollision = true;
}
}
}
}
}
else
{
//No reservation, do nothing!
}
if (reservationCollision) //if there is a boldeddate between the selected dates
{
ErrorStartDateLabel.Text = "Tijdens uw geselecteerde periode";
ErrorEndDateLabel.Text = " is er al een reservering geplaatst!";
ErrorStartDateLabel.ForeColor = Color.Red;
ErrorEndDateLabel.ForeColor = Color.Red;
startdateLabel.ForeColor = Color.Red;
enddateLabel.ForeColor = Color.Red;
ErrorStartDateLabel.Visible = true;
ErrorEndDateLabel.Visible = true;
enddateTextbox.Text = "";
reservationCollision = false;
}
}
My explanation and code might be a bit vague, I'm sorry for that. I thought it would be better to add more information than necessary instead of giving a bad explanation of my problem and code.

How to determine if a date it was yesterday, in the last month, in the last year using c#?

I would like to determine if a DateTime was yesterday, if it was in the last month and if it was in the last year.
For example if today is 2013. 10. 21. then 2013. 10. 20. was yesterday, 2013. 09. 23. was in the last month and 2012. 03. 25. was in the last year.
How can i determine these using c#?
// myDate = 2012.02.14 ToDate ... you know
if (myDate == DateTime.Today.AddDays(-1);)
Console.WriteLine("Yestoday");
else if (myDate > DateTime.Today.AddMonth(-1) && myDate < DateTime.Today)
Console.WriteLine("Last month");
// and so on
it needs test and fixes, but it is the way ;)
bool IsYesterday(DateTime dt)
{
DateTime yesterday = DateTime.Today.AddDays(-1);
if (dt >= yesterday && dt < DateTime.Today)
return true;
return false;
}
bool IsInLastMonth(DateTime dt)
{
DateTime lastMonth = DateTime.Today.AddMonths(-1);
return dt.Month == lastMonth.Month && dt.Year == lastMonth.Year;
}
bool IsInLastYear(DateTime dt)
{
return dt.Year == DateTime.Now.Year - 1;
}
I think testing like this could do the trick:
if(new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).AddMonths(-1) > dateToTestIfLastMonth){
http://msdn.microsoft.com/en-us/library/8ysw4sby.aspx
You can subtract dates then check the timespan object.
Straightforward implementation:
public enum DateReference {
Unknown,
Yesterday,
LastMonth,
LastYear,
}
public static DateReference GetDateReference(DateTime dateTime) {
var date = dateTime.Date;
var dateNow = DateTime.Today;
bool isLastYear = date.Year == dateNow.Year - 1;
bool isThisYear = date.Year == dateNow.Year;
bool isLastMonth = date.Month == dateNow.Month - 1;
bool isThisMonth = date.Month == dateNow.Month;
bool isLastDay = date.Day == dateNow.Day - 1;
if (isLastYear)
return DateReference.LastYear;
else if (isThisYear && isLastMonth)
return DateReference.LastMonth;
else if (isThisYear && isThisMonth && isLastDay)
return DateReference.Yesterday;
return DateReference.Unknown;
}

Categories