I need my application to expire 30 days from today, I will store the current date in the application config.How will I check if the application has expired ? I don't mind if the user changed the clock back and the app works (too stupid a user to do that).
if (appmode == "Trial") {
????
}
string dateInString = "01.10.2009";
DateTime startDate = DateTime.Parse(dateInString);
DateTime expiryDate = startDate.AddDays(30);
if (DateTime.Now > expiryDate) {
//... trial expired
}
DateTime.AddDays does that:
DateTime expires = yourDate.AddDays(30);
DateTime.Now.Add(-30)
Gives you the date 30 days back from now
One I can answer confidently!
DateTime expiryDate = DateTime.Now.AddDays(30);
Or possibly - if you just want the date without a time attached which might be more appropriate:
DateTime expiryDate = DateTime.Today.AddDays(30);
DateTime _expiryDate = DateTime.Now + TimeSpan.FromDays(30);
A possible solution would be on first run, create a file containing the current date and put it in IsolatedStorage. For subsequent runs, check the contents of the file and compare with the current date; if the date difference is greater than 30 days, inform the user and close the application.
A better solution might be to introduce a license file with a counter. Write into the license file the install date of the application (during installation). Then everytime the application is run you can edit the license file and increment the count by 1. Each time the application starts up you just do a quick check to see if the 30 uses of the application has been reached i.e.
if (LicenseFile.Counter == 30)
// go into expired mode
Also this will solve the issue if the user has put the system clock back as you can do a simple check to say
if (LicenseFile.InstallationDate < SystemDate)
// go into expired mode (as punishment for trying to trick the app!)
The problem with your current setup is the user will have to use the application every day for 30 days to get their full 30 day trial.
string[] servers = new string[] {
"nist1-ny.ustiming.org",
"nist1-nj.ustiming.org",
"nist1-pa.ustiming.org",
"time-a.nist.gov",
"time-b.nist.gov",
"nist1.aol-va.symmetricom.com",
"nist1.columbiacountyga.gov",
"nist1-chi.ustiming.org",
"nist.expertsmi.com",
"nist.netservicesgroup.com"
};
string dateStart, dateEnd;
void SetDateToday()
{
Random rnd = new Random();
DateTime result = new DateTime();
int found = 0;
foreach (string server in servers.OrderBy(s => rnd.NextDouble()).Take(5))
{
Console.Write(".");
try
{
string serverResponse = string.Empty;
using (var reader = new StreamReader(new System.Net.Sockets.TcpClient(server, 13).GetStream()))
{
serverResponse = reader.ReadToEnd();
Console.WriteLine(serverResponse);
}
if (!string.IsNullOrEmpty(serverResponse))
{
string[] tokens = serverResponse.Split(' ');
string[] date = tokens[1].Split(' ');
string time = tokens[2];
string properTime;
dateStart = date[2] + "/" + date[0] + "/" + date[1];
int month = Convert.ToInt16(date[0]), day = Convert.ToInt16(date[2]), year = Convert.ToInt16(date[1]);
day = day + 30;
if ((month % 2) == 0)
{
//MAX DAYS IS 30
if (day > 30)
{
day = day - 30;
month++;
if (month > 12)
{
month = 1;
year++;
}
}
}
else
{
//MAX DAYS IS 31
if (day > 31)
{
day = day - 31;
month++;
if (month > 12)
{
month = 1;
year++;
}
}
}
string sday, smonth;
if (day < 10)
{
sday = "0" + day;
}
if (month < 10)
{
smonth = "0" + month;
}
dateEnd = sday + "/" + smonth + "/" + year.ToString();
}
}
catch
{
// Ignore exception and try the next server
}
}
if (found == 0)
{
MessageBox.Show(this, "Internet Connection is required to complete Registration. Please check your internet connection and try again.", "Not connected", MessageBoxButtons.OK, MessageBoxIcon.Information);
Success = false;
}
}
I saw that code in some part of some website. Doing the example above exposes a glitch: Changing the current Time and Date to the start date would prolong the application expiration.
The solution? Refer to a online time server.
#Ed courtenay, #James,
I have one stupid question.
How to keep user away from this file?(File containing expiry date).
If the user has installation rights, then obviously user has access to view files also.
Changing the extension of file wont help.
So, how to keep this file safe and away from users hands?
You need to store the first run time of the program in order to do this. How I'd probably do it is using the built in application settings in visual studio. Make one called InstallDate which is a User Setting and defaults to DateTime.MinValue or something like that (e.g. 1/1/1900).
Then when the program is run the check is simple:
if (appmode == "trial")
{
// If the FirstRunDate is MinValue, it's the first run, so set this value up
if (Properties.Settings.Default.FirstRunDate == DateTime.MinValue)
{
Properties.Settings.Default.FirstRunDate = DateTime.Now;
Properties.Settings.Default.Save();
}
// Now check whether 30 days have passed since the first run date
if (Properties.Settings.Default.FirstRunDate.AddMonths(1) < DateTime.Now)
{
// Do whatever you want to do on expiry (exception message/shut down/etc.)
}
}
User settings are stored in a pretty weird location (something like C:\Documents and Settings\YourName\Local Settings\Application Data) so it will be pretty hard for average joe to find it anyway. If you want to be paranoid, just encrypt the date before saving it to settings.
EDIT: Sigh, misread the question, not as complex as I thought >.>
A bit late to this question, but I created a class with all the handy methods needed to create a fully functional time trial in C#. Rather than your application config, I write the expiry time to the Windows Application Data path, and that will also remain persistent even after the program has closed (it's also tricky to find the path for the average user).
Fully documented and simple to use, I hope someone finds it useful!
public class TimeTrialManager
{
private long expiryTime = 0;
private string userPath = "";
public TimeTrialManager(string softwareName)
{
// Create folder in Windows Application Data folder for persistence:
userPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData).ToString() + "\\" + softwareName + "_prefs\\";
if (!Directory.Exists(userPath)) Directory.CreateDirectory(Path.GetDirectoryName(userPath));
userPath += "expiryinfo.txt";
if (File.Exists(userPath)) expiryTime = Convert.ToInt64(File.ReadAllText(userPath));
}
// Use this method to check if the expiry has already been created. If
// it has, you don't need to call the setExpiryDate() method ever again.
// C:\Users\Dan\AppData\Roaming\SSNotify_prefs\expiryinfo.txt
public bool expiryHasBeenStored()
{
return File.Exists(userPath);
}
// Use this to set expiry as the number of days from the current time.
// This should be called just once in the program's lifetime for that user.
public void setExpiryTime(double days, double seconds = 0)
{
DateTime time = DateTime.Now.AddDays(days).AddSeconds(seconds);
expiryTime = time.ToFileTimeUtc();
try { File.WriteAllText(userPath, expiryTime.ToString()); }
catch (Exception ex) { MessageBox.Show(ex.Message); }
}
// Check for this in a background timer or whenever else you wish to check if the time has run out
public bool trialHasExpired()
{
if (DateTime.Now.ToFileTimeUtc() >= expiryTime) return true; else return false;
}
// This method is optional and isn't required to use the core functionality of the class
// Perhaps use it to tell the user how long he has left to trial the software
public string expiryAsHumanReadableString(bool remaining = false)
{
DateTime dt = new DateTime();
dt = DateTime.FromFileTime(expiryTime); // alternative: FromFileTimeUtc
if (remaining == false) return dt.ToShortDateString() + " " + dt.ToLongTimeString();
else
{
TimeSpan ts = dt.Subtract(DateTime.Now);
if (ts.TotalSeconds < 0) return "0";
string days = "";
if (ts.Days != 0) days = ts.Days + " days + ";
return days + ts.ToString(#"hh\:mm\:ss");
}
}
}
Here is a typical usage of the above class. Couldn't be simpler!
TimeTrialManager ttm;
private void Form1_Load(object sender, EventArgs e)
{
timer1.Enabled = true;
ttm = new TimeTrialManager("TestTime");
if (!ttm.expiryHasBeenStored()) ttm.setExpiryTime(0,10); // Expires in 10 seconds from creation time
}
private void timer1_Tick_1(object sender, EventArgs e)
{
if (ttm.trialHasExpired()) {
timer1.Enabled = false;
MessageBox.Show("Trial over! :(");
Environment.Exit(0);
}
}
You just need to use
DateTime.AddDays
For example:
Add 30 days from today:
DateTime expiryDate = DateTime.Today.AddDays(30);
Subtract 30 days from today:
DateTime expiryDate = DateTime.Today.AddDays(-30);
if (cmb_mode_of_service.SelectedItem != null && cmb_term_of_service.SelectedItem != null)
{
if (cmb_mode_of_service.SelectedIndex > 0 && cmb_term_of_service.SelectedIndex > 0)
{
if (cmb_mode_of_service.SelectedItem.ToString() == "Single Service/Installation" || cmb_term_of_service.SelectedItem.ToString() == "Single Time")
{
int c2 = 1;
char c1 = 'A';
DataRow dr = dt.NewRow();
dr["SN"] = c2++;
dr["serviceid"] = txt_service_id.Text + "-" + c1++;
dr["servicedate"] = service_start_date.Text;
dr["servicestatus"] = "Pending";
dr["serviceexcutive"] = "Not Alowed";
dt.Rows.Add(dr);
dataGridView1.DataSource = dt;
txtexpirydate.Text = (Convert.ToDateTime(service_start_date.Text).AddDays(1)).ToString();
}
else
{
if (cmb_mode_of_service.SelectedItem.ToString() == "Weekly Service")
{
int year = 0;
if (cmb_term_of_service.SelectedItem.ToString() == "One Year")
{
year = 1;
}
if (cmb_term_of_service.SelectedItem.ToString() == "Two Year")
{
year = 2;
}
if (cmb_term_of_service.SelectedItem.ToString() == "three year")
{
year = 3;
}
DateTime currentdate = Convert.ToDateTime(service_start_date.Text);
DateTime Enddate = currentdate.AddYears(+year);
txtexpirydate.Text = Enddate.ToString();
char c1 = 'A';
int c2 = 1;
for (var dt1 = currentdate.AddDays(7); dt1 <= Enddate; dt1 = dt1.AddDays(7))
{
DataRow dr = dt.NewRow();
dr["SN"] = c2++;
dr["serviceid"] = txt_service_id.Text + "-" + c1++;
dr["servicedate"] = dt1.ToString();
dr["servicestatus"] = "Pending";
dr["serviceexcutive"] = "Not Alowed";
//txtexpirydate.Text = dt1.ToString();
dt.Rows.Add(dr);
}
dataGridView1.DataSource = dt;
}
if (cmb_mode_of_service.SelectedItem.ToString() == "Fortnight Service")
{
int year = 0;
if (cmb_term_of_service.SelectedItem.ToString() == "One Year")
{
year = 1;
}
if (cmb_term_of_service.SelectedItem.ToString() == "Two Year")
{
year = 2;
}
if (cmb_term_of_service.SelectedItem.ToString() == "three year")
{
year = 3;
}
DateTime currentdate = Convert.ToDateTime(service_start_date.Text);
DateTime Enddate = currentdate.AddYears(+year);
txtexpirydate.Text = Enddate.ToString();
char c1 = 'A';
int c2 = 1;
for (var dt1 = currentdate.AddDays(15); dt1 <= Enddate; dt1 = dt1.AddDays(15))
{
DataRow dr = dt.NewRow();
dr["SN"] = c2++;
dr["serviceid"] = txt_service_id.Text + "-" + c1++;
dr["servicedate"] = dt1.ToString();
dr["servicestatus"] = "Pending";
dr["serviceexcutive"] = "Not Alowed";
// txtexpirydate.Text = dt1.ToString();
dt.Rows.Add(dr);
}
dataGridView1.DataSource = dt;
}
if (cmb_mode_of_service.SelectedItem.ToString() == "Monthly Service")
{
int year = 0;
if (cmb_term_of_service.SelectedItem.ToString() == "One Year")
{
year = 1;
}
if (cmb_term_of_service.SelectedItem.ToString() == "Two Year")
{
year = 2;
}
if (cmb_term_of_service.SelectedItem.ToString() == "three year")
{
year = 3;
}
DateTime currentdate = Convert.ToDateTime(service_start_date.Text);
DateTime Enddate = currentdate.AddYears(+year);
txtexpirydate.Text = Enddate.ToString();
char c1 = 'A';
int c2 = 1;
for (var dt1 = currentdate.AddDays(30); dt1 <= Enddate; dt1 = dt1.AddDays(30))
{
DataRow dr = dt.NewRow();
dr["SN"] = c2++;
dr["serviceid"] = txt_service_id.Text + "-" + c1++;
dr["servicedate"] = dt1.ToString();
dr["servicestatus"] = "Pending";
dr["serviceexcutive"] = "Not Alowed";
// txtexpirydate.Text = dt1.ToString();
dt.Rows.Add(dr);
}
dataGridView1.DataSource = dt;
}
if (cmb_mode_of_service.SelectedItem.ToString() == "Trimister Service")
{
int year = 0;
if (cmb_term_of_service.SelectedItem.ToString() == "One Year")
{
year = 1;
}
if (cmb_term_of_service.SelectedItem.ToString() == "Two Year")
{
year = 2;
}
if (cmb_term_of_service.SelectedItem.ToString() == "three year")
{
year = 3;
}
DateTime currentdate = Convert.ToDateTime(service_start_date.Text);
DateTime Enddate = currentdate.AddYears(+year);
txtexpirydate.Text = Enddate.ToString();
char c1 = 'A';
int c2 = 1;
for (var dt1 = currentdate.AddDays(90); dt1 <= Enddate; dt1 = dt1.AddDays(90))
{
DataRow dr = dt.NewRow();
dr["SN"] = c2++;
dr["serviceid"] = txt_service_id.Text + "-" + c1++;
dr["servicedate"] = dt1.ToString();
dr["servicestatus"] = "Pending";
dr["serviceexcutive"] = "Not Alowed";
// txtexpirydate.Text = dt1.ToString();
dt.Rows.Add(dr);
}
dataGridView1.DataSource = dt;
}
if (cmb_mode_of_service.SelectedItem.ToString() == "Half Yearly Service")
{
int year = 0;
if (cmb_term_of_service.SelectedItem.ToString() == "One Year")
{
year = 1;
}
if (cmb_term_of_service.SelectedItem.ToString() == "Two Year")
{
year = 2;
}
if (cmb_term_of_service.SelectedItem.ToString() == "three year")
{
year = 3;
}
DateTime currentdate = Convert.ToDateTime(service_start_date.Text);
DateTime Enddate = currentdate.AddYears(+year);
txtexpirydate.Text = Enddate.ToString();
char c1 = 'A';
int c2 = 1;
for (var dt1 = currentdate.AddDays(180); dt1 <= Enddate; dt1 = dt1.AddDays(180))
{
DataRow dr = dt.NewRow();
dr["SN"] = c2++;
dr["serviceid"] = txt_service_id.Text + "-" + c1++;
dr["servicedate"] = dt1.ToString();
dr["servicestatus"] = "Pending";
dr["serviceexcutive"] = "Not Alowed";
// txtexpirydate.Text = dt1.ToString();
dt.Rows.Add(dr);
}
dataGridView1.DataSource = dt;
}
if (cmb_mode_of_service.SelectedItem.ToString() == "Yearly Service")
{
int year = 0;
if (cmb_term_of_service.SelectedItem.ToString() == "One Year")
{
year = 1;
}
if (cmb_term_of_service.SelectedItem.ToString() == "Two Year")
{
year = 2;
}
if (cmb_term_of_service.SelectedItem.ToString() == "three year")
{
year = 3;
}
DateTime currentdate = Convert.ToDateTime(service_start_date.Text);
DateTime Enddate = currentdate.AddYears(+year);
txtexpirydate.Text = Enddate.ToString();
char c1 = 'A';
int c2 = 1;
for (var dt1 = currentdate.AddDays(365); dt1 <= Enddate; dt1 = dt1.AddDays(365))
{
DataRow dr = dt.NewRow();
dr["SN"] = c2++;
dr["serviceid"] = txt_service_id.Text + "-" + c1++;
dr["servicedate"] = dt1.ToString();
dr["servicestatus"] = "Pending";
dr["serviceexcutive"] = "Not Alowed";
//txtexpirydate.Text = dt1.ToString();
dt.Rows.Add(dr);
}
dataGridView1.DataSource = dt;
}
}
}
Related
Trying to find the largest cohesive time for non-working-hours diff in a specific range.
The range that is looked at is defined by:
sDate = range start
eDate = range end
in this defined range, there could be existing registrations (orange blocks in image).
Could someone please give me some input on how to solve this issue.
This code will not compare existing post with each other.
public TimeSpan TimeNightRest(DateTime WhatDay, int dayRange, DataTable TimeData)
{
DateTime DayRangeStart = new DateTime(WhatDay.Year, WhatDay.Month, WhatDay.Day, 0, 0, 0);
DateTime DayRangeEnd = new DateTime(WhatDay.Year, WhatDay.Month, WhatDay.AddDays(dayRange).Day, 0, 0, 0);
TimeSpan nightRest = new TimeSpan();
foreach (DataRow drUnfiltered in TimeData.Rows)
{
DateTime sDate = DateTime.Parse(TimeData.Rows[0]["sDate"].ToString());
DateTime eDate = DateTime.Parse(TimeData.Rows[0]["eDate"].ToString());
//1. db-post cover range
if (sDate < WhatDay && eDate > WhatDay.AddDays(dayRange))
{
nightRest = TimeSpan.FromHours(0);
break;
}
//2. Post exists, start outside ends inside range
if(sDate < WhatDay && eDate < WhatDay.AddDays(dayRange))
{
nightRest = (WhatDay.addDays(dayRange) - eDate)
//More posts could exists that lower this value!!!
}
//3. Post exists, start inside ends outside range
if ((sDate > WhatDay && sDate <WhatDay.AddDays(dayRange)) && eDate > WhatDay.AddDays(dayRange))
{
nightRest = (sDate - WhatDay);
//More posts could exists that lower this value!!!
}
}
return nightRest;
}
I tried to write a different version, this code will compare different post trying to find the largest diff between them. But will fail to find posts that overlaps (no diff) and it will also fail with finding the correct diff with post that starts outside and ends inside the range and opposite.
`
///<Alternative></Alternative>
//1. - No Data Rest = 24h x DayRange
if (timeData.Rows.Count == 0)
{
nightRest = TimeSpan.FromHours(24 * dayRange);
}
///<Alternative></Alternative>
//2. - One Post, Compare to day start/end time
if (timeData.Rows.Count == 1)
{
DateTime sDate = Convert.ToDateTime(timeData.Rows[0]["sDate"].ToString());
DateTime eDate = Convert.ToDateTime(timeData.Rows[0]["eDate"].ToString());
TimeSpan range1 = (sDate - DayRangeStart);
TimeSpan range2 = (DayRangeEnd - eDate);
if (range1 > range2)
{
nightRest = range1;
}
else
{
nightRest = range2;
}
}
///<Alternative></Alternative>
//3. - If DataTable containes more than 1 post, then loop through to calculate diffrence
between post and day start/end
if (timeData.Rows.Count > 1)
{
int i = 1;
int RowCount = timeData.Rows.Count;
foreach (DataRow dr in timeData.Rows)
{
DateTime sDate = Convert.ToDateTime(dr["sdate"]);
DateTime eDate = Convert.ToDateTime(dr["edate"]);
DateTime prevPostSdate = new DateTime();
DateTime nextPostSdate = new DateTime();
//Only 1st time in loop
if (i != 1)
{
//Prev row
DataRow lastRow = timeData.Rows[(i - 1) - 1];
prevPostSdate = Convert.ToDateTime(lastRow["edate"]);
//prevPostEdate = Convert.ToDateTime(lastRow["edate"]);
}
else
{
prevPostSdate = DayRangeStart;
}
//If we are on EOF-post then dont get next post value, get instead range end value
if (i != RowCount)
{
//Next row
DataRow nextRow = timeData.Rows[(i - 1) + 1];
nextPostSdate = Convert.ToDateTime(nextRow["sdate"]);
}
else
{
nextPostSdate = DayRangeEnd;
}
///<Compare>Type #1
///Sdate inside && eDate inside
///</ Compare >
if (DayRangeStart < sDate && DayRangeEnd > eDate)
{
//Compair Range with Post-sdate & Post
//1. Range with Post-sdate
TimeSpan value1 = (sDate - prevPostSdate);
//2. Post-eDate with NextPostSdate
TimeSpan value2 = (nextPostSdate - eDate);
if (value1 > nightRest) nightRest = value1;
if (value2 > nightRest) nightRest = value2;
}
///<Compare>Type #2
///Sdate outside && eDate inside
///</ Compare >
if (DayRangeStart >= sDate && DayRangeEnd > eDate)
{
//Compair Range with Post-sdate & Post
//1. Range with Post-sdate
TimeSpan value1 = (nextPostSdate - eDate);
if (value1 > nightRest) nightRest = value1;
}
///<Compare>Type #3
///Sdate indise && eDate outside
///</ Compare >
if (DayRangeStart < sDate && DayRangeEnd <= eDate)
{
//Compare Range Post-sdate & Post
//1. Range with Post-sdate
TimeSpan value1 = (sDate - prevPostSdate);
//Console.WriteLine(value1);
if (value1 > nightRest) nightRest = value1;
}
///<Compare>Type #4
///Sdate outside && eDate outside
///</ Compare >
if (DayRangeStart >= sDate && DayRangeEnd <= eDate)
{
nightRest = TimeSpan.FromHours(0);
}
i++;
}
}
`
Well i manage to solve this. Probably some much better code out there but this does the work!
public DataTable FilterTable(DataTable table, DateTime startDate, DateTime endDate)
{
var filteredRows =
from row in table.Rows.OfType<DataRow>()
where (DateTime)row["sDate"] < endDate && startDate <= (DateTime)row["eDate"]
select row;
var filteredTable = table.Clone();
filteredRows.ToList().ForEach(r => filteredTable.ImportRow(r));
return filteredTable;
}
public TimeSpan TimeNightRest(DateTime WhatDay, int dayRange, DataTable TimeData)
{
DateTime DayRangeStart = DateTime.Parse(WhatDay.ToShortDateString());
DateTime DayRangeEnd = DateTime.Parse(DayRangeStart.AddDays(dayRange).ToShortDateString());
TimeSpan nightRest = new TimeSpan();
DataTable dtTime = FilterTable(TimeData, WhatDay, WhatDay.AddDays(dayRange));
//1. - No posts
if (dtTime.Rows.Count == 0)
{
nightRest = TimeSpan.FromHours(24 * dayRange);
}
//2. - One post Exists!
if (dtTime.Rows.Count == 1)
{
DateTime sDate = Convert.ToDateTime(dtTime.Rows[0]["sDate"].ToString());
DateTime eDate = Convert.ToDateTime(dtTime.Rows[0]["eDate"].ToString());
if (sDate < DayRangeEnd && DayRangeStart <= eDate)
{
TimeSpan range1 = (sDate - DayRangeStart);
TimeSpan range2 = (DayRangeEnd - eDate);
if (range1 > range2)
{
nightRest = range1;
}
else
{
nightRest = range2;
}
//Negative TimeSpans is ==> Zero
if(nightRest < TimeSpan.Zero)
{
nightRest = TimeSpan.FromHours(0);
}
}
else
{
nightRest = TimeSpan.FromHours(24 * dayRange);
}
}
//3. More then 1 post i db
if (dtTime.Rows.Count > 1)
{
int i = 1;
int RowCount = dtTime.Rows.Count;
foreach (DataRow dr in dtTime.Rows)
{
DateTime sDate = Convert.ToDateTime(dr["sdate"]);
DateTime eDate = Convert.ToDateTime(dr["edate"]);
if (sDate < DayRangeEnd && DayRangeStart <= eDate)
{
DateTime prevPostSdate = new DateTime();
DateTime nextPostSdate = new DateTime();
//1st loop
if (i != 1)
{
//Prev row
DataRow lastRow = dtTime.Rows[(i - 1) - 1];
prevPostSdate = Convert.ToDateTime(lastRow["edate"]);
}
else
{
prevPostSdate = DayRangeStart;
}
//If we are on EOF-post then dont get next post value, get instead range end value
if (i != RowCount)
{
//Next row
DataRow nextRow = dtTime.Rows[(i - 1) + 1];
nextPostSdate = Convert.ToDateTime(nextRow["sdate"]);
}
else
{
nextPostSdate = DayRangeEnd;
}
if (DayRangeStart < sDate && DayRangeEnd > eDate)
{
TimeSpan value1 = (sDate - prevPostSdate);
TimeSpan value2 = (nextPostSdate - eDate);
if (value1 > nightRest) nightRest = value1;
if (value2 > nightRest) nightRest = value2;
}
if (DayRangeStart >= sDate && DayRangeEnd > eDate)
{
TimeSpan value1 = (nextPostSdate - eDate);
if (value1 > nightRest) nightRest = value1;
}
if (DayRangeStart < sDate && DayRangeEnd <= eDate)
{
TimeSpan value1 = (sDate - prevPostSdate);
if (value1 > nightRest) nightRest = value1;
}
if (DayRangeStart >= sDate && DayRangeEnd <= eDate)
{
nightRest = TimeSpan.FromHours(0);
}
}
else
{
nightRest = TimeSpan.FromHours(24 * dayRange);
}
i++;
}
}
return nightRest;
}
I have a grid view in wpf(C#) which contain Birth Day Date. I used bellow code for calculated the age for first row.
Now how to calculated the all row (ages)?
private void Window_Loaded(object sender, RoutedEventArgs e)
{
string birth_day = "";
var query = from u in db.tbl_User select u;
var result = query.ToList();
if (result.Count > 0)
{
birth_day = result[0].BirthDayDate;
DateTime birthdaydate = DateTime.Parse(ShamsiToMiladi(birth_day));
DateTime todaydate = DateTime.Parse(ShamsiToMiladi(PublicVariable.TodayDate));
int days = todaydate.Day - birthdaydate.Day;
if (days < 0)
{
todaydate = todaydate.AddMonths(-1);
days += DateTime.DaysInMonth(todaydate.Year, todaydate.Month);
}
int months = todaydate.Month - birthdaydate.Month;
if (months < 0)
{
todaydate = todaydate.AddYears(-1);
months += 12;
}
int years = todaydate.Year - birthdaydate.Year;
MessageBox.Show(string.Format("{0} year{1}, {2} month{3} and {4} day{5}",
years, (years == 1) ? "" : "s",
months, (months == 1) ? "" : "s",
days, (days == 1) ? "" : "s"));
}
Just a simple foreach:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var query = db.tbl_User.ToList();
if (!query.Any())return;
var results = new List<string>();
foreach(var user in query){
var birth_day = user.BirthDayDate;
DateTime birthdaydate = DateTime.Parse(ShamsiToMiladi(birth_day));
DateTime todaydate = DateTime.Parse(ShamsiToMiladi(PublicVariable.TodayDate));
int days = todaydate.Day - birthdaydate.Day;
if (days < 0)
{
todaydate = todaydate.AddMonths(-1);
days += DateTime.DaysInMonth(todaydate.Year, todaydate.Month);
}
int months = todaydate.Month - birthdaydate.Month;
if (months < 0)
{
todaydate = todaydate.AddYears(-1);
months += 12;
}
int years = todaydate.Year - birthdaydate.Year;
results.Add(
string.Format(
"{0} year{1}, {2} month{3} and {4} day{5}",
years, (years == 1) ? "" : "s",
months, (months == 1) ? "" : "s",
days, (days == 1) ? "" : "s"
)
);
}
}
Not enough rep to comment but to use foreach:
if (result.Count > 0)
{
birth_day = result[0].BirthDayDate;
becomes
foreach (var item in result)
{
// Use result.BirthDayDate
I have a table named Attendancelogs where I am saving the records that I fetch from a biometric device, the table structure is;
LogType defines the type of log i.e. Biometric/Manual
CheckType defines the type of entry i.e. I or O
VerifyMode defines the type of punch i.e. Fingerprint/Password
isIgnore is used to exclude an entry from the logs.
Now, what I am trying to do is to write a function called sortFunc(); that will process on the already stored records in the Attendancelogs table. what this is suppose to do is;
Mark the checkType of each employee as I for the first entry, then O for their second entry of the date and so on.
If an employee has a last I at the end of the day, meaning no check out, then the next day's first punch of that employee (with in 12 AM - 7 AM) is considered check out for the previous day (marking as a nighter case for that employee) the rest entries are considered as sequential I and O.
any multiple entries within 10 seconds (or defined time) is ignored and marked CheckType as "Auto Ignored for x seconds"
If an employee is not allowed to use Card/Password then his CheckTypes are marked as Card not allowed or Password not allowed
Here is the function that I wrote;
public static bool inn = true;
public void sortLogs(int machineNum)
{
DateTime prevDate = DateTime.MinValue;
DateTime currentDate = DateTime.MinValue;
DateTime prevDateTime = DateTime.MinValue;
DateTime currentDateTime = DateTime.MinValue;
TimeSpan lowerBound = TimeSpan.Zero;
TimeSpan upperBound = TimeSpan.Zero;
var time = DateTime.ParseExact("00:00:00", "HH:mm:ss", null).ToString("hh:mm:ss tt", CultureInfo.GetCultureInfo("en-US"));
lowerBound = Convert.ToDateTime(time).TimeOfDay;
var time2 = DateTime.ParseExact("07:00:00", "HH:mm:ss", null).ToString("hh:mm:ss tt", CultureInfo.GetCultureInfo("en-US"));
upperBound = Convert.ToDateTime(time2).TimeOfDay;
upperBound = new TimeSpan(7, 0, 0);
var CheckType = "N/S";
bool isNighter = false;
List<AttendanceLog> firstDates = new List<AttendanceLog>();
AttendanceLog lastEmp = new AttendanceLog();
var empList = db.AttendanceLogs.OrderBy(x => x.EmpID).ThenBy(x => x.DateTime).ToList();
var countEmps = empList.DistinctBy(p => p.EmpID).Count();
string[,] array = new string[countEmps, 2];
var checkDevice = db.DeviceInformations.Where(xy => xy.DeviceID == machineNum && xy.IsActive == 1.ToString()).ToList();
AttendanceLog firstObj = new AttendanceLog();
int counter = 0;
int tempEmp = -1;
foreach (var emp in empList)
{
if (emp.EmpID == 0)
continue;
var cardAcceptance = db.Roles.Where(x => x.EmpID == emp.EmpID && x.Card_Acceptance == true).ToList();
var passwordAcceptance = db.Roles.Where(x => x.EmpID == emp.EmpID && x.Password_Acceptance == true).ToList();
currentDate = emp.Date;
currentDateTime = emp.DateTime;
if (emp.EmpID != tempEmp)
{
inn = true;
}
if (prevDateTime != DateTime.MinValue)
{
var seconds = (emp.DateTime - prevDateTime).TotalSeconds;
var settings = db.settings.Where(xy => xy.Constant_Name == "Entry Delay").FirstOrDefault();
if (settings.Constant_Value <= 0)
settings.Constant_Value = 10;
else
if (seconds > 0 && seconds < settings.Constant_Value)
{
//store prevDateTime in deleted table
emp.CheckType = "Auto Ignored: " + seconds + " seconds interval.";
// prevDateTime = emp.DateTime;
continue;
}
}
if (passwordAcceptance.Count <= 0)
{
if (emp.VerifyMode == "3")
{
try
{
emp.CheckType = "Password not allowed";
//db.SaveChanges();
continue;
}
catch (DbEntityValidationException e)
{
foreach (var eve in e.EntityValidationErrors)
{
foreach (var ve in eve.ValidationErrors)
{
}
}
throw;
}
}
}
if (cardAcceptance.Count <= 0)
{
if (emp.VerifyMode == "4")
{
try
{
emp.CheckType = "Card not allowed";
// db.SaveChanges();
continue;
}
catch (DbEntityValidationException e)
{
foreach (var eve in e.EntityValidationErrors)
{
foreach (var ve in eve.ValidationErrors)
{
}
}
throw;
}
}
}
if (counter != countEmps)
{
if (emp.EmpID != firstObj.EmpID)
{
array[counter, 0] = emp.EmpID.ToString();
firstObj.EmpID = emp.EmpID;
firstObj.Date = emp.Date;
counter++;
}
}
if (currentDate == firstObj.Date)
{
//check for entry delay
//get emp datetime here
//comapre with the slots
//if the datetime exsits in between
//otherwise store it with boolean flag for the first entry only, the rest should not be flagged
if (emp.DateTime.TimeOfDay > lowerBound && emp.DateTime.TimeOfDay < upperBound)
{
//consider the first check as nighter and then ignore the rest
}
else {
//checks after the upperBound means, no nighter
}
if (inn)
{
inn = false;
emp.CheckType = "I";
}
else
{
inn = true;
emp.CheckType = "O";
}
for (int i = 0; i < array.Length / 2; i++)
{
if (array[i, 0] == emp.EmpID.ToString())
{
array[i, 1] = emp.CheckType;
break;
}
}
//CheckType = emp.CheckType;
prevDate = currentDate;
prevDateTime = currentDateTime;
}
else
{
if (prevDate != currentDate)
{
if (emp.DateTime.TimeOfDay > lowerBound && emp.DateTime.TimeOfDay < upperBound)
{
//consider the first check as nighter and then ignore the rest
if (inn)
{
inn = false;
emp.CheckType = "I";
}
else
{
inn = true;
emp.CheckType = "O";
}
for (int i = 0; i < array.Length / 2; i++)
{
if (array[i, 0] == emp.EmpID.ToString())
{
array[i, 1] = emp.CheckType;
break;
}
}
//CheckType = emp.CheckType;
prevDate = currentDate;
prevDateTime = currentDateTime;
}
else
{
//checks after the upperBound means, no nighter
}
for (int i = 0; i < array.Length / 2; i++)
{
if (array[i, 0] == emp.EmpID.ToString())
{
if (array[i, 1] == "I")
{
emp.CheckType = "O";
inn = true;
}
else
{
emp.CheckType = "I";
inn = false;
}
}
}
}
else
{
if (inn)
{
inn = false;
emp.CheckType = "I";
}
else
{
inn = true;
emp.CheckType = "O";
}
for (int i = 0; i < array.Length / 2; i++)
{
if (array[i, 0] == emp.EmpID.ToString())
{
array[i, 1] = emp.CheckType;
}
}
}
prevDate = currentDate;
}
tempEmp = emp.EmpID.Value;
}
db.SaveChanges();
}
This did run but it messes up the "12 AM to 7 AM" checks and the password checks, i.e. not the accurate results.
As one of the example seen ^ consecutive O should not be there. I have been going crazy over this!
I have some values.
DateTime date=04/03/2015(date)
Total Woring days=6 (total)
Rotation Days=2 (rotationday)
Shift Group=S1(this group contain two shift id 1 and 2)
I want to run the shift for 6 days. but after each 2 days Shift id 1 rotate to shift id 2 and again after two days shift id 2 rotate to shift id 1 and so on...
My output should be like
04/03/2015=1
05/03/2015=1
06/03/2015=2
07/03/2015=2
08/03/2015=1
09/03/2015=1
I am getting shift id through a foreach loop. I tried like below mentioned way but not getting a proper resul. Please help me solve this issue
SqlCommand cmd2 = new SqlCommand("select ShiftID from ShiftGroup where
ShiftName='" + ide + "'", conn2);
SqlDataAdapter sda2 = new SqlDataAdapter(cmd2);
DataSet ds4 = new DataSet();
var rows2 = ds4.Tables[0].Rows;
if (ds4.Tables[0].Rows.Count > 0)
{
foreach (DataRow row2 in rows2)
{
string shiftname = Convert.ToString(row2["ShiftID"]);
DateTime date=04/03/2015(date)
Total Woring days=6 (total)
Rotation Days=2 (rotationday)
DateTime rotation= date.AddDays(rotationday);//
DateTime totaldate = date.AddDays(workingdays);
for (DateTime rotation = date; rotation <= totaldate; rotation = rotation.AddDays(1))//total working days
{
//to check rotation date
if (rotation <= totaldate )
{
allocation.shiftallocation( rotation, shiftid);
}
}
}
I am stucked with this from last day, anybody help me . No need of consider my for loop, kindly provide a for loop which generate the above mentioned output
You can try this,
DateTime date=DateTime.ParseExact("04/03/2015","dd/MM/yyyy",CultureInfo.InvariantCulture);
DateTime totaldate = date.AddDays(6);
for (int i=0; date <= totaldate; date = date.AddDays(1),i++)//total working days
{
if((i/2)%2==0)
Console.WriteLine(date+" "+1);
else
Console.WriteLine(date+" "+2);
}
Don't use dates at loop cycle, use abstract indicies. You can really abstract from concrete numbers and use only variables for managing result. So you can easily change rotationDays count and even workshifts labels array without changing cycle.
var date = DateTime.Parse("04/03/2015");
var totalWorkingDays = 15;
var rotationDays = 2;
var workshifts = new[] { "S1", "S2" };
var currentWorkshiftIndex = 0;
for (int dayIndex = 0; dayIndex <= totalWorkingDays; dayIndex++) {
if (dayIndex != 0 && dayIndex % rotationDays == 0) currentWorkshiftIndex = (currentWorkshiftIndex + 1) % workshifts.Length;
Console.WriteLine(date.AddDays(dayIndex) + " " + workshifts[currentWorkshiftIndex]);
}
var date = DateTime.Parse("04/03/2015");
var totalWorkingDays = 6;
var rotationDays = 2;
var rotationId = 1;
var rotationCounter = 1;
for (DateTime rotation = date;
rotation <= date.AddDays(totalWorkingDays);
rotation = rotation.AddDays(1))
{
Console.WriteLine(rotation + " " + rotationId);
if (rotationCounter++ == 2)
{
rotationCounter = 1;
rotationId = 3 - rotationId;
}
}
Or, with a linq query
var date = DateTime.Parse("04/03/2015");
var totalWorkingDays = 6;
var rotationDays = 2;
foreach (var d in Enumerable.Range(0, totalWorkingDays)
.Select((i, index) => date.AddDays(i) +
(((int)(index / rotationDays)) % 2 == 1 ? " 2" : " 1")))
{
Console.WriteLine(d);
}
According to your comment for the 5 working days a week, I wrote this:
var start = new DateTime(2015, 04, 03);
var working_day_count = 6;
var rotation_interval = 2;
var shifts = new List<int> { 1, 2 };
var rotation_count = 1;
var shift_index = 0;
for (var i = 0; i < working_day_count; i++) {
while ((start.DayOfWeek == DayOfWeek.Saturday) ||
(start.DayOfWeek == DayOfWeek.Sunday)) {
start = start.AddDays(1);
}
Console.WriteLine(start.ToString() + " = " + shifts[shift_index].ToString());
start = start.AddDays(1);
rotation_count++;
if (rotation_count > rotation_interval) {
rotation_count = 1;
shift_index++;
if (shift_index >= shifts.Count) {
shift_index = 0;
}
}
}
Just change the values of the first four varibales as you like.
I tried to make it easy to understand instead of performant or compact.
A generic solution with holidays taken into account.
int totalDays = 10;
int rotationDays = 3;
int[] shifts = new[] { 1, 2 };
string startDate = "04/03/2015";
var holidays = new List<DayOfWeek>(new[] { DayOfWeek.Saturday, DayOfWeek.Sunday, DayOfWeek.Tuesday });
var shiftAllocations = new Dictionary<DateTime, int>();
int currentShiftIndex = 0;
DateTime current = DateTime.ParseExact(startDate, "dd/MM/yyyy", CultureInfo.InvariantCulture);
for (int i = 0; i < totalDays; i += rotationDays)
{
var currentShiftId = shifts[currentShiftIndex];
// For each day from the current day till the number of shift rotation days, allocate the shift.
for (int j = 0; j < rotationDays;)
{
// If the current day is a holiday, move to the next day by incrementing i.
if (holidays.Contains(current.AddDays(i + j).DayOfWeek))
{
i++;
continue;
}
shiftAllocations.Add(current.AddDays(i + j), currentShiftId);
j++;
}
// Increase the shift index if the value is within the bounds. If not reset the index to the beginning
if ((currentShiftIndex + 1) >= shifts.Length)
currentShiftIndex = 0;
else
currentShiftIndex++;
}
foreach (var kvp in shiftAllocations)
{
Console.WriteLine(kvp.Key.ToString("dd/MM/yyyy") + ":" + kvp.Value);
}
I have a Java application I'm trying to convert to C#. I have solved a fair bit of the program, but I have this clear method that troubles me:
private void checkCourts()
{
if (splMonth.getSelectedValue() != null && splDate.getSelectedValue() != null)
{
courtModel.clear();
Calendar booking = new GregorianCalendar();
int year = Calendar.getInstance().get(Calendar.YEAR);
int month = new Scanner(splMonth.getSelectedValue().toString()).nextInt() - 1;
int date = new Scanner(splDate.getSelectedValue().toString()).nextInt();
int time = Integer.parseInt(cmbxTime.getSelectedItem().toString());
int currentMonth = Calendar.getInstance().get(Calendar.MONTH);
int currentDate = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
int currentTime = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
booking.set(year, month, date, time, 0, 0);
if (month > currentMonth || (month == currentMonth && date > currentDate) || (month == currentMonth && date == currentDate && time > currentTime))
{
try
{
ArrayList<Reservation> rs = BookingManager.getInstance().getReservations();
Reservation r = new Reservation(booking);
ArrayList<String> courtNames = BookingManager.getInstance().getCourtsName();
for (int i = 0; i < rs.size(); i++)
{
r.getReservationTime().clear(Calendar.MILLISECOND);
rs.get(i).getReservationTime().clear(Calendar.MILLISECOND);
}
if (!rs.contains(r))
{
for (String c : courtNames)
{
courtModel.addElement(c);
}
}
else
{
for (String c : courtNames)
{
courtModel.addElement(c);
}
for (int i = 0; i < rs.size(); i++)
{
if (r.getReservationTime().getTime().equals(rs.get(i).getReservationTime().getTime()))
{
String courtName = BookingManager.getInstance().getNameById(rs.get(i).getCourtId());
courtModel.removeElement(courtName);
}
}
}
splCourt.setModel(courtModel);
}
catch (Exception e)
{
System.out.println("ERROR - " + e.getMessage());
}
}
else
{
JOptionPane.showMessageDialog(null, "Den valgte dato er ikke tilgængelig for booking.", "Advarsel", JOptionPane.INFORMATION_MESSAGE);
}
}
}
Well, the top for loop is the real issue, I think. I would like to remove the reservation times that already have been booked.
This is my first for loop try-out:
private void checkCourts()
{
DateTime current = DateTime.Now;
int year = Int32.Parse(DateTimePicker.Value.ToString("yyyy"));
int currentYear = current.Year;
int month = Int32.Parse(DateTimePicker.Value.ToString("MM"));
int currentMonth = current.Month;
int day = Int32.Parse(DateTimePicker.Value.ToString("dd"));
int currentDay = current.Day;
int time = (int)cmbxTime.SelectedItem;
int currentTime = current.TimeOfDay.Hours;
string date1 = year.ToString() + "," + month.ToString() + "," + day.ToString();
DateTime thisdate = DateTime.Parse(date1);
thisdate = thisdate.AddHours(time);
List<Reservation> rs = BookingManager.getInstance().getReservations();
Reservation r = new Reservation(thisdate);
List<string> courtNames = BookingManager.getInstance().getCourtsName();
if (month > currentMonth || (month == currentMonth && day > currentDay) ||
(month == currentMonth && day == currentDay && time > currentTime) && year >= currentYear)
{
try
{
for (int i = 0; i < rs.Count; i++)
{
r.ReservationTime = r.ReservationTime.AddTicks(-r.ReservationTime.Ticks % 10000000);
rs[i].ReservationTime = rs[i].ReservationTime.AddTicks(-rs[i].ReservationTime.Ticks % 10000000);
}
if (!rs.Contains(r))
{
foreach (string c in courtNames)
{
lboxCourts.Items.Add(c);
}
}
else
{
foreach (string c in courtNames)
{
lboxCourts.Items.Add(c);
}
for (int i = 0; i < rs.Count; i++)
{
if (r.ReservationTime.Equals(rs[i].ReservationTime))
{
String courtName = BookingManager.getInstance().getNameById(rs[i].CourtId);
lboxCourts.Items.Remove(courtName);
MessageBox.Show("is equal");
}
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
else
{
MessageBox.Show("Den valgte dato er ikke gyldig! - vær opmærksom på at hvis du vælger dags dato, at tidspunktet ikke kan være tidligere end nuværende tidspunkt!");
}
}
Hope you can clear my sight.. I have simply lost focus. I know of what I have see online - that datetimepicker is not that easy to edit. But then I would just edit the already booked item - to something like "already booked".
According to the docs, your Java code .clear(Calendar.MILLISECOND) is simply removing any milliseconds from the value. It's not doing anything with your application logic to remove the actual reservation times. It doesn't appear to involve any kind of DateTimePicker either.
Assuming in c# that the ReservationTime is a DateTime property, and r.ReservationTime is a different property than rs[i].ReservationTime, then you would need to do the following:
for (int i = 0; i < rs.Count; i++)
{
r.ReservationTime = r.ReservationTime.AddTicks(-r.ReservationTime.Ticks % 10000000);
rs[i].ReservationTime = rs[i].ReservationTime.AddTicks(-rs[i].ReservationTime.Ticks % 10000000);
}
There are a couple of points to note:
Java's Calendar class has resolution to the millisecond, so removing milliseconds would be truncating the value to the second.
DateTime in .Net has resolution to the tick. I tick is 100 nanoseconds, so there are 10,000,000 ticks in a second.
Therefore, you can't just clear the milliseconds, you have to clear by computing the remainder of ticks smaller than one second. Those are then subtracted from the original value, getting you the same result.
DateTime in .Net is immutable, so you can't just change one property. You have to compute a new value, and then assign it back to the original variable.
It ended up like this:
for (int i = 0; i < rs.Count; i++)
{
r.ReservationTime = r.ReservationTime;
rs[i].ReservationTime = DateTime.Parse(rs[i].ReservationTime.ToString());
if (thisdate.CompareTo(rs[i].ReservationTime) != 0)
{
foreach (string c in courtNames)
{
lboxCourts.Items.Add(c);
}
}
else
{
lboxCourts.Items.Clear();
foreach (string c in courtNames)
{
lboxCourts.Items.Add(c);
}
for (int j = 0; j < rs.Count; j++)
{
if (r.ReservationTime.Equals(rs[j].ReservationTime))
{
string courtName = BookingManager.getInstance().getNameById(rs[j].CourtId);
lboxCourts.Items.Remove(courtName);
}
}
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
else
{
MessageBox.Show("Den valgte dato er ikke gyldig! - vær opmærksom på at hvis du vælger dags dato, at tidspunktet ikke kan være tidligere end nuværende tidspunkt!");
}
}
Thank you for your help... now my method is removing the already booked courts ;-)
Kindest regards
Rasmus