I have 2 datetime pickers and i want to display number of days between them on a text box if a user selects a date.
The problem with my code is that it is not giving me correct answers and the TimeSpan doesn't seem to work.
When i choose different dates it gives me answer 10.999998008713 days instead of 11 days and I don't know if i need to do math roundup
private void btnCalc_Click(object sender, EventArgs e)
{
DateTime start = ArrivalDate.Value;
DateTime finish = DepartureDate.Value;
TimeSpan numberOfNights = finish-start;
double TotalDays= numberOfNights.Days;
txtBoxNum.Text = (numberOfNights.ToString());
}
private void ArrivalDate_ValueChanged(object sender, EventArgs e)
{
DepartureDate.Value = ArrivalDate.Value.AddDays(1);
}
private void DepartureDate_ValueChanged(object sender, EventArgs e)
{
if (DepartureDate.Value < ArrivalDate.Value)
{
MessageBox.Show("Cannot be less than previous date");
DepartureDate.Value = ArrivalDate.Value.AddDays(1);
snip...
}
}
i dont know if i need to do math roundup
Neither do we. 10.999998008713 days is about 10 days, 23 hours, 59 minutes and 59 seconds. Do you want to count that as 11 days? If so what about 10 days, 23 hours, 59 minutes and 58 seconds? At some point you are going to have to decide what the cutoff between 10 days and 11 days is. This probably depends on your business rules and we don't know that.
Also, numberOfNights.Days is the day component of your numberOfNights value; so for November 4 2013 that would be 4. Are you sure that's what you want? You don't want numberOfNights.TotalDays, which would be the elapsed time between your finish and start in days?
this one did the trick
int TotalDays= numberOfNights.Days;
txtBoxNum.Text = ((int)Math.Ceiling(numberOfNights.TotalDays)).ToString();
Related
I am try to find a nice way to work out the week number from a non standard starting date. Week 1 shall contain the first Sunday in April. To calculate this, I just loop through the first 7 days in April til I find the first Sunday. Weeks will start on Sunday.
Normally I would attempt to solve this doing something like this:
numberOfDaysDifferenceBetweenEpoch / 7 % 52 + 1;
However about every 5 years it works out as there are 53 weeks in a year. Obviously the function above will not work if it happens to be a 53 week year. An easy solution would be just to make two functions, which take the modulus of 52 or 53 however I'm hoping there is a cleaner way of doing this. What would the best way to approach this problem?
Here is one way that should work. You may want to optimise the GetEpochInYear method if you are using it frequently.
private static DateTime GetEpochInYear(int year)
{
DateTime currentYearEpoch = new DateTime(year, 4, 1);
while (currentYearEpoch.DayOfWeek != DayOfWeek.Sunday)
{
currentYearEpoch = currentYearEpoch.AddDays(1);
}
return currentYearEpoch;
}
private static int GetWeekNumber(DateTime dateOfInterest)
{
DateTime currentYearEpoch = GetEpochInYear(dateOfInterest.Year);
if (dateOfInterest < currentYearEpoch)
{
currentYearEpoch = GetEpochInYear(dateOfInterest.Year - 1);
}
int days = (int)(dateOfInterest - currentYearEpoch).TotalDays;
return (days / 7) +1;
}
Here is the code: Need to modify this to run the service every 15th day and last day of every month
this.serviceTimer.Interval = 300000; // 5 mins
this.serviceTimer.Elapsed += new ElapsedEventHandler (this.serviceTimer_Click);
this.serviceTimer.Start();
Logger.WriteEventLog("Service Started");
Just small Business logic to be done as shown below :
Set time interval for every 24 hours
timer.Interval = 60000*60*24;
Then check for current month and get number of days in current month so you will get total number of days then divide total number of days by 2 so that you have 2 dates
1) last day of month ie total no of days in month
2) middle date of month ie divided by 2
check for current date with these 2 days if it is equal then go for timeElapsed event
{
this.serviceTimer.Elapsed += new ElapsedEventHandler (this.serviceTimer_Click);
}
else
{
do nothing
}
In your serviceTimer_Click
{
...
DateTime nextExecute = DateTime.Now.AddMOnth(1);
timer.Stop();
timer.Interval = (nextExecute - DatTime.Now).TotalMilliseconds;
timer.Start();
}
And to start it:
{
...
DateTime now = DateTime.Now;
DateTime firstExecute = new DateTime( now.Year, now.Month, 15 ); //add time if needed...
if ( firstExecute < now )
{
firstExecute.AddMonth( 1 );
}
timer.Interval = (firstExecute - now).TotalMilliseconds;
}
Not compiled, but you get the drift...
Edit
Speaking about drift: to avoid your execution drifting to a later point in time, you could use a more clever way to build the nextExecute DateTime.
I want to make a Windows Form Application which only shows a timer as:
xx days
xx hours
xx minutes
xx seconds
No option for setting the timer or anything, i want to do that in the code
However, the problem is i want it to count down from current time (DateTime.Now)
to a specific date. So i end up with the time left as TimeSpan type. I'm now in doubt how to actually display this, so it's actually working, and updating (counting down)
Can't seem to find a tutorial that helps me, so i hope i may be able to get some help here :)
You can use a timespan format string and a timer:
DateTime endTime = new DateTime(2013,01,01,0,0,0);
private void button1_Click(object sender, EventArgs e)
{
Timer t = new Timer();
t.Interval = 500;
t.Tick +=new EventHandler(t_Tick);
TimeSpan ts = endTime.Subtract(DateTime.Now);
label1.Text = ts.ToString("d' Days 'h' Hours 'm' Minutes 's' Seconds'");
t.Start();
}
void t_Tick(object sender, EventArgs e)
{
TimeSpan ts = endTime.Subtract(DateTime.Now);
label1.Text = ts.ToString("d' Days 'h' Hours 'm' Minutes 's' Seconds'");
}
following will give you the countdown string
//Get these values however you like.
DateTime daysLeft = DateTime.Parse("1/1/2012 12:00:01 AM");
DateTime startDate = DateTime.Now;
//Calculate countdown timer.
TimeSpan t = daysLeft - startDate;
string countDown = string.Format("{0} Days, {1} Hours, {2} Minutes, {3} Seconds til launch.", t.Days, t.Hours, t.Minutes, t.Seconds);
Use ToDate.Subtract( Now ) then all you have to do is to format the TimeSpan that you get and show it on the form.
You should be able to google something like this and get literally hundreds of results.
http://channel9.msdn.com/coding4fun/articles/Countdown-to, here's the first one that looked good.
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Getting specific days in a month
I've touched on this problem once before, in How to find the 3rd Friday in a month with C#? But since I did not explain my problem well then, I must try again:
My goal here is simple: upon the press of a button (referred to here as "Button1"), I must determine whether today's date is prior to either the first, or the third Wednesday of the month. If this is the case, I must then set the text of a label (referred to here as "lblDate") to the date of whichever of these future Wednesdays is nearest to the current date.
So far, I've written this:
protected void Button1_Click(object sender, EventArgs e)
{
DateTime Now = DateTime.Today;
DateTime TempDate = new DateTime(Now.Year, Now.Month, 1);
if (TempDate.DayOfWeek != DayOfWeek.Wednesday)
{
TempDate = TempDate.AddDays(1);
string date = TempDate.ToString();
lblDate.Text = date;
}
if (TempDate == TempDate.AddDays(1))
{
TempDate = TempDate.AddDays(14);
string date = TempDate.ToString();
lblDate.Text = date;
}
}
As you can see, something is missing. I would greatly appreciate any assistance in filling that in...
You could also try it like this:
protected DateTime getFirstWednesdayOfMonth(DateTime seedDate)
{
DateTime wed1 = new DateTime(seedDate.Year, seedDate.Month, 1); //1st Wednesday can start on the 1st of the month
while (wed1.DayOfWeek != DayOfWeek.Wednesday)
{
wed1 = wed1.AddDays(1);
}
return wed1;
}
protected DateTime getThirdWednesdayOfMonth(DateTime seedDate)
{
DateTime wed3 = new DateTime(seedDate.Year, seedDate.Month, 15); //3rd Wednesday cannot start prior to the 15th of the month
while (wed3.DayOfWeek != DayOfWeek.Wednesday)
{
wed3 = wed3.AddDays(1);
}
return wed3;
}
protected void Button1_Click(object sender, EventArgs e)
{
DateTime Now = DateTime.Today;
DateTime wed1 = getFirstWednesdayOfMonth(Now);
DateTime wed3 = getThirdWednesdayOfMonth(Now);
if (Now < wed1)
{
lblDate.Text = wed1.ToString();
}
else if (Now < wed3)
{
lblDate.Text = wed3.ToString();
}
}
Well I'm not entirely sure this will answer your question but it might get you on the right track. You can figure out the day of the week from the DateTime feature. Just use something similar to:
DateTime dateValue = new DateTime(2008, 6, 11);
Console.WriteLine((int) dateValue.DayOfWeek); // Displays 3
Use that in conjunction with the actual date say something like:
if((int) dateValue.DayOfWeek == 3) //which is Wednesday
if(date < 7 && date > 1)
week == 1st Weds of month
else(date < 21 && date > 14)
week == 3rd Weds of month
That's not exact code obviously but perhaps something along those lines would help out a little. And you will have to adjust the parameters a bit in order to adjust for the 1st not falling exactly on a monday. Since there is only seven days in a week and even if the first falls on a tuesday it just fall within the range of 1 and 7, likewise for 14 and 21. But just play around with that and you should figure the answer out soon enough.
I've a time ticker event, I want to write it to a label in format ( hours:minutes:seconds 00:00:00 ) it does not print the 0 values! it shows like ::1 when starts to count... what to do? Solved, thanks for all replies
private void timer_Tick(object sender, EventArgs e)
{
seconds++;
if(seconds == 59)
{
minutes++;
seconds = 0;
}
if(minutes == 59)
{
hours++;
minutes = 0;
}
this.label1.Text = string.Format("{0:##}:{1:##}:{2:##}", hours, minutes, seconds);
}
A better method is using DateTime and TimeSpan objects. For example:
DataTime start = <set this somehow>
void timer_Tick(...)
{
var elapsed = DateTime.Now - start;
label1.Text = string.Format("{0:HH:mm:ss}", elapsed);
}
Best would be to use TimeSpan and DateTime as others have said. If you want to continue using your current method, though, change the format string to:
string.Format("{0:00}:{1:00}:{2:00}", hours, minutes, seconds)
The 00 format will cause two digits to always be printed, even zeroes.
Try a thought experiment - set seconds and minutes to 58, and walk through your code and see what happens...
Use a TimeSpan