Iterate between two dates in C# - c#

I have two dates:
DateTime fromDate = new DateTime(2013,7,27,12,0,0);
DateTime toDate = new DateTime(2013,7,30,12,0,0);
I want to iterate from fromDate to toDate by incrementing fromDate with a single day and the loop should break when fromDate becomes equal to or greater than the toDate. I have tried this:
while(fromDate < toDate)
{
fromDate.AddDays(1);
}
But this is an infinite loop and won't stop. How can I do this ?

Untested but should work:
for(DateTime date = fromDate; date < toDate; date = date.AddDays(1)) {
}
Modify the comparison to <= if you want to include toDate as well.

DateTime.AddDays indeed adds the specified number of days to the date - but the resulting date is returned as a new DateTime value; the original DateTime value is not changed.
Therefore, make sure you assign the result of the your operation back to the variable you inspect in your loop condition:
while (fromDate < toDate)
{
fromDate = fromDate.AddDays(1);
}

Related

How to check current date is greater then or equal to stored in data base date and time in C#

'Following is the code, I want to be check stored in database date and time if greater or equal then current date and time, if current date is greater then stored date then how to compare Time in this check
DateTime sysDate = DateTime.Now.Date;
int sysMinute = DateTime.Now.Minute;
int sysHour = DateTime.Now.Hour;
DateTime scheduledDate = Convert.ToDateTime(item.Scheduled_Start_Date.ToString()).Date;
int scheduledMinute = Convert.ToDateTime(item.Scheduled_Start_Time.ToString()).Minute;
int scheduledHour = Convert.ToDateTime(item.Scheduled_Start_Time.ToString()).Hour;
if (sysDate >= scheduledDate && sysMinute >= scheduledMinute && sysHour >= scheduledHour)
{
var currency = GetEventCurrency(evDB.EventID);
ev.PriceRange = currency.GetFormattedAmount(item.ScheduledPrice.ToString());
isScheduledPrice = true;
}
When getting system datetime with DateTime.Now you have to be aware that several calls may produce incoherent results. This is specially important on the change of the minute, hour or even day.
Do just one call and operate with that result.
In your question is not necessary to segregate DateTime components.
DateTime sysDate = DateTime.Now;
DateTime scheduledDate = Convert.ToDateTime(item.Scheduled_Start_Date.ToString()).Date;
DateTime scheduledTime = Convert.ToDateTime(item.Scheduled_Start_Time.ToString()).Time;
DateTime scheduledDateTime = scheduledDate + scheduledTime;
Once scheduled datetime is in C# format you can just compare them:
if (sysDate >= scheduledDateTime)
{
var currency = GetEventCurrency(evDB.EventID);
ev.PriceRange = currency.GetFormattedAmount(item.ScheduledPrice.ToString());
isScheduledPrice = true;
}
Datetimes in C# are stored in ticks (100 ns) from 00:00:00 of January 1st of year 1 up to the expressed date and time.
Comparison thus is easy as those are just scalars (internally).

How to get dates between two dates in C#

