I made a <List>DateTime class which named GetDataRange so that users can get days between two specific days.
Then I want to show days in the columns of data grid view. I use a foreach loop, This loop will cause a problem. The problem is it won't show all days in the columns because I want to show all days in other calendar. see the codes :
for (int i = 0; i < dtEnd.Subtract(dtStart).Days; i++)
{
TimeSpan counter = new TimeSpan(i, 0, 0, 0);
string s1 = "10/9/2012";
string s2 = "11/10/2012";
d1 = Convert.ToDateTime(s1);
d2 = Convert.ToDateTime(s2);
foreach (DateTime item in GetDateRange(d1, d2))
{
s = item.ToShortDateString();
}
PersianCalendar p = new PersianCalendar();
DateTime date = Convert.ToDateTime(s);
int day = p.GetDayOfMonth(date);
int month = p.GetMonth(date);
int year = p.GetYear(date);
string dt = string.Format("{0}/{1}/{2}", year, month, day);
dataGridView1.Columns.Add(string.Format("col{0}", i), string.Format("{0} {1}", (dtStart + counter).DayOfWeek.ToString(), dt));
}
It will show only one day because of that foreach loop. DayOfWeek is working perfectly but the problem is showing the days in foreach loop it will only show one day.
UPDATE
string dt only show one day it won't show other days.
You can't do that. because every time in the loop you are overriding the value. can you show the dates in a new row.
Try this :
for (int i = 0; i < dtEnd.Subtract(dtStart).Days; i++)
{
TimeSpan counter = new TimeSpan(i, 0, 0, 0);
dataGridView1.Columns.Add(string.Format("col{0}", i), string.Format("{0}", (dtStart + counter).DayOfWeek.ToString()));
}
Then add new row for that :
d1 = dtStart;
d2 = dtEnd;
foreach (DateTime item in GetDateRange(d1, d2))
{
int day = p.GetDayOfMonth(item);
int month = p.GetMonth(item);
int year = p.GetYear(item);
string dt1 = string.Format("{0}/{1}/{2}", year, month, day);
listBox1.Items.Add(dt1);
}
dataGridView1.Rows.Add();
for (int i = 0; i < dataGridView1.Columns.Count; i++)
{
try
{
dataGridView1.Rows[0].Cells[i].Value = listBox1.Items[i];
}
catch (Exception)
{
}
}
Related
Instead of specifying
"string[] week_Days = {"Monday", "Tuesday"...};"
How to dynamically set days as array?
I tried solving it, but couldn't get starting day as "Sunday" -
DateTime days = DateTime.Now;
string[] weekDays = new string[7];
for (int i = 0; i < weekDays.Length; i++)
{
weekDays[i] = string.Format("{0:dddd}", days.AddDays(i));
Console.WriteLine(weekDays[i]);
days = DateTime.Now;
}
Output -
Wednesday
Thursday
Friday
Saturday
Sunday
Monday
Tuesday
using System;
using System.Globalization;
static void Main()
{
string[] weekDays = new CultureInfo("en-us").DateTimeFormat.DayNames;
for (int i = 1; i <= 7; i++)
Console.WriteLine(weekDays[i % 7]);
}
You could use the DayOfWeek enum:
string[] weekdays = Enum.GetNames(typeof(DayOfWeek));
EDIT: If you need to change the start day of the week:
private static string[] GetWeekdays(DayOfWeek firstDayOfWeek)
{
string[] weekdays = new string[7];
DateTime dateTime = DateTime.Now;
while (dateTime.DayOfWeek != firstDayOfWeek)
{
// Find the next date with start day of week
dateTime = dateTime.AddDays(1);
}
for (int i = 0; i < 7; i++)
{
// Get day of week of current day, add 1 day, iterate 7 times.
weekdays[i] = dateTime.DayOfWeek.ToString();
dateTime = dateTime.AddDays(1);
}
return weekdays;
}
You can use this LINQ query. The only challenge is to get the correct order:
DayOfWeek firstWeekDay = DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek;
string[] weekDays = Enum.GetValues(typeof(DayOfWeek)).Cast<DayOfWeek>()
.OrderBy(dow => dow < firstWeekDay ? 7-(int)dow : dow-firstWeekDay)
.Select(dow => dow.ToString())
.ToArray();
Maybe someone has a more elegant way than this OrderBy.
string[] week_Days = new string[7];
DayOfWeek day = DayOfWeek.Sunday;
for (int i = 0; i < week_Days.Length; i++)
{
week_Days[i] = day.ToString();
Console.WriteLine(week_Days[i]);
day++;
}
Instead of assigning DateTime property, Use DayOfWeek. it solves the issue with ease.
Your code fails because DateTime.Now isn't always on a sunday:
DateTime days = DateTime.Now;
Better use the existing DayOfWeek enum:
string[] weekdays = Enum.GetNames(typeof(DayOfWeek));
This could be done in this way too. Until you get "Monday", add days to the DateTime.Now.
int j = 0;
string[] weekDays = new string[7];
DateTime days = DateTime.Now;
while (weekDays[0] != "Sunday")
{
days = days.AddDays(j++);
weekDays[0] = string.Format("{0:dddd}", days);
if (weekDays[0] != "Sunday")
days = DateTime.Now;
}
for (int i = 0; i < weekDays.Length; i++)
{
weekDays[i] = string.Format("{0:dddd}", days.AddDays(i));
Console.WriteLine(weekDays[i]);
}
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 use the following code to change the Column Name but unfortunately it won't let me do that. Please help me to solve this problem:
DateTime dt = DateTime.Now;
string s = dt.DayOfWeek.ToString();
for (int i = 0; i < 10; i++)
{
dataGridView1.Columns.Add(string.Format("col{0}", i), s);
}
for (int i = 0; i < dataGridView1.Columns.Count; i++)
{
int c = dataGridView1.CurrentCell.ColumnIndex;
string str = dataGridView1.Columns[c].HeaderText;
if (str == "Wednesday")
{
str = "fifth day of week";
}
}
Also is there any way so that I can get all day of week after each other between specific datetimes.
Any help will be appreciated
You need to set DataGridView.Column[index].HeaderText:
DateTime dt = DateTime.Now;
string s = dt.DayOfWeek.ToString();
for (int i = 0; i < 10; i++)
{
dataGridView1.Columns.Add(string.Format("col{0}", i), s);
}
for (int i = 0; i < dataGridView1.Columns.Count; i++)
{
string str = dataGridView1.Columns[i].HeaderText;
if (str == "Wednesday")
{
dataGridView1.Columns[i].HeaderText = "fifth day of week";
}
}
Add this line to Datagridview DataBindingComplete event handler
this.dataGridView1.Columns["your database column name"].HeaderText = " preferred name";
The below code will get all days of week after each other between specific datetimes and print the names of the days as column headers:
DateTime dtStart = new DateTime(2012, 11, 1);
DateTime dtEnd = new DateTime(2012, 11, 7);
for (int i = 0; i < dtEnd.Subtract(dtStart).Days; i++)
{
TimeSpan counter = new TimeSpan(i, 0, 0, 0);
dataGridView1.Columns.Add(string.Format("col{0}", i), (dtStart + counter).DayOfWeek.ToString());
}
I need to calculate the number of days between two dates (DateTime) but with a twist. I want to know how many days fall into each of the months that the two days span. Is there an easy way two do it?
Example:
I have start date 30/03/2011 and end date 05/04/2011 then the result should be something like:
var result = new Dictionary<DateTime, int>
{
{ new DateTime(2011, 3, 1), 2 },
{ new DateTime(2011, 4, 1), 5 }
};
You could try something like this:
using System;
using System.Collections.Generic;
static class Program {
// return dictionary tuple<year,month> -> number of days
static Dictionary<Tuple<int, int>, int> GetNumberOfDays(DateTime start, DateTime end) {
// assumes end > start
Dictionary<Tuple<int, int>, int> ret = new Dictionary<Tuple<int, int>, int>();
DateTime date = end;
while (date > start) {
if (date.Year == start.Year && date.Month == start.Month) {
ret.Add(
Tuple.Create<int, int>(date.Year, date.Month),
(date - start).Days + 1);
break;
} else {
ret.Add(
Tuple.Create<int, int>(date.Year, date.Month),
date.Day);
date = new DateTime(date.Year, date.Month, 1).AddDays(-1);
}
}
return ret;
}
static void Main(params string[] args) {
var days = GetNumberOfDays(new DateTime(2011, 3, 1), new DateTime(2011, 4, 1));
foreach (var m in days.Keys) {
Console.WriteLine("{0}/{1} : {2} days", m.Item1, m.Item2, days[m]);
}
}
}
You can use the class Month of the Time Period Library for .NET:
// ----------------------------------------------------------------------
public Dictionary<DateTime,int> CountMonthDays( DateTime start, DateTime end )
{
Dictionary<DateTime,int> monthDays = new Dictionary<DateTime, int>();
Month startMonth = new Month( start );
Month endMonth = new Month( end );
if ( startMonth.Equals( endMonth ) )
{
monthDays.Add( startMonth.Start, end.Subtract( start ).Days );
return monthDays;
}
Month month = startMonth;
while ( month.Start < endMonth.End )
{
if ( month.Equals( startMonth ) )
{
monthDays.Add( month.Start, month.DaysInMonth - start.Day + 1 );
}
else if ( month.Equals( endMonth ) )
{
monthDays.Add( month.Start, end.Day );
}
else
{
monthDays.Add( month.Start, month.DaysInMonth );
}
month = month.GetNextMonth();
}
return monthDays;
} // CountMonthDays
Usage:
// ----------------------------------------------------------------------
public void CountDaysByMonthSample()
{
DateTime start = new DateTime( 2011, 3, 30 );
DateTime end = new DateTime( 2011, 4, 5 );
Dictionary<DateTime, int> monthDays = CountMonthDays( start, end );
foreach ( KeyValuePair<DateTime, int> monthDay in monthDays )
{
Console.WriteLine( "month {0:d}, days {1}", monthDay.Key, monthDay.Value );
}
// > month 01.03.2011, days 2
// > month 01.04.2011, days 5
} // CountDaysByMonthSample
Simple yes, fast no:
DateTime StartDate = new DateTime(2011, 3, 30);
DateTime EndDate = new DateTime(2011, 4, 5);
int[] DaysPerMonth = new int[12];
while (EndDate > StartDate)
{
DaysPerMonth[StartDate.Month]++;
StartDate = StartDate.AddDays(1);
}
Here's my solution. I did a quick check and it seems to work... let me know if there are any problems:
public Dictionary<DateTime, int> GetMontsBetween(DateTime startDate, DateTime EndDate)
{
Dictionary<DateTime, int> rtnValues = new Dictionary<DateTime, int>();
DateTime startMonth = new DateTime(startDate.Year, startDate.Month, 1);
DateTime endMonth = new DateTime(EndDate.Year, EndDate.Month, 1);
//some checking
if (startDate >= EndDate)
{
rtnValues.Add(startMonth, 0); // Or return null;
}
else if (startDate.Month == EndDate.Month && startDate.Year == EndDate.Year)
{
rtnValues.Add(startMonth, EndDate.Day - startDate.Day);
}
else
{
//Add first month remaining days
rtnValues.Add(startMonth, DateTime.DaysInMonth(startDate.Year, startDate.Month) - startDate.Day);
//Add All months days inbetween
for (DateTime st = startMonth.AddMonths(1); st < endMonth; st = st.AddMonths(1))
{
rtnValues.Add(new DateTime(st.Year, st.Month, 1), DateTime.DaysInMonth(st.Year, st.Month) );
}
//Add last month days
rtnValues.Add(new DateTime(EndDate.Year, EndDate.Month, 1), EndDate.Day);
}
return rtnValues;
}
Little example of how we can accurately get the total months and days between 2 dates using the built-in DateTime.DaysInMonth method which gives us the number of days in each month so we can get 100% accuracy.
DateTime date1 = DateTime.Now.AddDays(60);
DateTime date2 = DateTime.Now;
TimeSpan ts = date1 - date2;
int totalDays = int.Parse(ts.TotalDays.ToString("0"));
int totalMonths = Math.Abs((date1.Month - date2.Month) + 12 * (date1.Year - date2.Year));
int months = 0;
int days = 0;
int totalDaysInMonths = 0;
for (int i = totalMonths; i > 0; i--)
{
int month = date2.Month + i;
int year = date1.Year;
if (month > 12)
{
year++;
int newMonth = month - 12;
month = newMonth;
}
totalDaysInMonths = totalDaysInMonths + DateTime.DaysInMonth(year, month);
}
if (totalDays > totalDaysInMonths)
{
months = totalMonths - 1;
days = totalDays - totalDaysInMonths;
}
else if (totalDays < totalDaysInMonths)
{
months = totalMonths - 1;
int tempTotalDaysInMonths = 0;
for (int i = months; i > 0; i--)
{
int month = date2.Month + i;
int year = date1.Year;
if (month > 12)
{
year++;
int newMonth = month - 12;
month = newMonth;
}
tempTotalDaysInMonths = tempTotalDaysInMonths + DateTime.DaysInMonth(year, month);
}
days = totalDays - tempTotalDaysInMonths;
}
else
{
months = totalMonths;
}
return string.Format("{0} months and {1} days", months, days);
A very quick and dirty run at it using linqpad:
DateTime start = DateTime.Parse("03/30/2011");
DateTime end = new DateTime(2011,04,05,23,59,59);
var startNextMonthFirstDay = new DateTime(start.Year, start.Month+1, 1);
var diffForStartMonth = (startNextMonthFirstDay - start);
var totalDiff = (end-start);
var diff = Math.Round(totalDiff.TotalDays);
var diffForEndMonth = diff - diffForStartMonth.Days;
Dictionary<DateTime, int> result = new Dictionary<DateTime, int>();
result.Add(new DateTime(start.Year, start.Month, 1), diffForStartMonth.Days);
result.Add(new DateTime(end.Year, end.Month, 1), (int)diffForEndMonth);
//Dictionary<DateTime,int>{{new DateTime(2011,3,1),2},{new DateTime(2011,4,1),5}}
result.Dump();
DateTime dt1 = new DateTime(2011, 12, 12);
DateTime dt2 = new DateTime(2011, 06, 12);
TimeSpan ts = dt1.Subtract(dt2);
String s = ts.Days.ToString();
MessageBox.Show(s);
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;
}
}
}