How can I do universal query for date range? - c#

I'm using LINQ for getting list of objects which are in a specific date range. For example, I have current day in DateTime format: 21.05.2016 0:00:00 and I need to get news which were published after 1 day ago (5 day ago, 3 months ago, 1 year ago, 5 years ago) and until this moment. I did it the folowing way:
List<MyObject> data =
DataDownloader.myList.Where(s => s.Date.Year >= fromDate.Year
&& s.Date.Month >= fromDate.Month
&& s.Date.Day >= fromDate.Day
&& s.Date.Year <= toDate.Year
&& s.Date.Month <= toDate.Month
&& s.Date.Day <= toDate.Day).ToList();
toDate is my current date. I find the fromDate by the following:
1 day:
fromDate = toDate;
5 days:
fromDate = toDate.AddDays(-5);
3 months:
fromDate = toDate.AddMonths(-3);
etc.
But I get only 2 news for 3 months. It's 21.04.2016 0:00:00 and 21.05.2016 0:00:00. So you know they differ only numbers of months because my current date is 21.05.2016. What's I do wrong? I should get much more news I know it.

You're comparing each of the elements of a date, which isn't going to give you the right answer.
You're saying for the 'last 3 months' (from 21/02/2016 to 21/05/2016) that the day has to be between 21 and 21, the month between 2 and 5 and the year between 2016 and 2016
You're effectively searching for 21/02/2016, 21/03/2016, 21/04/2016 or 21/05/2016 rather than all dates between.
Just compare the date:
list.Where(x => x.Date >= fromDate && x.Date <= toDate).ToList();

Related

C# Time Period in weeks between 2 dates