I would like to get dates between two dates. Instead of expected 9 different dates, I get 875287 and run out of memory. What would be the problem with the code below?
StartDate value is 01/04/2016 00:00:00
EndDate value is 10/04/2016 00:00:00
var selectedDates = new List<DateTime?>();
for (var date = StartDate; date <= EndDate; date.Value.AddDays(1))
{
selectedDates.Add(date);
}
You aren't assigning the value of date.Value.AddDays(1) to anything, so it ends up in an infinite loop. You'd need to change your code so that date is set to the result of AddDays.
for (var date = StartDate; date <= EndDate; date = date.AddDays(1))
{
selectedDates.Add(date);
}
LINQ solution (let's generate selectedDates):
var selectedDates = Enumerable
.Range(0, int.MaxValue)
.Select(index => new DateTime?(StartDate.AddDays(index)))
.TakeWhile(date => date <= EndDate)
.ToList();
As far as I can see, since AddDays method returns a new instance of a DateTime, it does not change the current instance since DateTime is immutable.
Looks like your date is DateTime?, you can change this part as;
for (var date = StartDate; date <= EndDate; date = date.Value.AddDays(1))
{
selectedDates.Add(date);
}
As usr pointed, this might be affected on DST. You might wanna check Dmitry's answer as well.
A shorter notation using Linq's Range method uses the ability to already figure out the number of days using the TimeSpan.Days property after subtracting start from end.
Assuming the start is before end you'd end up with:
DateTime StartDate = new DateTime(1979, 10, 4);
DateTime EndDate = new DateTime(2016, 10, 4);
var dates = Enumerable.Range(0, (EndDate - StartDate).Days + 1)
.Select(day => StartDate.AddDays(day))
If you need it to be Nullable, add:
.Cast<DateTime?>()
If you need this to be a List, add:
.ToList()
It's probably quite a bit more efficient than the other LINQ based solution.
Decided to change it up with a do/while
var selectedDates = new List<DateTime?>();
DateTime? StartDate = DateTime.Parse("01/04/2016 00:00:00");
DateTime? EndDate = DateTime.Parse("10/04/2016 00:00:00");
do
{
selectedDates.Add(StartDate);
StartDate = StartDate.Value.AddDays(1);
}while(StartDate < EndDate);

How to corectly Loop over days

I am trying to make a string with start dates and end dates. That can loop over X number of days.
int nrOfDaysToLoopBy = 3;
List<string> Dates = new List<string>();
string startDate = "2014-01-01"; //this date is given to me by an api I am just hard codeing for testing
string endDate = "2014-01-30";
DateTime StartDate = DateTime.ParseExact(startDate, "yyyy-MM-dd", CultureInfo.InvariantCulture);
DateTime EndDate = DateTime.ParseExact(endDate, "yyyy-MM-dd", CultureInfo.InvariantCulture);
DateTime myDate = StartDate; // setting the initial date
for (DateTime date = StartDate.AddDays(nrOfDaysToLoopBy); date.Date <= EndDate.Date; date = date.AddDays(nrOfDaysToLoopBy))
{
Dates.Add("start-date=" + myDate.ToString("yyyy-MM-dd") + "&end-date=" + date.ToString("yyyy-MM-dd"));
myDate = date.AddDays(1);
}
// Dealing with any left over days.
if (myDate != EndDate && EndDate > myDate)
{
Dates.Add("start-date=" + myDate.ToString("yyyy-MM-dd") + "&end-date=" + EndDate.ToString("yyyy-MM-dd"));
}
My results:
start-date=2014-01-01&end-date=2014-01-04
start-date=2014-01-05&end-date=2014-01-07
The problem here is that there is 4 days between 2014-01-01 and 2014-01-04 not 3.
Results I am trying to get:
start-date=2014-01-01&end-date=2014-01-03
start-date=2014-01-04&end-date=2014-01-06
Update:
Can we agree that the days between 2014-01-01&end-date=2014-01-04 are
2014-01-01, 2014-01-02, 2014-01-03, and 2014-01-04 That's 4
I have been playing with this for a few hours now and nothing I have done has fixed the problem.
The problem here is that there is 4 days between 2014-01-01 and 2014-01-04 not 3.
One could argue that there's 3 days between 2014-01-01 and 2014-01-04: Between 2014-01-01 and 2014-01-04, three 24h periods pass:
2014-01-01 -- 2014-01-02
2014-01-02 -- 2014-01-03
2014-01-03 -- 2014-01-04
You see, the problem is how you define between. If you want to include the start and the end date, you need to adjust the number of dates you add.
Edit:
This fixed the problem. nrOfDaysToLoopBy-1
for (DateTime date = StartDate.AddDays(nrOfDaysToLoopBy-1); date.Date <= EndDate.Date; date = date.AddDays(nrOfDaysToLoopBy))
{
}
Simply change the statement:
DateTime date = StartDate.AddDays(nrOfDaysToLoopBy);
in your for loop initialization to
DateTime date = StartDate.AddDays(nrOfDaysToLoopBy-1);
The issue is that when you add days, the number of days "between" as you're calling it is actually the number of days you add + 1. So monday->monday (zero days added) is 1 day, monday->tuesday (one day added) is 2 days, etc. That's why you need the -1 modification for the start date.
The reason you don't need this alteration on every other iteration on the loop is because of the myDate = date.AddDays(1) line. This reduces the difference between myDate and date by one, bringing it back to the correct difference

Storing dates in a list using c#

I have two textboxes and a button, both textbox have calender attach to them. I want to store the dates which are between the first textbox and second textbox in a list, I am invoking following method on button click.
private void CollectDates()
{
DateTime StartDate = Convert.ToDateTime(txtFromDate.Text);
DateTime EndDate = Convert.ToDateTime(txtTillDate.Text);
List<DateTime> datelist = new List<DateTime>();
for (StartDate = Convert.ToDateTime(txtFromDate.Text); StartDate < Convert.ToDateTime(txtTillDate.Text); StartDate.AddDays(1))
{
datelist.Add(StartDate);
}
}
But I am getting error after storing the first date in the list: Exception of type 'System.OutOfMemoryException' was thrown.
I think my loop is running endlessly, any help will be appreciated.
DateTime.AddDays() does not change the datetime you must assign its return value. Like
StartDate = StartDate.AddDays(1)
It is indeed an infinite loop. You're stating that if the start date is less than the end date, add start date to the list. It'll keep doing this for infinity as start date should always (in theory) be less than the end date. The add days function isn't assigned to a variable so it never gets added to the start date.
Also another piece of advice with .Net datetime is to use the in-built compare function.
DateTime Compare function
Hope that helps!
Try this:
private void CollectDates()
{
DateTime StartDate = Convert.ToDateTime(txtFromDate.Text);
DateTime EndDate = Convert.ToDateTime(txtTillDate.Text);
List<DateTime> dateList = new List<DateTime>();
DateTime currentDate = StartDate;
while(currentDate <= EndDate)
{
dateList.Add(currentDate);
currentDate.AddDays(1);
}
}
use this
for (int i =0; i<(EndDate-StartDate).Days; i++)
{
datelist.Add(StartDate.AddDays(i));
}
you might want to try linq:
Enumerable.Range(0, (int)endDate.Subtract(startDate).TotalDays)
.Select(d => startDate.AddDays(d))
.ToList()

Iterate over each Day between StartDate and EndDate [duplicate]

This question already has answers here:
How do I loop through a date range?
(17 answers)
Closed 6 years ago.
I have a DateTime StartDate and EndDate.
How can I, irrespective of times, iterate across each Day between those two?
Example: StartDate is 7/20/2010 5:10:32 PM and EndDate is 7/29/2010
1:59:12 AM.
I want to be able to iterate across 7/20, 7/21, 7/22 .. 7/29.
for(DateTime date = StartDate; date.Date <= EndDate.Date; date = date.AddDays(1))
{
...
}
The .Date is to make sure you have that last day, like in the example.
An alternative method that might be more reusable is to write an extension method on DateTime and return an IEnumerable.
For example, you can define a class:
public static class MyExtensions
{
public static IEnumerable EachDay(this DateTime start, DateTime end)
{
// Remove time info from start date (we only care about day).
DateTime currentDay = new DateTime(start.Year, start.Month, start.Day);
while (currentDay <= end)
{
yield return currentDay;
currentDay = currentDay.AddDays(1);
}
}
}
Now in the calling code you can do the following:
DateTime start = DateTime.Now;
DateTime end = start.AddDays(20);
foreach (var day in start.EachDay(end))
{
...
}
Another advantage to this approach is that it makes it trivial to add EachWeek, EachMonth etc. These will then all be accessible on DateTime.
You have to be careful about end-date. For example, in
Example: StartDate is 7/20/2010 5:10:32 PM and EndDate is 7/29/2010 1:59:12 AM.
I want to be able to iterate across 7/20, 7/21, 7/22 .. 7/29.
date < endDate will not include 7/29 ever. When you add 1 day to 7/28 5:10 PM - it becomes 7/29 5:10 PM which is higher than 7/29 2 AM.
If that is not what you want then I'd say you do
for (DateTime date = start.Date; date <= end.Date; date += TimeSpan.FromDays(1))
{
Console.WriteLine(date.ToString());
}
or something to that effect.
The loops of #Yuriy Faktorovich, #healsjnr and #mho will all throw a System.ArgumentOutOfRangeException: The added or subtracted value results in an un-representable DateTime
exception if EndDate == DateTime.MaxValue.
To prevent this, add an extra check at the end of the loop
for(DateTime date = StartDate; date.Date <= EndDate.Date; date = date.AddDays(1))
{
...
if (date.Date == DateTime.MaxValue.Date)
{
break;
}
}
(I would have posted this as a comment to #Yuriy Faktorovich's answer, but I lack reputation)
DateTime date = DateTime.Now;
DateTime endDate = date.AddDays(10);
while (date < endDate)
{
Console.WriteLine(date);
date = date.AddDays(1);
}

Categories