linq select where between dates - c#

I'm trying to add to the dates all the events between Date and DateFinal in order to fill the calendar with the events.
I've already searched but I can't find any solution for this.
pageItems.Add("dates", allEvents.Select(i => i.Date).ToList());
This is what I have so far but only show the days of i.Date and I want to show all of the days between Date and DateFinal.
Cheers and thanks in advance
In the allEvents I have
allEvents = Current.Descendants(n => n.NodeTypeAlias == "EventPage")
.get_Items()
.Select(n => new{
Node = n,
Date = (Helper.ParseXmlDate(n.GetProperty("itemDate")) ?? n.UpdateDate).DatePart(),
DateFinal = (Helper.ParseXmlDate(n.GetProperty("itemDateFinal")) ?? n.UpdateDate).DatePart()
});

Use this:
allEvents.Where(i => i.Date > Date && i.Date < DateFinal).Select(i => i.Date).ToList()

First.. Sorry if I have misunderstood the question
If you have 2 DateTime and you want to select a list of all the Days(as DateTime) between those 2 dates, you could use Enumerable.Range using the amount of days between the Date and DateFinal to loop in your select statement to add a day to the start date and output a list of DateTimes
This will select all the dates between Date and DateFinal.
allevents.Select(i => Enumerable.Range(1, (i.DateFinal - i.Date).Days).Select(dayCount => i.Date.AddDays(dayCount))).ToList()
If you need to include Date and DateFinal to the list you can use
allevents.Select(i => Enumerable.Range(0, 1 + (i.DateFinal - i.Date).Days).Select(dayCount => i.Date.AddDays(dayCount))).ToList()
Input:
Date: 02/20/2013
DateFinal: 02/31/2013
OutPut:
02/20/2013
02/21/2013
02/22/2013
02/23/2013
...
Is that what you mean?

You probably searching for:
TimeSpan span=d2-d1;
span.TotalDays;
so it should look like:
allEvents.Select(i => (DateFinal - i.Date).TotalDays).ToList()
This shows all days between some DateFinal and i.Date
If this is not what you're searching for, please clarify.

Related

.NET when grouping records by hour impossible to use datetime in the select

