I use nager.date to know if a day is a holiday day or a weekend day Saturday and Sunday).
I need to extract the date (starting from today or any other date) after 5 working days.
DateTime date1 = new DateTime(2019, 12, 23);
int i = 0;
while ( i < 5)
{
if (DateSystem.IsPublicHoliday(date1, CountryCode.IT) || DateSystem.IsWeekend(date1, CountryCode.IT))
{
date1 = date1.AddDays(1);
}
else
{
date1= date1.AddDays(1);
i++;
}
}
The problem of this code is that if the last else occurs, it add me 1 day but without doing any other check.
For example:
If the start date is 13/07/2020, the result will be at the end 18/07/2020 and as you can see is on Saturday.
How could I modify this code to achieve what I need?
The order is important. The AddDays should be called first, and after it is called we check if the new day matches our criteria.
Note: I have renamed the i variable so it is more clear.
DateTime date1 = new DateTime(2019, 12, 23);
int daysAdded = 0;
while (daysAdded < 5)
{
date1 = date1.AddDays(1);
if (!DateSystem.IsPublicHoliday(date1, CountryCode.IT) && !DateSystem.IsWeekend(date1, CountryCode.IT)) {
// We only consider laboral days
// laboral days: They are not holidays and are not weekends
daysAdded ++;
}
}
I always try to generalize my solutions, so here's one enabling LINQ:
public bool IsWorkingDay(DateTime dt)
=> !DateSystem.IsPublicHoliday(dt) && !DateSystem.IsWeekend(dt);
public DateTime NextWorkingDay(DateTime dt)
{
dt = dt.AddDays(1);
while (!IsWorkingDay(dt))
dt = dt.AddDays(1);
return dt;
}
public IEnumerable<DateTime> WorkingDaysFrom(DateTime dt)
{
if (!IsWorkingDay(dt))
dt = NextWorkingDay(dt); // includes initial dt, remove if unwanted
while (true)
{
yield return dt;
dt = NextWorkingDay(dt);
}
}
This will pump out working days from a given date until end of time, and then use LINQ to grab the number you want:
var next5 = WorkingDaysFrom(DateTime.Today).Take(5).ToList();
here's how to get all the working days in 2020:
var working2020 = WorkingDaysFrom(new DateTime(2020, 1, 1))
.TakeWhile(dt => dt.Year == 2020)
.ToList();
DateTime date1 = new DateTime(2019, 12, 23);
int i = 0;
while ( i < 5)
{
date1 = date1.AddDays(1);
if (!DateSystem.IsPublicHoliday(date1, CountryCode.IT) && !DateSystem.IsWeekend(date1, CountryCode.IT))
{
i++;
}
}
but I think that you need a DateTime[] to store all the five days
This is a better and a faster way to do this without using third party libraries.
DateTime nowDate = DateTime.Now;
DateTime expectedDate;
if (nowDate.DayOfWeek == DayOfWeek.Saturday)
{
expectedDate = nowDate.AddDays(6);
}
else if (nowDate.DayOfWeek == DayOfWeek.Sunday)
{
expectedDate = nowDate.AddDays(5);
}
else
{
expectedDate = nowDate.AddDays(7);
}
I thought about the problem, and based on the LINQ suggestion Lasse-v-Karlsen made, developed this code, which gives you most flexibility:
void Main()
{
// a list of public holidays
var holidays = new List<DateTime>() {new DateTime(2020,1,1),
new DateTime(2020,12,24), new DateTime(2020,12,25), new DateTime(2020,12,26)};
// a function checking if the date is a public holiday
Func<DateTime, bool> isHoliday = (dt) => holidays.Any(a=>a==dt);
// the start date
var dt = new DateTime(2020, 07, 13);
// end date, 5 working days later
var endDate = GetWorkingDay(dt, 5, isHoliday);
// print it
Console.WriteLine(endDate?.ToString("yyyy-mm-dd"));
}
public DateTime? GetWorkingDay(DateTime dt, int skipWorkingDays = 0,
Func<DateTime, bool> holidays=null)
{
if (holidays == null) holidays = (dt) => false;
IEnumerable<DateTime> NextWorkingDay(DateTime dt)
{
while (true)
{
var day = dt.DayOfWeek;
if (day != DayOfWeek.Saturday && day != DayOfWeek.Sunday
&& !holidays.Invoke(dt)) yield return dt;
dt = dt.AddDays(1);
}
}
if (skipWorkingDays<0) return null;
if (skipWorkingDays==0) return NextWorkingDay(dt).First();
var nextXDays = NextWorkingDay(dt).Take(skipWorkingDays).ToList();
var endDate = nextXDays.OrderByDescending(d => d).First();
return endDate;
}
Whether you have a list of public holidays like in this example, or a function coming from a library telling you if a date is a public holiday or not, just feel free to modify the Lambda function isHoliday. In your case, it would be defined as:
Func<DateTime, bool> isHoliday = (dt) => DateSystem.IsPublicHoliday(dt, CountryCode.IT);
Related
how can I get the date of selected week which are in the date range selected in C#.
I am new in C#, please help me out to save these dates in DB, which comes under the date range
You could make all the possible Dates between the ranges and then check against a list of DaysOfWeeks:
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var selectedDayOfWeeks = new List<DayOfWeek>{DayOfWeek.Thursday, DayOfWeek.Saturday};
var startDate = new DateTime(2017, 10, 24);
var endDate = new DateTime(2017, 10, 28);
var possibleDates = new List<DateTime>();
for(var current = startDate; current <= endDate; current= current.AddDays(1))
{
if(selectedDayOfWeeks.Contains(current.DayOfWeek))
{
possibleDates.Add(current);
}
}
foreach(var d in possibleDates){
Console.WriteLine(d);
}
}
}
This is one way...
var from = DateTime.Parse("10/24/2018");
var to = DateTime.Parse("11/14/2018");
var dayList = new List<DateTime>();
for (var day = from.Date; day.Date <= to.Date; day = day.AddDays(1))
{
if
(
day.DayOfWeek == DayOfWeek.Monday ||
day.DayOfWeek == DayOfWeek.Wednesday ||
day.DayOfWeek == DayOfWeek.Friday ||
day.DayOfWeek == DayOfWeek.Sunday
)
{
dayList.Add(day);
}
}
DayOfWeek is an enumeration in the system namespace, you can determine your day of week check box and add a corresponding enum value to a list of DayOfWeek and use as Kevin Smith demonstrated
var selectedDaysOfWeek = new List<DayOfWeek>();
var from = DateTime.Parse("10/24/2018");
var to = DateTime.Parse("11/14/2018");
var dayList = new List<DateTime>();
if (checkBoxMonday.IsChecked) { selectedDaysOfWeek.Add(DayOfWeek.Monday); }
if (checkBoxTuesday.IsChecked) { selectedDaysOfWeek.Add(DayOfWeek.Tuesday); }
if (checkBoxWednesday.IsChecked) { selectedDaysOfWeek.Add(DayOfWeek.Wednesday); }
if (checkBoxThursday.IsChecked) { selectedDaysOfWeek.Add(DayOfWeek.Thursday); }
if (checkBoxFriday.IsChecked) { selectedDaysOfWeek.Add(DayOfWeek.Friday); }
if (checkBoxSaturday.IsChecked) { selectedDaysOfWeek.Add(DayOfWeek.Saturday); }
if (checkBoxSunday.IsChecked) { selectedDaysOfWeek.Add(DayOfWeek.Sunday); }
for (var day = from.Date; day.Date <= to.Date; day = day.AddDays(1))
{
if (selectedDaysOfWeek.Contains(day.DayOfWeek))
{
dayList.Add(day);
}
}
foreach(var day in dayList)
{
// Add to day to DB
}
I am working on an Asp.net project using C#. I am facing a problem in this project. This task based on service scheduled according to condition.
Problem:
Two textboxes for dates, one dropdownlist for type
First I have selected two dates according to type generate scheduled.
For example:
I have selected dates 14/03/2014 to 14/6/2014 and type Monthly
Monthly means increase value by 1 month
So the output should look like this
14/04/2014
14/05/2014
14/06/2014
There are three dates that are scheduled between two date range
Question:
How to achieve this task ?
Sorry for poor English.....
Looping and adding one month at a time should work
public IEnumerable<DateTime> GenerateDates(DateTime start, DateTime end)
{
var dates = new List<DateTime>();
var date = new DateTime(start.Year, start.Month, start.Day);
while (date.Month <= end.Month && date.Year <= end.Year)
{
date = date.AddMonths(1);
dates.Add(date);
}
return dates;
}
var listDates = GetDates(new DateTime(2014, 3, 14), new DateTime(2014, 6, 14), "Day").ToList();
public IEnumerable<DateTime> GetDates(DateTime from, DateTime to,string type)
{
switch (type)
{
case "Month":
{
for (var dt = from.AddMonths(1); dt <= to; dt=dt.AddMonths(1))
{
yield return dt;
}
break;
}
case "Day":
{
for (var dt = from.AddDays(1); dt <= to; dt = dt.AddDays(1))
{
yield return dt;
}
break;
}
}
}
If you need to include the '14/03/2014' in the result, just remove from.AddMonths(1) from the for loop
From your question I assume that there are several modes, not just MONTHLY. Therefore I'd propose to add a registry that contains the possible modes and the function that is used to determine the next date. This registry is easily extensible if you want to offer some more modes. The sample uses a string key, but you can also use a enum.
As it is implemented now, the start date is included in the list of dates whereas the end date isn't. You can change this by tweaking the while loop.
class ScheduleDateProvider
{
private static readonly Dictionary<string, Func<DateTime, DateTime>> modesDict;
static ScheduleDateProvider()
{
// Register modes
modesDict = new Dictionary<string, Func<DateTime, DateTime>>();
modesDict.Add("Quaterly", (dt) => dt.AddMonths(3) );
modesDict.Add("Monthly", (dt) => dt.AddMonths(1) );
modesDict.Add("Weekly", (dt) => dt.AddDays(7) );
modesDict.Add("Daily", (dt) => dt.AddDays(1) );
}
public IEnumerable<DateTime> GetDatesInRange(DateTime startDate, DateTime endDate, string mode)
{
// Assemble dates in a list
var getNextDateFct = modesDict[mode];
var lst = new List<DateTime>();
while(startDate < endDate)
{
lst.Add(startDate);
startDate = getNextDateFct(startDate);
}
return lst.AsReadOnly();
}
}
The following code shows how to use the code:
void Main()
{
DateTime startDate = DateTime.Today;
DateTime endDate = DateTime.Today.AddYears(1);
string selectedMode = "Monthly";
var scheduleDateProv = new ScheduleDateProvider();
var dates = scheduleDateProv.GetDatesInRange(startDate, endDate, selectedMode);
foreach(var dt in dates)
Console.WriteLine(dt.ToShortDateString());
}
I have DateStart, DateEnd Periodicity, TypePeriodicity fields.
We have a query:
var result = Events.Where(e => e.DateStart <=today && e.DateEnd >= today).ToList();
I want that this query to check Periodicity.
For example:
name - record1
DateStart = 2012-02-02
DateEnd = 2012-03-31
Periodicity = 2
TypePeriodicity = 1 ( it's mean a week, may be also day = 0, month=2):
I want the following, if current date equals:
2,3,4,5 February - return `record1`
6,7,8..12 - not return, because TypePeriodicity = 1 and Periodicity = 2, which means every 2 weeks
13..19 - return `record1`
20..26 - not return
and so on until `DateEnd`
Thanks.
PS. Maybe not LINQ, but simple method that recieve result as parameter.
Here is something to get you started:
You could define a DateEvaluator delegate like so:
delegate bool DateEvaluator(DateTime startDate, DateTime endDate, DateTime dateToCheck, int periodicity);
The purpose of the delegate would be to evaluate for a given periodicity type if a date should be considered as within range. We would have hence 3 date evaluators.
One for each period type: Lets call them dayPeriodicityChecker, weekPeriodicityChecker and monthPeriodicityChecker
Our dayPeriodicityChecker is straightforward:
DateEvaluator dayPeriodicityChecker = (startDate, endDate, dateToCheck, periodicity) =>
{
if ((dateToCheck < startDate) || (dateToCheck > endDate))
return false;
TimeSpan dateDiff = dateToCheck - startDate;
return dateDiff.Days % periodicity == 0;
};
Our weekPeriodicityChecker needs to account for the start day of week, so the start date would need to be adjusted to the date in which the startDate week actually starts:
DateEvaluator weekPeriodicityChecker = (startDate, endDate, dateToCheck, periodicity) =>
{
if ((dateToCheck < startDate) || (dateToCheck > endDate))
return false;
DateTime adjustedStartDate = startDate.AddDays(-(int)startDate.DayOfWeek + 1);
TimeSpan dateDiff = dateToCheck - adjustedStartDate;
return (dateDiff.Days / 7) % periodicity == 0;
};
Our monthPeriodicityChecker needs to cater for months with a variable number of days:
DateEvaluator monthPeriodicityChecker dateToCheck, periodicity) =>
{
if ((dateToCheck < startDate) || (dateToCheck > endDate))
return false;
int monthDiff = 0;
while (startDate.AddMonths(1) < dateToCheck)
{
monthDiff++
// i'm sure there is a speedier way to calculate the month difference, but this should do for the purpose of this example
}
return (monthDiff - 1) % periodicity == 0;
};
Once you have all your date evaluators defined you could put them in an array like so:
DateEvaluator[] dateEvaluators = new DateEvaluator[]
{
dayPeriodicityChecker,
weekPeriodicityChecker,
monthPeriodicityChecker
};
This will allow you to do :
int periodicityType = 0; // or 1=week or 2=months
bool isDateIn = dateEvaluators[periodicityType ](startDate, endDate, dateTocheck, Periodicity)
So lets test this:
PeriodicityEvent pEvent = new PeriodicityEvent
{
Name = "record1",
DateStart = new DateTime(2012, 02, 02),
DateEnd = new DateTime(2012, 03, 31),
PeriodicityType = 1,
Periodicity = 2
};
DateTime baseDate = new DateTime(2012, 02, 01);
for (int i = 0; i < 30; i++)
{
DateTime testDate = baseDate.AddDays(i);
if (dateEvaluators[pEvent.PeriodicityType](pEvent.DateStart, pEvent.DateEnd, testDate, pEvent.Periodicity))
{
Console.WriteLine("{0} is in", testDate.ToString("dd MMM"));
}
else
{
Console.WriteLine("{0} is out", testDate.ToString("dd MMM"));
}
}
This will produce the desired output as below:
To use you would simply do:
Events.Where(e => dateEvaluators[e.PeriodType](e.DateStart, e.DateEnd, today, e.Periodicity).ToList();
Good luck!
I have two DateTimes, and I want to get all DateTimes between these Dates. Such as, if my Dates are like 01.01.2010 - 05.01.2010, my function should return me a list of date (List), and it must contain 01.01.2010, 02.01.2010, 03.01.2010, 04.01.2010, and 05.01.2010.
I wrote a function like this. It works fine, if my dates are in a month. It won't work if my dates are like 01.01.2010 - 05.02.2010. Because the month changed, and my function can't handle it. Is there a function in C# that returns all dates between two dates? Or how can I handle month change?
public void GetAllDatesAndInitializeTickets(DateTime startingDate, DateTime endingDate)
{
List<DateTime> allDates = new List<DateTime>();
int starting = startingDate.Day;
int ending = endingDate.Day;
for (int i = starting; i <= ending; i++)
{
allDates.Add(new DateTime(startingDate.Year, startingDate.Month, i));
}
Question solved, see Tim Robinson's simple answer to use.
You can use DateTime objects directly in the loop, in place of your int. DateTime.AddDays handles month ends correctly.
for (DateTime date = startingDate; date <= endingDate; date = date.AddDays(1))
allDates.Add(date);
How about something like this?
public IEnumerable<DateTime> DateRange(DateTime fromDate, DateTime toDate)
{
return Enumerable.Range(0, toDate.Subtract(fromDate).Days + 1)
.Select(d => fromDate.AddDays(d));
}
Edit: Tested now. :)
public IEnumerable<DateTime> GetAllDatesAndInitializeTickets(DateTime startingDate, DateTime endingDate)
{
if (endingDate < startingDate)
{
throw new ArgumentException("endingDate should be after startingDate");
}
var ts = endingDate - startingDate;
for (int i = 0; i < ts.TotalDays; i++)
{
yield return startingDate.AddDays(i);
}
}
You were so close... just don't use the day, use the whole date.
static IEnumerable<DateTime> GetAllDatesAndInitializeTickets(DateTime startingDate, DateTime endingDate)
{
List<DateTime> allDates = new List<DateTime>();
for (DateTime i = startingDate; i <= endingDate; i = i.AddDays(1))
{
allDates.Add(i);
}
return allDates.AsReadOnly();
}
Given a lowerdate value and higher date value in String and a frequency as the third parameter this method should return a dictionary of dates; where the key is the start value of a date range and the value is the respective range.
This works fine if the frequency is either weekly or monthly- you can customize it as per your need.
The date values passed should be in proper format or you might need to format it using tryParseExact or something like that.
protected static Dictionary<DateTime, String> getDateRange(String lowerDate, String higherDate, String frequency)
{
DateTime startDate, endDate;
startDate = Convert.ToDateTime(lowerDate);
endDate = Convert.ToDateTime(higherDate);
Dictionary<DateTime, String> returnDict = new Dictionary<DateTime, String>();
while (frequency.Equals("weekly") ? (startDate.AddDays(7) <= endDate) : (startDate.AddMonths(1) <= endDate))
{
if (frequency.Equals("weekly"))
{
returnDict.Add(startDate, startDate + "-" + startDate.AddDays(7));
startDate = startDate.AddDays(8);
}
if (frequency.Equals("monthly"))
{
returnDict.Add(startDate, startDate + "-" + startDate.AddMonths(1));
startDate = startDate.AddMonths(1).AddDays(1);
}
}
returnDict.Add(startDate, startDate + "-" + endDate);
return returnDict;
}
The top solutions will fail if the date includes different hours. Here is a solution getting all hours and all days:
All Days:
static public List<string> get_days_between_two_dates(DateTime start_date, DateTime end_date)
{
List<string> days_list = new List<string>();
DateTime temp_start;
DateTime temp_end;
//--Normalize dates by getting rid of minues since they will get in the way when doing the loop
temp_start = new DateTime(start_date.Year, start_date.Month, start_date.Day);
temp_end = new DateTime(end_date.Year, end_date.Month, end_date.Day);
//--Example Should return
//--1-12-2014 5:59AM - 1-13-2014 6:01AM return 12 and 13
for (DateTime date = temp_start; date <= temp_end; date = date.AddDays(1))
{
days_list.Add(date.ToShortDateString());
}
return days_list;
}
All Hours:
static public List<string> get_hours_between_two_dates(DateTime start_date, DateTime end_date)
{
List<string> hours_24_list = new List<string>();
DateTime temp_start;
DateTime temp_end;
//--Normalize dates by getting rid of minutes since they will get in the way when doing the loop
temp_start = new DateTime(start_date.Year, start_date.Month, start_date.Day, start_date.Hour, 0, 0);
temp_end = new DateTime(end_date.Year, end_date.Month, end_date.Day, end_date.Hour, 0, 0);
//--Example Should return
//--5:59AM - 6:01AM return 5am and 6am
for (DateTime date = temp_start; date <= temp_end; date = date.AddHours(1))
{
hours_24_list.Add(date.ToShortTimeString());
}
return hours_24_list;
}
Based on your starting code and using the features available at the time of writing, here is a quick console app to demonstrate how to do it - use AddDays() instead:
class Program
{
static void Main(string[] args)
{
GetDates(new DateTime(2010, 1, 1), new DateTime(2010, 2, 5));
Console.ReadKey();
}
static List<DateTime> GetDates(DateTime startDate, DateTime endDate)
{
List<DateTime> dates = new List<DateTime>();
while ((startDate = startDate.AddDays(1)) < endDate)
dates.Add(startDate);
return dates;
}
}
Although I think the Enumerable.Range() answer from Matt is a nicer solution.
static IEnumerable<DateTime> GetAllDatesAndInitializeTickets(DateTime startingDate, DateTime endingDate)
{
List<DateTime> allDates = new List<DateTime>();
for (DateTime i = startingDate; i <= endingDate; i = i.AddDays(1))
{
allDates.Add(i);
}
return allDates.AsReadOnly();
}
I'm not even sure how to do this without using some horrible for loop/counter type solution. Here's the problem:
I'm given two dates, a start date and an end date and on a specified interval I need to take some action. For example: for every date between 3/10/2009 on every third day until 3/26/2009 I need to create an entry in a List. So my inputs would be:
DateTime StartDate = "3/10/2009";
DateTime EndDate = "3/26/2009";
int DayInterval = 3;
and my output would be a list that has the following dates:
3/13/2009
3/16/2009
3/19/2009
3/22/2009
3/25/2009
So how the heck would I do something like this? I thought about using a for loop that would iterate between every day in the range with a separate counter like so:
int count = 0;
for(int i = 0; i < n; i++)
{
count++;
if(count >= DayInterval)
{
//take action
count = 0;
}
}
But it seems like there could be a better way?
Well, you'll need to loop over them one way or the other. I prefer defining a method like this:
public IEnumerable<DateTime> EachDay(DateTime from, DateTime thru)
{
for(var day = from.Date; day.Date <= thru.Date; day = day.AddDays(1))
yield return day;
}
Then you can use it like this:
foreach (DateTime day in EachDay(StartDate, EndDate))
// print it or whatever
In this manner you could hit every other day, every third day, only weekdays, etc. For example, to return every third day starting with the "start" date, you could just call AddDays(3) in the loop instead of AddDays(1).
I have a Range class in MiscUtil which you could find useful. Combined with the various extension methods, you could do:
foreach (DateTime date in StartDate.To(EndDate).ExcludeEnd()
.Step(DayInterval.Days())
{
// Do something with the date
}
(You may or may not want to exclude the end - I just thought I'd provide it as an example.)
This is basically a ready-rolled (and more general-purpose) form of mquander's solution.
For your example you can try
DateTime StartDate = new DateTime(2009, 3, 10);
DateTime EndDate = new DateTime(2009, 3, 26);
int DayInterval = 3;
List<DateTime> dateList = new List<DateTime>();
while (StartDate.AddDays(DayInterval) <= EndDate)
{
StartDate = StartDate.AddDays(DayInterval);
dateList.Add(StartDate);
}
Code from #mquander and #Yogurt The Wise used in extensions:
public static IEnumerable<DateTime> EachDay(DateTime from, DateTime thru)
{
for (var day = from.Date; day.Date <= thru.Date; day = day.AddDays(1))
yield return day;
}
public static IEnumerable<DateTime> EachMonth(DateTime from, DateTime thru)
{
for (var month = from.Date; month.Date <= thru.Date || month.Month == thru.Month; month = month.AddMonths(1))
yield return month;
}
public static IEnumerable<DateTime> EachDayTo(this DateTime dateFrom, DateTime dateTo)
{
return EachDay(dateFrom, dateTo);
}
public static IEnumerable<DateTime> EachMonthTo(this DateTime dateFrom, DateTime dateTo)
{
return EachMonth(dateFrom, dateTo);
}
1 Year later, may it help someone,
This version includes a predicate, to be more flexible.
Usage
var today = DateTime.UtcNow;
var birthday = new DateTime(2018, 01, 01);
Daily to my birthday
var toBirthday = today.RangeTo(birthday);
Monthly to my birthday, Step 2 months
var toBirthday = today.RangeTo(birthday, x => x.AddMonths(2));
Yearly to my birthday
var toBirthday = today.RangeTo(birthday, x => x.AddYears(1));
Use RangeFrom instead
// same result
var fromToday = birthday.RangeFrom(today);
var toBirthday = today.RangeTo(birthday);
Implementation
public static class DateTimeExtensions
{
public static IEnumerable<DateTime> RangeTo(this DateTime from, DateTime to, Func<DateTime, DateTime> step = null)
{
if (step == null)
{
step = x => x.AddDays(1);
}
while (from < to)
{
yield return from;
from = step(from);
}
}
public static IEnumerable<DateTime> RangeFrom(this DateTime to, DateTime from, Func<DateTime, DateTime> step = null)
{
return from.RangeTo(to, step);
}
}
Extras
You could throw an Exception if the fromDate > toDate, but I prefer to return an empty range instead []
DateTime startDate = new DateTime(2009, 3, 10);
DateTime stopDate = new DateTime(2009, 3, 26);
int interval = 3;
for (DateTime dateTime=startDate;
dateTime < stopDate;
dateTime += TimeSpan.FromDays(interval))
{
}
DateTime begindate = Convert.ToDateTime("01/Jan/2018");
DateTime enddate = Convert.ToDateTime("12 Feb 2018");
while (begindate < enddate)
{
begindate= begindate.AddDays(1);
Console.WriteLine(begindate + " " + enddate);
}
According to the problem you can try this...
// looping between date range
while (startDate <= endDate)
{
//here will be your code block...
startDate = startDate.AddDays(1);
}
thanks......
DateTime startDate = new DateTime(2009, 3, 10);
DateTime stopDate = new DateTime(2009, 3, 26);
int interval = 3;
while ((startDate = startDate.AddDays(interval)) <= stopDate)
{
// do your thing
}
Here are my 2 cents in 2020.
Enumerable.Range(0, (endDate - startDate).Days + 1)
.ToList()
.Select(a => startDate.AddDays(a));
You can use the DateTime.AddDays() function to add your DayInterval to the StartDate and check to make sure it is less than the EndDate.
You might consider writing an iterator instead, which allows you to use normal 'for' loop syntax like '++'. I searched and found a similar question answered here on StackOverflow which gives pointers on making DateTime iterable.
you have to be careful here not to miss the dates when in the loop a better solution would be.
this gives you the first date of startdate and use it in the loop before incrementing it and it will process all the dates including the last date of enddate hence <= enddate.
so the above answer is the correct one.
while (startdate <= enddate)
{
// do something with the startdate
startdate = startdate.adddays(interval);
}
you can use this.
DateTime dt0 = new DateTime(2009, 3, 10);
DateTime dt1 = new DateTime(2009, 3, 26);
for (; dt0.Date <= dt1.Date; dt0=dt0.AddDays(3))
{
//Console.WriteLine(dt0.Date.ToString("yyyy-MM-dd"));
//take action
}
Iterate every 15 minutes
DateTime startDate = DateTime.Parse("2018-06-24 06:00");
DateTime endDate = DateTime.Parse("2018-06-24 11:45");
while (startDate.AddMinutes(15) <= endDate)
{
Console.WriteLine(startDate.ToString("yyyy-MM-dd HH:mm"));
startDate = startDate.AddMinutes(15);
}
#jacob-sobus and #mquander and #Yogurt not exactly correct.. If I need the next day I wait 00:00 time mostly
public static IEnumerable<DateTime> EachDay(DateTime from, DateTime thru)
{
for (var day = from.Date; day.Date <= thru.Date; day = day.NextDay())
yield return day;
}
public static IEnumerable<DateTime> EachMonth(DateTime from, DateTime thru)
{
for (var month = from.Date; month.Date <= thru.Date || month.Year == thru.Year && month.Month == thru.Month; month = month.NextMonth())
yield return month;
}
public static IEnumerable<DateTime> EachYear(DateTime from, DateTime thru)
{
for (var year = from.Date; year.Date <= thru.Date || year.Year == thru.Year; year = year.NextYear())
yield return year;
}
public static DateTime NextDay(this DateTime date)
{
return date.AddTicks(TimeSpan.TicksPerDay - date.TimeOfDay.Ticks);
}
public static DateTime NextMonth(this DateTime date)
{
return date.AddTicks(TimeSpan.TicksPerDay * DateTime.DaysInMonth(date.Year, date.Month) - (date.TimeOfDay.Ticks + TimeSpan.TicksPerDay * (date.Day - 1)));
}
public static DateTime NextYear(this DateTime date)
{
var yearTicks = (new DateTime(date.Year + 1, 1, 1) - new DateTime(date.Year, 1, 1)).Ticks;
var ticks = (date - new DateTime(date.Year, 1, 1)).Ticks;
return date.AddTicks(yearTicks - ticks);
}
public static IEnumerable<DateTime> EachDayTo(this DateTime dateFrom, DateTime dateTo)
{
return EachDay(dateFrom, dateTo);
}
public static IEnumerable<DateTime> EachMonthTo(this DateTime dateFrom, DateTime dateTo)
{
return EachMonth(dateFrom, dateTo);
}
public static IEnumerable<DateTime> EachYearTo(this DateTime dateFrom, DateTime dateTo)
{
return EachYear(dateFrom, dateTo);
}
If you convert your dates to OADate you can loop thru them as you would do with any double number.
DateTime startDate = new DateTime(2022, 1, 1);
DateTime endDate = new DateTime(2022, 12, 31);
for (double loopDate = startDate.ToOADate(); loopDate <= endDate.ToOADate(); loopDate++)
{
DateTime selectedDate;
selectedDate = DateTime.FromOADate(loopDate);
}