Why won't my Monthcalendar accept today's date? - c#

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.

Related

Calendar selection based on working days using 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;
}
}

How to change the color of a Cell in a DataGridView if date is 1 month before what is in the cell?

I'v been looking through a LOT of websites and i did not find any awnser,
So let's say I have a DataGridView with a Column and the Rows are (assuming today's date is 21/05/2019 (dd/mm/yyyy))
22/05/2019
22/04/2019
21/01/2019
So I want the first one to be in red (because its 1 day off today's date)
I want the second one to be in orange (because it entered the -1 month mark)
And the last one should be normal because its far from -1 month.
I've tryed this:
var dateminusonemonth = DateTime.Today.AddMonths(-1);
foreach (DataGridViewRow row in dgproduit.Rows)
if (Convert.ToString(dateminusonemonth) = txtboxdatecontrole.Text)
{
row.DefaultCellStyle.BackColor = Color.Red;
}
But it doesn't work at all and I dont know where to look at...
EDIT : This is what i want, but i cant get it to work Change row color in DataGridView based on column date
EDIT : It worked ! with this code :
DateTime now = DateTime.Now, thirtyDaysAgo = now.AddDays(-30), expirationDate;
foreach (DataGridViewRow row in dgproduit.Rows)
{
string cellText = row.Cells["datecontrole"].Value + "";
if (DateTime.TryParse(cellText, out expirationDate))
{
if (expirationDate < now)
row.DefaultCellStyle.BackColor = Color.OrangeRed;
else if (expirationDate > thirtyDaysAgo)
row.DefaultCellStyle.BackColor = Color.LightBlue;
}
}
Whenever you have sequences of items, LINQ is your best friend
Assuming the column that shows the dates that you want to color is columnDate
DataGridViewColumn columnDate = ...
DataGridView myDataGridView = ...
var dateCells = myDataGridView.Rows.Cast<DataGridViewRow>()
.Select(row => row.Cells[columnDate.Name])
.Select(dateCell => new
{
DataGridViewCell = dateCell,
Date = DateTime.Parse(dateCell.Value.ToString()).Date,
});
So Date contains the Date part of the displayed value in the DateCell. If you don't want to compare on Date, but on a TimeSpan of 24 hours, you should remember the DateTime.
Date = DateTime.Parse(dateCell.Value.ToString());
Now to get the cells that you want to colorize:
DateTime today = DateTime.Today;
// The cells that have a date between (today - 1 day) and (today + 1 day) should be red:
var todayMinus1Day = today.AddDays(-1);
var todayPlus1Day = today.AddDays(+1);
var todayMinus1Month = today.AddMonths(-1);
var todayPlus1Month = today.AddMonths(+1)
foreach (var cell in dateCells)
{
if (todayMinus1Month <= cell.Date && cell.Date <= todayPlus1Month)
{
// either orange or red: not default:
cell.DataGridViewCell.Style = cell.DataGridViewCell.GetInheritedStyle();
cell.DataGridViewCell.Style.BackColor =
(todayMinums1Day <= cell.Date && cell.Date <= todayPlus1Day) ?
Color.Red : Color.Orange;
}
else
{ // use the inherited style = set the cell style to null
cell.DataGridViewCell.Style = null;
}
}
I can't understand what exactly you need but I will try.
var dateminusonemonth = DateTime.Today.AddMonths(-1);
foreach (DataGridViewRow row in dgproduit.Rows)
{
DateTime DateToComapre = Datetime.Parse(row.Cells[Cell with you Date to Comapre].value); //Date format must match!
if (DateTime.Now < DateToCompare)
{
row.DefaultCellStyle.BackColor = Color.Red;
}
else if (dateminusonemonth < DateToCompare && DateToCompare < DateTime.Now)
{
row.DefaultCellStyle.BackColor = Color.Orange;
}
else
{
drow.RowHeadersDefaultCellStyle.SelectionBackColor = Color.Empty;
}
}

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# WinForm error import from excel to database

Hei. I need to understand why I receive an error like that :
C# windows form import from excel error
I can't separe the year from string (year time). Or, can I renounce at split and import directly the string as "date"? Sorry, I'm too beginner in c#, but I need this help, is a task for me.
Here is my code :
for (int i = 0; i < dvColumns.Count; i++)
{
string columnName = string.Empty;
string columnField = string.Empty;
if ((dvColumns[i]["Header"] != null) && (!Convert.IsDBNull(dvColumns[i]["Header"])))
{
columnName = dvColumns[i]["Header"].ToString();
}
if ((dvColumns[i]["Field"] != null) && (!Convert.IsDBNull(dvColumns[i]["Field"])))
{
columnField = dvColumns[i]["Field"].ToString();
}
rangeObject = cellsObject.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, cellsObject, new object[] { row, i + 1 });
object valueObject = rangeObject.GetType().InvokeMember("Value", BindingFlags.GetProperty, null, rangeObject, null);
if (columnName == "FiscalCode" && columnField == "PartnerId")
{
string fiscalCode = Erp.Core.Utils.GetStringFromObject(valueObject);
partnerId = p.GetPartnerIdByFiscalCode(fiscalCode);
eventRow["PartnerId"] = partnerId;
}
else if (columnField == "StartDate" || columnField == "EndDate")
{
string date = Erp.Core.Utils.GetStringFromObject(valueObject);
DateTime columnDate = DateTime.Now;
string[] dateComponents = null;
int year = 0;
int month = 0;
int day = 0;
if (date.Contains("."))
{
dateComponents = date.Split('.');
}
if (date.Contains("/"))
{
dateComponents = date.Split('/');
}
if (date.Contains(":"))
{
dateComponents = date.Split(':');
}
if (dateComponents.Length > 1)
{
string s = dateComponents[0];
day = Erp.Core.Utils.GetIntFromObject(s);
s = dateComponents[1];
month = Erp.Core.Utils.GetIntFromObject(s);
s = dateComponents[2];
year = Erp.Core.Utils.GetIntFromObject(s);
columnDate = new DateTime(year, month, day, 9, 0, 0);
}
eventRow[columnField] = columnDate;
}
else if (columnField != "PartnerId" && columnField != "StartDate" && columnField != "EndDate")
{
eventRow[columnField] = valueObject;
}
}
I tried to keep in excel same format as in database table : 'yyyy/mm/dd hh:mm:ss.000'.
The line date = Erp.Core.Utils.GetStringFromObject(valueObject); get my date from first excel cell.
ds.Tables["Events"] is all time empty.
I know this line eventRow[columnField] = date; must add the dates in DB, really? After split, day is ok (receive an int by s[0]), month is ok (receive an int by s[1], but s[2] for year is something like 2017 19:06:22 .... year plus time). I tried to split again by space, but without results, to keep the number (2017) in year variable.
Best way is to use DateTime.ParseExact method. In your case, if original format is 'yyyy/mm/dd hh:mm:ss.000', you can convert it to DateTime like this:
//string date = Erp.Core.Utils.GetStringFromObject(valueObject);
string date = "2017/08/15 10:20:30.000";
DateTime columnDate = DateTime.ParseExact(date, "yyyy/MM/dd HH:mm:ss.fff", CultureInfo.InvariantCulture);
This way you can skip parsing excel string.
In your example, usage will be like this:
//...snip...
else if (columnField == "StartDate" || columnField == "EndDate")
{
string date = Erp.Core.Utils.GetStringFromObject(valueObject);
//parsing date string
DateTime columnDate = DateTime.ParseExact(date, "yyyy/MM/dd HH:mm:ss.fff", CultureInfo.InvariantCulture);
eventRow[columnField] = columnDate;
}
else if (columnField != "PartnerId" && columnField != "StartDate" && columnField != "EndDate")
{
eventRow[columnField] = valueObject;
}
if hours are in 12-hour format, use lowercase hh, like this "yyyy/MM/dd hh:mm:ss.fff"

