I want to filter some documents between a different date. First I tried comparing the dates directly, but the time (hour, minutes, second) doesn't have to be considered. Therefore only the date part is needed, but the following approach is wrong:
DateTime? fromDate = documentFilter.fromDate;
if (fromDate.HasValue) {
filterResults = filterResults.Where (d => d.LastModifiedAt.Value.Year >= fromDate.Value.Year
&& d.LastModifiedAt.Value.Month >= fromDate.Value.Month
&& d.LastModifiedAt.Value.Day >= fromDate.Value.Day);
}
DateTime? toDate = documentFilter.toDate;
if (toDate.HasValue) {
filterResults = filterResults.Where (d => d.LastModifiedAt.Value.Year <= toDate.Value.Year
&& d.LastModifiedAt.Value.Month <= toDate.Value.Month
&& d.LastModifiedAt.Value.Day <= toDate.Value.Day);
}
Consider the from date 8/15/2014 12:00:00 AM and the to date 9/15/2014 12:00:00 AM. If the document has the date 8/16/2014 10:06:25 AM it won't be in the results. The reason is that I directly compare each component (year, month, day). Because the day is 16 and 16 > 15 the last condition is not met.
How can I solve this? Should I set the time to one minute before midnight? Or should I calculate the difference?
Just use the DateTime.Date property:
if (fromDate.HasValue) {
filterResults = filterResults
.Where(d => d.LastModifiedAt.Date >= fromDate.Value.Date);
}
if (toDate.HasValue) {
filterResults = filterResults
.Where(d => d.LastModifiedAt.Date <= toDate.Value.Date);
}
DateTime has a Date property which returns a DateTime for the same day at midnight:
DateTime? fromDate = documentFilter.fromDate;
if (fromDate.HasValue)
filterResults = filterResults.Where(d => d.LastModifiedAt.Value.Date >= fromDate.Value.Date);
DateTime? toDate = documentFilter.toDate;
if (toDate.HasValue)
filterResults = filterResults.Where(d => d.LastModifiedAt.Value.Date <= toDate.Value.Date);
Related
I want to get all dates in the last three months, so I did the following:
protected void BindPermissions(int empNum)
{
var permPeriod = new Dictionary<int, int>();
permPeriod.Add(DateTime.Now.Year, DateTime.Now.Month);
permPeriod.Add(DateTime.Now.AddMonths(-1).Year, (DateTime.Now.AddMonths(-1).Month));
permPeriod.Add(DateTime.Now.AddMonths(-2).Year, (DateTime.Now.AddMonths(-2).Month));
var dt = payload_object.AttendancePermissionBO.permissionList
.Where(x => x.empNum == empNum
&& ((x.permDate.Year == permPeriod.Keys.ElementAtOrDefault(0) && x.permDate.Month == permPeriod.Values.ElementAtOrDefault(0)) ||
(x.permDate.Year == permPeriod.Keys.ElementAtOrDefault(1) && x.permDate.Month == permPeriod.Values.ElementAtOrDefault(1)) ||
(x.permDate.Year == permPeriod.Keys.ElementAtOrDefault(2) && x.permDate.Month == permPeriod.Values.ElementAtOrDefault(2)))).ToList().OrderBy(x => x.permDate);
GV_PermissionHistory.DataSource = dt;
GV_PermissionHistory.DataBind();
}
Is there a better way to do that or this method suits what i need?
It seems like you do not really want all dates in the last three months, but you want all items in your collection where permDate is a date within some date range.
Given your own approach, that some date range seems to be the two previous months plus the entire current month. I.e. for 5th of July 2022, the date range is all of May, June and July 2022.
I think you can simplify your approach by defining a start date and an end date, and compare the permDate values with those two values. A straight-forward way of doing that could be:
var today = DateTime.Today;
var startMonth = today.AddMonths(-2);
var endMonth = today.AddMonths(1);
var startDate = new DateTime(startMonth.Year, startMonth.Month, 1);
var endDate = new DateTime(endMonth.Year, endMonth.Month, 1);
Then, you can use startDate and endDate in your filtering:
var dt = payload_object.AttendancePermissionBO.permissionList
.Where(x =>
x.empNum == empNum &&
x.permDate >= startDate &&
x.permDate < endDate)
.OrderBy(x => x.permDate)
.ToList();
You can use the below code for all the dates of last X- months. You can do some changes based on your requirements.
public static void Main()
{
var list= new List<DateTime>();
for(int i=0;i<3;i++){
var month= DateTime.Now.AddMonths(-i);
var monthDates= GetDates(month.Year, month.Month);
list.AddRange(monthDates);
}
foreach(var item in list){
Console.WriteLine(item.ToString());
}
}
public static List<DateTime> GetDates(int year, int month)
{
return Enumerable.Range(1, DateTime.DaysInMonth(year, month))
.Select(day => new DateTime(year, month, day))
.ToList();
}
Get the date (boundary) three months ago from today.
DateTime threeMonthsAgoDate = DateTime.Now.AddMonths(-3);
Filter the data for permDate that after (inclusive) the date from 3 months ago.
var dt = payload_object.AttendancePermissionBO.permissionList
.Where(x => x.empNum == empNum
&& x.permDate >= threeMonthsAgoDate.Date)
.OrderBy(x => x.permDate)
.ToList();
Updated:
This answer is for querying records from the last 3 months ago until the current date.
Based on Post Owner's requirements and existing code, what he needs is from
Start Date: 2022-05-01
End Date: 2022-07-31 (inclusive)
Hence #Astrid's answer is most accurate.
Good day everyone. I'm new to C# but I can't seem to understand how DateTime work.
All I wanted to do is to check If a (givenday) = today and time is 7pm I wanted to return true. Is this the right way to do it?
Take note ActionDate is a field which is inputed by the user.
DateTime dateA = Convert.ToDateTime(ActionDate);
int a = dateA.Year;
int b = dateA.Month;
int c = dateA.Day;
int d = timeA.Hour;
int e = timeA.Minute;
var newDate = new DateTime(a, b, c, d, e, 0);
DateTime end = Convert.ToDateTime(newDate);
DateTime start = Convert.ToDateTime(A);
TimeSpan span = end.Subtract(start);
Decimal minutes = Convert.ToDecimal(span.TotalMinutes);
if
{
return true;
} else
{
return false;
}
Thank you in advance.
The way to check if a give date is today and is at 7pm is to use DateTime.Now.
Note that 19 is 7pm and 7 is 7am, the Hour property uses 24 hour format.
bool IsCurrentDayAnd7(DateTime dt) => dt.Date == DateTime.Now.Date && dt.Hour == 19;
As #TimSchmelter commented you could use DateTime.Today:
bool IsCurrentDayAnd7(DateTime dt) => dt.Date == DateTime.Today && dt.Hour == 19;
You can use Date property to compare date with current date.
if (newDate.Date == DateTime.Now.Date && newDate.Hour == 19)
{
return true;
}
You have made your code a bit too complicated. First, convert that user input to date, and compate it with current date and time.
DateTime dateA = Convert.ToDateTime(ActionDate);
if (dateA.Date == DateTime.Today && dateA.Hour == 19)
{
//it is current date and hour is 7pm
}
Alternatively, check if user's imput is ok, like this:
DateTime dateA;
if (!DateTime.TryParse(ActionDate, out dateA))
{
//alert user that he's entered wrong date
}
EDIT:
as Tim Schmelter noted, code's a bit more readable using DateTime.Today instead of DateTime.Now.Date
At the moment I have this code to return a table of all dates between 2 dates. How could I change this to have it only return the weekend dates.
The purpose of this is to use the weekend dates to check against column headers in a DataGridView to "grey-out" the weekends. I hope that's clear.
static public List<string> GetDates(DateTime start_date, DateTime end_date)
{
List<string> days_list = new List<string>();
for (DateTime date = start_date; date <= end_date; date = date.AddDays(1))
{
days_list.Add(date.ToShortDateString());
}
return days_list;
}
Use the DateTime.DayOfWeek property.
https://msdn.microsoft.com/en-US/library/system.datetime.dayofweek(v=vs.110).aspx
static public List<string> GetDates(DateTime start_date, DateTime end_date)
{
List<string> days_list = new List<string>();
for (DateTime date = start_date; date <= end_date; date = date.AddDays(1))
{
if (date.DayOfWeek == DayOfWeek.Sunday || date.DayOfWeek == DayOfWeek.Saturday)
days_list.Add(date.ToShortDateString());
}
return days_list;
You can create range of dates and then filter on them using DayOfWeek as #Vitor said:
static public List<DateTime> GetWeekendDates(DateTime start_date, DateTime end_date)
{
return Enumerable.Range(0, (int)((end_date- start_date).TotalDays) + 1)
.Select(n => StartDate.AddDays(n))
.Where(x=>x.DayOfWeek == DayOfWeek.Saturday
|| x.DayOfWeek == DayOfWeek.Sunday)
.ToList();
}
hope this solution will help you
DateTime startDate = new DateTime(2011,3,1);
DateTime endDate = DateTime.Now;
TimeSpan diff = endDate - startDate;
int days = diff.Days;
for (var i = 0; i <= days; i++)
{
var testDate = startDate.AddDays(i);
switch (testDate.DayOfWeek)
{
case DayOfWeek.Saturday:
case DayOfWeek.Sunday:
Console.WriteLine(testDate.ToShortDateString());
break;
}
}
in above code I am finding Saturday and Sunday between 1st March 2011 and today. So I have taken two variables called startDate and endDate. After that I have got difference between them and then via for loop I am checking that day of week is Saturday or Sunday
What I'm basically looking to do is monitor a period of time between 2 dates,
say 01/01/2011 to 04/04/2011.
I am then looking for a way to then compare 2 new dates, where if these new dates fall
between the above ones i can say assign a boolean a value and if they dont i wont.
so if 02/02/2011 to 03/03/2011 then assign the boolean wheras if outside then no.
??
You can just use normal compare operators with DateTime to do this.
For example
public bool Check(DateTime d1, DateTime d2)
{
DateTime StartDate = new DateTime(2011,1,1);
DateTime EndDate = new DateTime(2011,4,4);
return ((d1 >= StartDate && d1 <= EndDate) && (d2 >= StartDate && d2 <= EndDate));
}
This is a straight-forward as:
bool isInside = (testDate >= startDate && testDate <= endDate);
This example show how to check if a date is between two dates.
Code has been tested and works:
DateTime dtStart = new DateTime(2011, 02, 02);
DateTime dtEnd = new DateTime(2011, 03, 03);
if (DateTime.Now >= dtStart && DateTime.Now <= dtEnd)
{
// Date is within range
}
I'm trying to get my linq statement to get me all records between two dates, and I'm not quite sure what I need to change to get it to work: (a.Start >= startDate && endDate)
var appointmentNoShow =
from a in appointments
from p in properties
from c in clients
where a.Id == p.OID && (a.Start.Date >= startDate.Date && endDate)
Just change it to
var appointmentNoShow = from a in appointments
from p in properties
from c in clients
where a.Id == p.OID &&
(a.Start.Date >= startDate.Date && a.Start.Date <= endDate)
var appointmentNoShow = from a in appointments
from p in properties
from c in clients
where a.Id == p.OID
where a.Start.Date >= startDate.Date
where a.Start.Date <= endDate.Date
var QueryNew = _context.Appointments.Include(x => x.Employee).Include(x => x.city).Where(x => x.CreatedOn >= FromDate).Where(x => x.CreatedOn <= ToDate).Where(x => x.IsActive == true).ToList();
So you are scrolling down because the Answers do not work:
This works like magic (but they say it has efficiency issues for big data, And you do not care just like me)
1- Data Type in Database is "datetime" and "nullable" in my case.
Example data format in DB is like:
2018-11-06 15:33:43.640
An in C# when converted to string is like:
2019-01-03 4:45:16 PM
So the format is :
yyyy/MM/dd hh:mm:ss tt
2- So you need to prepare your datetime variables in the proper format first:
Example 1
yourDate.ToString("yyyy/MM/dd hh:mm:ss tt")
Example 2 - Datetime range for the last 30 days
DateTime dateStart = DateTime.Now.AddDays(-30);
DateTime dateEnd = DateTime.Now.AddDays(1).AddTicks(-1);
3- Finally the linq query you lost your day trying to find (Requires EF 6)
using System.Data.Entity;
_dbContext.Shipments.Where(s => (DbFunctions.TruncateTime(s.Created_at.Value) >= dateStart && DbFunctions.TruncateTime(s.Created_at.Value) <= dateEnd)).Count();
To take time comparison into account as well :
(DbFunctions.CreateDateTime(s.Created_at.Value.Year, s.Created_at.Value.Month, s.Created_at.Value.Day, s.Created_at.Value.Hour, s.Created_at.Value.Minute, s.Created_at.Value.Second) >= dateStart && DbFunctions.CreateDateTime(s.Created_at.Value.Year, s.Created_at.Value.Month, s.Created_at.Value.Day, s.Created_at.Value.Hour, s.Created_at.Value.Minute, s.Created_at.Value.Second) <= dateEnd)
Note the following method mentioned on other stackoverflow questions and answers will not work correctly:
....
&&
(
s.Created_at.Value.Day >= dateStart.Day && s.Created_at.Value.Day <= dateEnd.Day &&
s.Created_at.Value.Month >= dateStart.Month && s.Created_at.Value.Month <= dateEnd.Month &&
s.Created_at.Value.Year >= dateStart.Year && s.Created_at.Value.Year <= dateEnd.Year
)).count();
if the start day was in this month for example and the end day is on the next month, the query will return false and no results, for example:
DatabaseCreatedAtItemThatWeWant = 2018/12/05
startDate = 2018/12/01
EndDate = 2019/01/04
the query will always search for days between 01 and 04 without taking the "month" into account, so "s.Created_at.Value.Day <= dateEnd.Day" will fail
And in case you have really big data you would execute Native SQL Query rather than linq
...
... where Shipments.Created_at BETWEEN CAST(#Created_at_from as datetime) AND CAST(#Created_at_to as datetime))
....
Thanks
If someone interested to know how to work with 2 list and between dates
var newList = firstList.Where(s => secondList.Any(secL => s.Start > secL.RangeFrom && s.End < secL.RangeTo))
public List<tbltask> gettaskssdata(int? c, int? userid, string a, string StartDate, string EndDate, int? ProjectID, int? statusid)
{
List<tbltask> tbtask = new List<tbltask>();
DateTime sdate = (StartDate != "") ? Convert.ToDateTime(StartDate).Date : new DateTime();
DateTime edate = (EndDate != "") ? Convert.ToDateTime(EndDate).Date : new DateTime();
tbtask = entity.tbltasks.Include(x => x.tblproject).Include(x => x.tbUser).
Where(x => x.tblproject.company_id == c
&& (ProjectID == 0 || ProjectID == x.tblproject.ProjectId)
&& (statusid == 0 || statusid == x.tblstatu.StatusId)
&& (a == "" || (x.TaskName.Contains(a) || x.tbUser.User_name.Contains(a)))
&& ((StartDate == "" && EndDate == "") || ((x.StartDate >= sdate && x.EndDate <= edate)))).ToList();
return tbtask;
}
this my query for search records based on searchdata and between start to end date
If you have date interval filter condition and you need to select all records which falls partly into this filter range. Assumption: records has ValidFrom and ValidTo property.
DateTime intervalDateFrom = new DateTime(1990, 01, 01);
DateTime intervalDateTo = new DateTime(2000, 01, 01);
var itemsFiltered = allItems.Where(x=>
(x.ValidFrom >= intervalDateFrom && x.ValidFrom <= intervalDateTo) ||
(x.ValidTo >= intervalDateFrom && x.ValidTo <= intervalDateTo) ||
(intervalDateFrom >= x.ValidFrom && intervalDateFrom <= x.ValidTo) ||
(intervalDateTo >= x.ValidFrom && intervalDateTo <= x.ValidTo)
);
I had a problem getting this to work.
I had two dates in a db line and I need to add them to a list for yesterday, today and tomorrow.
this is my solution:
var yesterday = DateTime.Today.AddDays(-1);
var today = DateTime.Today;
var tomorrow = DateTime.Today.AddDays(1);
var vm = new Model()
{
Yesterday = _context.Table.Where(x => x.From <= yesterday && x.To >= yesterday).ToList(),
Today = _context.Table.Where(x => x.From <= today & x.To >= today).ToList(),
Tomorrow = _context.Table.Where(x => x.From <= tomorrow & x.To >= tomorrow).ToList()
};
You can use DbFunctions.TruncateTime(StartDateTime) To remove the time from datetime
var appointmentNoShow =
from a in appointments
from p in properties
from c in clients
where a.Id == p.OID && (DbFunctions.TruncateTime(a.Start) >= DbFunctions.TruncateTime(startDate) && endDate)