I've two dates
21/01/2011 [From Date]
25/01/2011 [To Date]
How can I get all the dates between these ranges using c#
The answer should be
21/01/2011 22/01/2011
23/01/2011 24/01/2011
25/01/2011
var allDates = Enumerable.Range(0, int.MaxValue)
.Select(x => fromDate.Date.AddDays(x))
.TakeWhile(x => x <= toDate.Date);
I'm sure this can help you:
http://geekswithblogs.net/thibbard/archive/2007/03/01/CSharpCodeToGetGenericListOfDatesBetweenStartingAndEndingDate.aspx
var dateArr = new List<DateTime>();
for (var date = startDate; date <= endDate; date = date.AddDays(1)) {
dateArr.Add(date);
}
Now dateArr contains your required dates.
public System.Collections.Generic.IEnumerable<DateTime> GetDatesBetween(
DateTime start,
DateTime end
)
{
DateTime current = start;
while (current <= end)
{
yield return current.Date;
current = current.AddDays(1);
}
}
should do the job
[edit] Added the .Date to "round" the date to midnigth
How about:
var startDT = new DateTime(2011, 01, 21);
var endDT = new DateTime(2011, 01, 25);
var workDT = startDT;
do
{
Console.WriteLine(workDT.ToString("dd/MM/yyyy"));
workDT = workDT.AddDays(1);
} while (workDT <= endDT);
Console.ReadLine();
I dont know if we have anything to do this inbuilt in Framework but you can try this:
DateTime dt1 = new DateTime(2011,01,21);
DateTime dt2 = new DateTime(2011,01,25);
List<DateTime> datetimerange = new List<DateTime>();
while(DateTime.Compare(dt1,dt2) <= 0)
{
datetimerange.Add(dt1);
dt1 = dt1.AddDays(1);
}
if (toDate < fromDate)
return;
var days = (new DateTime[(toDate - fromDate).Days + 1).
Select((x, i) => fromDate.AddDays(i));
Related
I have 2 datetime format as departure date and arrival date, such as 25/04/2014 as a departure and 22/04/2014 as an arrival, now I wish to return the dates between those two as following: 22/04/2014|23/04/2014|24/04/2014|25/04/2014 in C#, do you have any idea for this?
You could avoid to type a loop using Linq
StringBuilder sb = new StringBuilder();
DateTime arrival = new DateTime(2014,4,22);
DateTime departure = new DateTime(2014,4,25);
int days = Convert.ToInt32((departure - arrival).TotalDays);
var rng = Enumerable.Range(0,days+1).ToList();
rng.ForEach(r => sb.Append(arrival.AddDays(r).ToShortDateString() + "|"));
sb.Length--;
Console.WriteLine(sb.ToString());
var startDate = new DateTime(2014, 4, 22);
var endDate = new DateTime(2014, 4, 25);
var sb = new StringBuilder();
while (startDate <= endDate)
{
sb.AppendFormat("|{0}", startDate.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture));
startDate = startDate.AddDays(1);
}
Console.WriteLine(sb.ToString().Substring(1));
See it in action
Like:
var startDate = new DateTime(2014, 04, 25);
var endDate = new DateTime(2014, 04, 29);
var currentDate = startDate;
while (currentDate <= endDate)
{
Console.WriteLine(currentDate);
currentDate = currentDate.AddDays(1);
}
...but with proper formatting, but this would be view-logic.
VoilĂ :
DateTime start = new DateTime(2014, 4, 24);
DateTime end = new DateTime(2014, 4, 22);
DateTime current = start < end ? start : end;
DateTime stop = start < end ? end : start;
List<DateTime> dates = new List<DateTime>();
while (current <= stop)
{
dates.Add(current);
current = current.AddDays(1);
}
StringBuilder sb = new StringBuilder();
foreach (DateTime dt in dates)
{
if (sb.Length > 0)
sb.Append("|");
sb.Append(dt.ToString("dd/MM/yyyy"));
}
Console.WriteLine(sb.ToString());
I trying to find a simple way to solve this.
I have a Initial Date, and a Final Date.
And I want to generate a List<Datetime> with each of the dates in a given period.
Example : Initial Date is "2013/12/01" and Final Date is "2013/12/05".
And I want to automatically populate a list with
"2013/12/01"
"2013/12/02"
"2013/12/03"
"2013/12/04"
"2013/12/05"
What would you suggest me?
Thanks
var startDate = new DateTime(2013, 12, 1);
var endDate = new DateTime(2013, 12, 5);
var dates = Enumerable.Range(0, (int)(endDate - startDate).TotalDays + 1)
.Select(x => startDate.AddDays(x))
.ToList();
for(var day = from.Date; day.Date <= end.Date; day = day.AddDays(1))
{
list.Add(day);
}
DateTime startDate = new DateTime(2013, 12, 1); // or any other start date
int numberOfDays = 5;
var dates = Enumerable.Range(0, numberOfDays)
.Select(i => startDate.AddDays(i))
.ToList();
You can use Linq like:
DateTime startDate = new DateTime(2013, 12, 1);
DateTime endDate = new DateTime(2013, 12, 5);
List<DateTime> dates =
Enumerable.Range(0, ((endDate - startDate).Days) + 1)
.Select(n => startDate.AddDays(n))
.ToList();
For output:
foreach (var item in dates)
{
Console.WriteLine(item.ToShortDateString());
}
Output:
01/12/2013
02/12/2013
03/12/2013
04/12/2013
05/12/2013
You can do something like this:
DECLARE #startdate datetime, #enddate datetime, #increment int
SET #startdate = '2013/12/01'
SET #enddate = '2013/12/05'
SET #increment = 0
WHILE DATEADD(dd, #increment, #startdate) <= #enddate
BEGIN
SELECT DATEADD(dd, #increment, #startdate)
SET #increment = #increment + 1
END
Inside the while loop you can put the values on a table or do whatever you wish instead of just printing them out.
I want to count data of each day from database using the for loop. Here, I don't know to get the begining of day (start from 12 am) and end of that day ( 12 pm) from value of only date. In below code startDate and endDate have only date value e.g. 2/11/2012.
for (DateTime dates = startDate; dates <= endDate; dates.AddDays(1))
{
DateTime BeginingOfDay = begining of value variable dates; // 2/2/2012 00:00:00
DateTime EndOfDay = at end of value variable dates; // 2/2/2012 23:59:59
int count = (from u in db.CDRs where (u.StartTime >= BeginingOfDay && u.StartTime <= EndOfDay) select u).Count();;
dictionary.Add(dates.ToString("MM/dd/yyyy"), count);
}
The best way to deal with this is to use the right combination of lessthan/greaterthan operators with midnight on day n, and midnight on day n+1
so given a day, eg
var date = new Date(2012,8,24); // today
get midnight on that day (start of the day)
var start = new Date(date.Year, date.Month, date.Day, 0,0,0); // could also be date.Date
and to get midnight on the next day just add 1 day
var end = start.AddDays(1);
now use greater-than-or-equal-to for the start, and less-than for the end:
var inRange = x.StartTime>=start && x.EndTime<end
Put together into your example becomes:
for (DateTime dates = startDate; dates <= endDate; dates.AddDays(1))
{
DateTime BeginingOfDay = new DateTime(dates.Year,dates.Month,dates.Day,0,0,0);
DateTime EndOfDay = BeginingOfDay.AddDays(1);
int count = (from u in db.CDRs where (u.StartTime >= BeginingOfDay && u.StartTime < EndOfDay) select u).Count();;
dictionary.Add(dates.ToString("MM/dd/yyyy"), count);
}
This should get you the results you want:
using(var dataContext = new YourDataContext())
{
var dictionary = dataContext.CDRs.GroupBy(u => new
{
u.StartTime.Year,
u.StartTime.Month,
u.StartTime.Day
})
.Select(g => new{ Date = g.Key, Count = g.Count() })
.ToDictionary(g => new DateTime(g.Key.Year, g.Key.Month, g.Key.Day), g=>g.Count);
return dictionary;
}
If i have a time period, lets say DateFrom and DateTo and I have a list of Dates, These dates will be the split dates. For example:
DateTime dateFrom = new DateTime(2012, 1, 1);
DateTime dateTo = new DateTime(2012, 12, 31);
List<DateTime> splitDates = new List<DateTime>
{
new DateTime(2012,2,1),
new DateTime(2012,5,1),
new DateTime(2012,7,1),
new DateTime(2012,11,1),
};
List<Tuple<DateTime, DateTime>> periods = SplitDatePeriod(dateFrom, dateTo, splitDates);
I want the result to be a list of periods, so for the previous example the result should be:
(01/01/2012 - 01/02/2012)
(02/02/2012 - 01/05/2012)
(02/05/2012 - 01/07/2012)
(02/07/2012 - 01/11/2012)
(02/11/2012 - 31/12/2012)
I have already wrote a method to do that:
List<Tuple<DateTime, DateTime>> SplitDatePeriod(DateTime dateFrom, DateTime dateTo, List<DateTime> splitDates)
{
var resultDates = new List<Tuple<DateTime, DateTime>>();
// sort split dates
List<DateTime> _splitDates = splitDates.OrderBy(d => d.Date).ToList();
DateTime _curDate = dateFrom.Date;
for (int i = 0; i <= _splitDates.Count; ++i)
{
DateTime d = (i < _splitDates.Count) ? _splitDates[i] : dateTo;
// skip dates out of range
if (d.Date < dateFrom.Date || d.Date > dateTo.Date)
continue;
resultDates.Add(Tuple.Create(_curDate, d));
_curDate = d.AddDays(1);
}
return resultDates;
}
The Question
It looks so ugly, Is there more neat and shorter way of doing this? using Linq maybe?
This is one that works and takes care of some edge cases also:
var realDates = splitDates
.Where(d => d > dateFrom && d < dateTo)
.Concat(new List<DateTime>() {dateFrom.AddDays(-1), dateTo})
.Select(d => d.Date)
.Distinct()
.OrderBy(d => d)
.ToList();
// now we have (start - 1) -- split1 -- split2 -- split3 -- end
// we zip it against split1 -- split2 -- split3 -- end
// and produce start,split1 -- split1+1,split2 -- split2+1,split3 -- split3+1,end
realDates.Zip(realDates.Skip(1), (a, b) => Tuple.Create(a.AddDays(1), b));
You can do it like this:
List<DateTime> split =
splitDates.Where(d => d >= dateFrom && d <= dateTo).ToList();
List<Tuple<DateTime, DateTime>> periods =
Enumerable.Range(0, split.Count + 1)
.Select(i => new Tuple<DateTime, DateTime>(
i == 0 ? dateFrom : split[i - 1].AddDays(1),
i == split.Count ? dateTo : split[i]
))
.ToList();
While L.B is correct and this probably belongs on Code Review, I felt like taking a crack at this:
Given Your First Code Block, the following code will do what you're asking for:
// List of all dates in order that are valid
var dateSegments = new [] { dateFrom, dateTo }
.Concat(splitDates.Where(x => x > dateFrom && x < dateTo))
.OrderBy(x => x)
.ToArray();
List<Tuple<DateTime, DateTime>> results = new List<Tuple<DateTime, DateTime>>();
for(var i = 0; i < dateSegments.Length - 1; i++)
{
results.Add(new Tuple<DateTime, DateTime>(dateSegments[i], dateSegments[i+1]));
}
If you put all the dates into a single list, then this should work:
var dates = new List<DateTime>
{
new DateTime(2012, 1, 1),
new DateTime(2012, 2, 1),
new DateTime(2012, 5, 1),
new DateTime(2012, 7, 1),
new DateTime(2012, 11, 1),
new DateTime(2012, 12, 31)
};
var z = dates.Zip(dates.Skip(1), (f, s) => Tuple.Create(f.Equals(dates[0]) ? f : f.AddDays(1), s));
List<DateTime> splitDates = GetSplitDates();
DateTime dateFrom = GetDateFrom();
DateTime dateTo = GetDateTo();
List<DateTime> edges = splitDates
.Where(d => dateFrom < d && d < dateTo)
.Concat(new List<DateTime>() {dateFrom, dateTo})
.Distinct()
.OrderBy(d => d)
.ToList();
//must be at least one edge since we added at least one unique date to this.
DateTime currentEdge = edges.First();
List<Tuple<DateTime, DateTime>> resultItems = new List<Tuple<DateTime, DateTime>>();
foreach(DateTime nextEdge in edges.Skip(1))
{
resultItems.Add(Tuple.Create(currentEdge, nextEdge));
currentEdge = nextEdge;
}
return resultItems;
I have Made it simple to get the Dates between the DateRange provided.
Model Object
public class DateObjectClass
{
public DateTime startDate { get; set; }
public DateTime endDate { get; set; }
}
Action :
public List<DateObjectClass> SplitDateRangeByDates(DateTime start,DateTime end)
{
List<DateObjectClass> datesCollection = new List<DateObjectClass>();
DateTime startOfThisPeriod = start;
while (startOfThisPeriod < end)
{
DateTime endOfThisPeriod =new DateTime(startOfThisPeriod.Year,startOfThisPeriod.Month,startOfThisPeriod.Day,23,59,59);
endOfThisPeriod = endOfThisPeriod < end ? endOfThisPeriod : end;
datesCollection.Add(new DateObjectClass() { startDate= startOfThisPeriod ,endDate =endOfThisPeriod});
startOfThisPeriod = endOfThisPeriod;
startOfThisPeriod = startOfThisPeriod.AddSeconds(1);
}
return datesCollection;
}
How to calculate a multiple date difference like
startDate1=("dd-MM-yy") 20-08-2011
endDate1=25-08-11
another
startdate2=27-08-2011
endDate2=30-08-2011
such that output will be
(endDate1-startDate1)+(endDate2-StartDate2) == 8days //only in terms of days
Use TimeSpan to calculate date difference.
Eg:
TimeSpan ts = Date1 - Date2;
int numberOfDays = ts.Days;
More info can be found here
Date - or + Date will return TimeSpan, it has a property named "Days" is what you need.
((endDate1-startDate)+(endDate2-StartDate2)).Days
Try this code :-
DateTime d1 = StarDate
DateTime d2 = EndDate;
TimeSpan t1 = d2.Subtract(d1);
days = t1.Days;
hours = t1.Hours;
Try this,
DateTime strdate = Convert.ToDateTime("1/1/2011");
DateTime enddate = Convert.ToDateTime("1/10/2011");
DateTime strdate1 = Convert.ToDateTime("1/1/2011");
DateTime enddate1 = Convert.ToDateTime("1/10/2011");
int resultdays = (enddate.Subtract(strdate) + enddate1.Subtract(strdate1)).Days;
Complete Code/Answer....
public class DateController : Controller
{
public ActionResult date()
{
int allDiff;
List<int> list=new List<int>();
int flag = 0;
int conflict = 0;
List<int> conf = new List<int>();
conf.Add(0);
int a = 0;
DateTime[] startDate = new DateTime[3];
startDate[0] = new DateTime(2011, 11, 5);
startDate[1] = new DateTime(2011, 11,7);
startDate[2] = new DateTime(2011, 11, 15);
DateTime[] endDate = new DateTime[3];
endDate[0] = new DateTime(2011, 11, 10);
endDate[1] = new DateTime(2011, 11,12);
endDate[2] = new DateTime(2011, 11, 20);
DateTime Min= startDate.Min();
DateTime Max = endDate.Max();
TimeSpan span = Max - Min;
int total = span.Days;
ViewBag.globalTotal = total;
foreach (DateTime e in endDate)
{
foreach (DateTime s in startDate)
{
if (s >= e)
{
TimeSpan span1 = s - e;
allDiff = span1.Days;
list.Add(allDiff);
flag = 1;
conflict = 1;
}
else {
flag = 0;
}
}
if((list.Count==1)&&(conflict==1)&&(list!=null)){
a = list[0];
conf.Add(a);
}
if ((flag == 1)&&(list.Count>1))
{
int m = list.Min();
ViewBag.dhiraj = m;
total = total - m;
list.Clear();
}
}
int confl= conf.Min();
total=total-confl;
ViewBag.Total = total;
return View();
}
}
`
If you want the exact DateDiff function as it works in SQL, you can remove time stamp of the Date variables and then Subtract one from another. It will give u exact number of days.
Ex.
DateTime dt = DateTime.Parse(fromDate.ToShortDateString());
DateTime dt1 = DateTime.Parse(toDate.ToShortDateString());
int noOfDays = dt.Subtract(dt1).TotalDays;