Randomly change the backcolor of selected dates in calendar asp.net C#

Using calendar control in Visual Studio for the web 2012, I am able to take dates from the SQL Server 2012 database (i.e to date and from date and highlight this dates in the calendar) I am also able to highlight the dates in-between the to date and from date.
All in all in my calendar at the moment I have dates 02/10/2013 (to date) and 04/10/2013 (from date) highlighted in the calendar and the dates in-between these dates. And also 15/10/2013 (to date) and 19/10/2013 (from date) highlighted and the dates in-between these dates are highlighted.
However I want to be able to randomly change the back colour of each of the selected date blocks in the calendar? How do I do this?
Many thanks
here is bit of the code that highlights the dates with a back color and makes them selectable and such. This code works perfectly fine but I want to be able to do the above?
protected void Calendar1_DayRender(object sender, DayRenderEventArgs e)
{
if (dsHolidays != null)
{
foreach (DataRow dr in dsHolidays.Tables[0].Rows)
{
DateTime nextDate;
DateTime endDate;
nextDate = (DateTime)dr["date"];
endDate = (DateTime)dr["date1"];
if (nextDate <= e.Day.Date && endDate >= e.Day.Date)
{
e.Cell.BackColor = System.Drawing.Color.Gray;
// dates are unselectable
e.Day.IsSelectable = false;
}
}
}
// makes the all the first dates selectable
foreach (DataRow dr in dsHolidays.Tables[0].Rows)
{
DateTime nextDate1;
nextDate1 = (DateTime)dr["date"];
{
if (e.Day.Date == nextDate1)
{
e.Day.IsSelectable = true;
e.Cell.ForeColor = System.Drawing.Color.Blue;
}
}
}
}
Maybe this code can help
Random randomGen = new Random();
KnownColor[] names = (KnownColor[])Enum.GetValues(typeof(KnownColor));
Color newColor = Color.FromKnownColor(names[randomGen.Next(names.Length)]);
protected void Calendar1_DayRender(object sender, DayRenderEventArgs e)
{
if (e.Day.IsWeekend)
{
e.Day.IsSelectable = false;
e.Cell.BackColor = System.Drawing.Color.Yellow;
}
if(e.Day.Date.Day%2==0 && !e.Day.IsOtherMonth && !e.Day.IsWeekend)
{
e.Day.IsSelectable = false;
e.Cell.BackColor = System.Drawing.Color.Orange;
e.Cell.ToolTip = "Booked";
}
if (e.Day.Date.Day % 2 != 0 && !e.Day.IsOtherMonth && !e.Day.IsWeekend)
{
e.Day.IsSelectable = false;
e.Cell.BackColor = System.Drawing.Color.PaleGreen;
e.Cell.ToolTip = "Available";
}
if(e.Day.Date.Day%5==0 && !e.Day.IsOtherMonth && !e.Day.IsWeekend )
{
e.Day.IsSelectable = false;
e.Cell.BackColor = System.Drawing.Color.Green;
e.Cell.ToolTip = "Fast Booking";
}
}

Categories