I'm trying to group a list of records by hour and store the number of record for each hour. Here is my code :
DateTime firstTimeStamp = myRecords.DataBaseRecords.First().TimeStamp;
Statistics = myRecords.DataBaseRecords
.GroupBy(x => x.TimeStamp.Hour)
.Select(group => new GraphModel() { Date =firstTimeStamp.AddHours(group.Key), Value = group.Count() })
.ToList();
The problem is that when I'm on the select fuction, I cannot acces to the DateTime anymore so the field group.key contains a value between 0 and 24. I just need to group all the records by hour and foreach hour, I need to have the number of records in the Value parameter.
You have to group the data by absolute hours as of the first timestamp, i.e. the differences in hours calculated for each TimeStamp value:
Statistics = myRecords.DataBaseRecords
.GroupBy(x => DbFunctions.DiffHours(firstTimeStamp, x.TimeStamp) into g
.Select(g => new GraphModel
{
Date = g.FirstOrDefault().TimeStamp,
Value = g.Count()
};
If this is plain LINQ to objects (not Entity Framework) you can replace ...
DbFunctions.DiffHours(firstTimeStamp, x.TimeStamp)
... by
(x.TimeStamp - firstTimeStamp).TotalHours
If it's LINQ to SQL, use
SqlMethods.DateDiffHour(firstTimeStamp, x.TimeStamp)
Perhaps something like this may work out for you:
DateTime myDateTime = new DateTime(DateTime.Parse(firstTimeStamp).AddHours(group.Key).Ticks);
Question specific to answer above:
...Date = new DateTime(DateTime.Parse(firstTimeStamp).AddHours(group.Key))...

Linq Query to find min and max in a datatable

I am fetching the attendance details of employees in a datatable .
It looks like this
Day SwipeTime
12/31/2012 11AM
12/31/2012 1PM
12/31/2012 7PM
12/31/2012 8PM
1/1/2012 2PM
1/1/2012 7PM
1/1/2012 8PM
1/2/2012 10AM
1/2/2012 8PM
I need to display the date and totalhours for an employee
where totalhours = lastswipe - firstwipe
my result would look like
Day TotalHours
12/31/2012 9
1/1/2012 6
1/2/2012 12
So i need to find min and max swipes grouped by date.
Please help me write the query
You can use Enumerable.GroupBy to group by date. Then you could create a Dictionary<DateTime,int> where the key is the date and the value are the total-hours for that date:
Dictionary<DateTime,int> dateGroups = table.AsEnumerable()
.GroupBy(r => r.Field<DateTime>("Date").Date)
.Select(g => new{
Date = g.Key,
TotalHours = g.Sum(r =>
DateTime.ParseExact(r.Field<string>("SwipeTime"),
"htt", CultureInfo.InvariantCulture).Hour)
}).ToDictionary(x => x.Date, x => x.TotalHours);
Edit: So, that was the TotalHours of the whole day, now the desired max-min calculation. You also have changed your desired timespan-format to "11:41 AM". Then i would use DateTime.Parse(str).TimeOfDay to get the timespan.
Dictionary<DateTime, int> dateGroups = table.AsEnumerable()
.GroupBy(r => r.Field<DateTime>("Date").Date)
.Select(g => new
{
Date = g.Key,
TotalHours =
(g.Max(r => DateTime.Parse(r.Field<string>("SwipeTime")).TimeOfDay)
- g.Min(r => DateTime.Parse(r.Field<string>("SwipeTime")).TimeOfDay)).Hours
}).ToDictionary(x => x.Date, x => x.TotalHours);
In this answer ordered list of times for day is created to avoid two things - parsing all rows twice, and creating two sets from parsed values to get max and min item. Also I do not parse day before grouping, because same date will have same string value.
var query = from row in table.AsEnumerable()
group row by row.Field<string>("Day") into g
let times = g.Select(r => DateTime.Parse(r.Field<string>("SwipeTime")))
.OrderBy(t => t.TimeOfDay)
.ToList()
select new
{
DateTime.Parse(g.Key).Date,
(times.Last() - times.First()).TotalHours
};
Result is a collection of anonymous objects with two properties DateTime Date and double TotalHours

Getting all orders that are from this month

Here my current month:
model.SalesForMonth = orders.Where(o => o.DateOfPayment.Value.Month == DateTime.Now.Month)
.Select(o => o.Total)
.Sum();
This is not working as expect as it's also fetching orders that happened last year at the same month.
Sure I could compare year and month, but there must be a more expressive solution I'm not familiar with.
How can I do this cleanly using Linq? (Not sure if relevant but orders is an IQueryable from Entity Framework)
The simplest way would be to create a start and end point:
// TODO: Consider what time zone you want to consider the current date in
var today = DateTime.Today;
var start = new DateTime(today.Year, today.Month, 1);
var end = start.AddMonths(1); // Exclusive end-point
var query = orders.Where(o => o.DateOfPayment.Value >= start &&
o.DateOfPayment.Value < end)
.Sum(o => o.Total)
I'm not sure what you want. You must compare year too to be sure that orders are from this year.
I think you can do it this way with linq:
model.SalesForMonth = orders.Where(o => (o.DateOfPayment.Value.Month == DateTime.Now.Month
&& o.DateOfPayment.Value.Year == DateTime.Now.Year))
.Select(o => o.Total)
.Sum();

How to order by a date part?

I have a DataColumn of DateTime datatype and I want to order by the year in descending order followed by the month in descending order.
Here's what I tried:
table.AsEnumerable()
.OrderByDescending(o => o.Field<DateTime>("MaxDateTaken").Year)
.ThenByDescending(o => o.Field<DateTime>("MaxDateTaken").Month)
I get an invalid cast error because both Year and Month are int datatypes, but I'm specifying DateTime in the <>
Any ideas?
You shouldn't get a cast error because of that - are you sure that field is really a DateTime?
It sounds like you really just want
table.AsEnumerable()
.OrderByDescending(o => o.Field<DateTime>("MaxDateTaken"))
anyway, given that ordering by the year and the month descending is basically ordering by the date descending, except it doesn't do anything with the "day" part. Do you really not want to include the "day" part in your ordering?
Why are you ignoring the day part? It could get simpler:
table = table.AsEnumerable()
.OrderByDescending(o => DateTime.Parse(o.Field<string>("MaxDateTaken")))
I fixed it like this:
table = table.AsEnumerable()
.OrderByDescending(o => DateTime.Parse(o.Field<string>("MaxDateTaken")).Year)
.OrderByDescending(o => DateTime.Parse(o.Field<string>("MaxDateTaken")).Month)

C# LINQ query to select only first date in a month from List<DateTime>

I have a List which contains dates from June 1, 2009 to June 1, 2014. How would I query it in C# LINQ to select only the first date of each month?
Your question is slightly ambiguous. If you want the first item appearing in the list in each month, you can use:
var result = list.GroupBy(x => new { x.Year, x.Month })
.Select(x => x.Min());
The simplest way I think is to filter by the Day property of your dates:
var firstDays = dates.Where(d=> d.Day == 1);
Like this:
dates.Where(d => d.Day == 1);
Or, using query comprehension,
from d in dates where d.Day == 1 select d;
Try the following
public static bool IsFirstDayOfMonth(this DateTime t) {
var other = new DateTime(t.Year,t.Month,1);
return other == t.Date;
}
var allDates = GetTheDates();
var filter = allDates.Where(x => x.IsFirstDayOfMonth());

Categories