I have a web application where the user will input 2 dates. A StartDate and an EndDate. Now I want to write it so that when StartDate and EndDate is selected to determine how many weeks there are and then to display the dates of those weeks for example if the user selects 01-11-2018 as the StartDate and 31-12-2018 as the EndDate then I want to display the following and keep in mind the Weeks are just for reference as to how it is going to look:
Week 98 : 01 November 2018 - 03 November 2018
Week 99 : 04 November 2018 - 10 November 2018
Week 100 : 11 November 2018 - 17 November 2018
I already have the amount of weeks by using this previous post.
Now I just want to be able to to display each individual weeks Start and End date in all the weeks. I tried creating a list with the weeks and then using a Foreach to check the weeks added but this is not quite right. I am just searching for the most efficient way of accomplishing this goal.
Links also checked with similar problems are :
Link1
I have made this snippet... not sure if everything is up to spec:
var startDate = new DateTime(2018, 11, 1);
var endDate = new DateTime(2018, 12, 31);
int diff = (7 + (startDate.DayOfWeek - DayOfWeek.Monday)) % 7;
var weekStartDate = startDate.AddDays(-1 * diff).Date;
var i = 1;
var weekEndDate = DateTime.MinValue;
while(weekEndDate < endDate) {
weekEndDate = weekStartDate.AddDays(6);
var shownStartDate = weekStartDate < startDate ? startDate : weekStartDate;
var shownEndDate = weekEndDate > endDate ? endDate : weekEndDate;
Console.WriteLine($"Week {i++}: {shownStartDate:dd MMMM yyyy} - {shownEndDate:dd MMMM yyyy}");
weekStartDate = weekStartDate.AddDays(7);
}
This assumes your weeks are "counting", starting on the week the start date is in, and uses monday as the first day of week and sunday as the last one (the ranges you see are monday - sunday except for the first/last week, which would use the start/end date instead if it doesn't happen to be monday or sunday)
You can run it online here: https://dotnetfiddle.net/jJ4Ydu
If you also need to know which week of the year it is, then it depends if you want the .NET style or the ISO8601 style... the typical one is the latter, and you can use, for example, the method found on this answer, so it'd look something like: https://dotnetfiddle.net/oJscjF
Notice how Dec-31st-2018 (which is monday) is the week 1 of 2019 on ISO8601, but week 53 for .NET

Getting records upon Financial year 6th April to 5th April using C# and Linq

I have a table in which i have Transaction date and i want to get records from last financial year.
for ex. If today is 17-03-2017 i want to get records from 06-04-2017 to till today. then if my today's date is more than 6th April then get records from this year 06-04-2017 to till today.
How can i get records using c# and linq with this condition.?
I have used this linq query
List<TransactionMaster> donations =
db.TransactionMasters.Where(s => s.DonorId == DonorId &&
s.TransactionDate.Year >= DateTime.Now.Year - 1 &&
s.TransactionDate.Month >= 4 && s.TransactionDate.Day >= 6)
.ToList();
but i get records from only year 2016 and month > April.
So how can i get records for financial year 6th April to 5th April?
Try to compare the dates directly instead of parts, such that:
var date = new DateTime(DateTime.Now.Year, 4,6);
List<TransactionMaster> donations =
db.TransactionMasters.Where(s => s.DonorId == DonorId &&
s.TransactionDate >= date).ToList();

Group by all full weeks between date period - LINQ

I know how to count number of weeks between two dates.
I have a date period (start date and end date).
Is it possible to get Tuple<DateTime, DateTime> or something where item_1 is a start day of week and item_2 is the end? I mean I finally want to see List<Tuple<DateTime, DateTime>>.
For example my period is from 13/09/16 till 5/10/16
As a result I want to see a list with two corteges:
19/09/16 - 25/09/16
26/09/16 - 2/10/16
I have wrote a regular cycle for this but want to have LINQ.
for (var day = start.Date; day.Date <= end.Date; day = day.AddDays(1))
{
if (day.DayOfWeek == DayOfWeek.Monday)
{
if (day.AddDays(6) < end.Date)
result.Add(Tuple.Create(day.Date, day.AddDays(6).Date));
}
}
Also it would be nice to include culture info if a week starting from Sunday like in USA.
It's very crude... but try something like this:
DateTime start = DateTime.Parse("13/09/16");
DateTime end = DateTime.Parse("5/10/16");
CultureInfo culture = Thread.CurrentThread.CurrentCulture;
Enumerable.Range(0, (end - start).Days)
.Where(x => start.AddDays(x).DayOfWeek == culture.DateTimeFormat.FirstDayOfWeek)
.Select(x => new Tuple<DateTime, DateTime>(start.AddDays(x), start.AddDays(x + 6)))
.Where(x => x.Item2 < end);
This will enumerate to:
| index | first | second |
-----------------------------
| 0 | 19/09/16| 25/09/16|
| 1 | 26/09/16| 2/10/16 |
Given a date you can determine the date when the week started by subtracting the first day of week from the day of week of the date. You then need to handle negative numbers in the case where the first day of week is Monday (1) and the day of week of the date is Sunday (0) as 0 - 1 = -1 and not 6. Here is a function that does that:
int GetDayOfWeekOffset(DateTime date, CultureInfo cultureInfo) {
return ((int) (date.DayOfWeek - cultureInfo.DateTimeFormat.FirstDayOfWeek) + 7)%7;
}
So if the first day of the week (determined by CultureInfo) is Monday then the function will return 0, 1, ..., 6 for days Monday, Tuesday, ..., Sunday. When the first day of the week is Sunday then it will return 0, 1, ..., 6 for days Sunday, Monday, ..., Saturday.
You can subtract the number of days returned by the function to get the date a week started given a date in that week:
var firstWeekStart = startDate.AddDays(-GetDayOfWeekOffset(startDate, cultureInfo));
var lastWeekStart = endDate.AddDays(-GetDayOfWeekOffset(endDate, cultureInfo));
These two dates can be used to generate the desired list:
var weekCount = (int) (lastWeekStart - firstWeekStart).TotalDays/7 + 1;
var weeks = Enumerable
.Range(0, weekCount)
.Select(week => firstWeekStart.AddDays(7*week))
.Where(weekStart => startDate <= weekStart && weekStart.AddDays(6) <= endDate)
.Select(weekStart => Tuple.Create(weekStart, weekStart.AddDays(6)))
.ToList();
Notice the Where clause that ensures that only weeks inside the range of dates determined by startDate and endDate are included.
This approach is more "efficient" compared to the answer provided by Scott as the implicit foreach loop enumerates weeks and not days (so up to 7 times fever iterations). However, "efficiency" probably doesn't really matter as long as you don't have to create a very long list of weeks.

Need specific dates in C#

I have an application in WindowsForms where I have to add exceptions if the day is 25th December and 1st January so is something like this
if(DateTime.Now== 25thJanuary) I don't care about the year just the day, so is it possible for C# to get these days?
DateTime now = DateTime.Now;
if (now.Day == 25 && now.Month == 12)
you could check the day and the month of today like this
Easy. For checking 25th December you can do,
if(DateTime.Now.Month == 12 && DateTime.Now.Day == 25)
using System.Diagonastics;
using System.Threading.Tasks;
DateTime now = DateTime.now;
if(now.Day == 25 && now.Month == 12)
{
....................
//Put your code here
....................
}
Well you have two choose to find do is 25th December or 1st January. First is use DateTime.Now this is return not only day, is return and hours and minutes and seconds (for seconds I'm not sure).
In my example I use DateTime.Today who return Year Month and Day. and return default hour minutes and seconds.
if ((DateTime.Today.Month == 12 && DateTime.Today.Day == 25) || (DateTime.Today.Day == 1 && DateTime.Today.Month == 1))
{
// do some stuff
}
I'm not sure but for performance maybe Today is better from Now because is not check what time is now. Today is check only what date is now (If we can talking here for performance).

How to calculate sum of amount for each 5 weeks before in linq?

I am having the amount field in income table in database, as well as the created date in same table. I need data like,
Week 1 => Sum(amount for week 1)
Week 2 => Sum(amount for week 2)
Week 3 => Sum(amount for week 3)
Week 4 => Sum(amount for week 4)
Week 5 => Sum(amount for week 5)
What should be my linq query. I am using entity framework.
Edited:
Say previous 4 week of current week + current week =5 weeks. here current week is the week of today's date. eg. today is 26'th Aug 2014 so current week is from 24'th Aug 2014 (Sunday) to 30'th Aug 2014 (Saturday).
You can use the methods in EntityFunctions to perform date and time arithmetic. So you should start by working out the start and end dates, then use TruncateTime if necessary to truncate your created date to a date (instead of date and time), and use DiffDays to work out "number of days since the start of the period". Then just divide by 7 to group...
DateTime today = DateTime.Today;
DateTime start = today.AddDays(-(int) today.DayOfWeek) // Sunday...
.AddDays(-28); // 4 weeks ago
DateTime end = start.AddDays(7 * 5);
var result = from entry in db.Entries
where entry.Created >= start && entry.Created < end
group entry.Amount by EntityFunctions.DiffDays(start,
EntityFunctions.TruncateTime(entry.Created)) / 7 into g
select new { Week = g.Key + 1, Sum = g.Sum() };
While I'd expect that to work, I haven't personally done any date/time work in EF myself. The general approach should be fine, it's just that you may need to tweak it. Also note that this won't give you any results for weeks that don't have any entries - it's probably easiest to do that outside EF.
EDIT: If the summing part isn't working, it's easy to do the summing locally instead:
var query = from entry in db.Entries
where entry.Created >= start && entry.Created < end
group entry.Amount by EntityFunctions.DiffDays(start,
EntityFunctions.TruncateTime(entry.Created)) / 7;
var result = query.AsEnumerable() // Execute the rest locally
.Select(g => new { Week = g.Key + 1, Sum = g.Sum() });

Categories

Resources