Compare DateTime in a generic list - c#

I'm trying to query a generic list using code below.
ArticleStartDate = Convert.ToDateTime("2013-05-07 09:00:00.450");
var queryable = context.GetQueryable<FeaturedArticleResultItem>()
queryable = queryable.Where(t => t.StartDisplay > ArticleStartDate).OrderBy(t => t.StartDisplay);
I'd like to get results which has a 'StartDisplay' date time later then 9:00am 7th of May, and my query returns list of items later then the day (7th, which is good), however, I've also got the items in the list like 8:30am 7th of May. It looks like it compares the date ok, but not the time...
Hope the above make sense.
Just a bit more info, I just found that t.StartDisplay looks like this {7/05/2013 1:31:00 a.m.}. Does it matter when comparing the time?

Related

How to efficiently search a list of objects with a DateTime property in my scenario

I have an already sorted list of object (sorted by date)
public class HistoryValue{
public DateTime Date {get;set;}
public decimal Value {get;set;
}
Then I have a list of days, for example,
1MonthAgo, 2MonthAgo,3MonthAgo,120MonthAgo
What I need is to find the Value on date
1MonthAgo, 2MonthAgo,3MonthAgo,120MonthAgo
If the date can not be found in the list, I should return the one just before that date. It is easiest to explain in a SQL statement although I am doing the real work in c#:
select top 1 Value
from HistoryValueList
where Date between #d12m-#lookbackdaymax and #d12m order by Date desc
I was thinking of using binary search, but don't think binary search will do exactly what I want. Maybe it is best do a looping and remember the closet object of each?
What you want is a "lower bound" kind of algorithm (please check this question), that is, a binary search (or bisect) algorithm that finds the left most element less than or equal to your search element.
You're in luck, there is such a thing called Language Integrated Query (LINQ) which lets you run queries on objects in C# which implement IEnumerable. That includes the List<HistoryValue> you're using.
You're looking for some code like:
HistoryValue val = historyValues.FirstOrDefault(v => v.Date > dateMin && v.Date <= dateMax);
Where historyValues is your list object.
This is pretty easy in C#. I am supposing that you get all records in list of HistoryValue class from DB!
Then you will write code like this:
List<HistoryValue> list = list; //your list get from db here!
HistoryValue historyValue = list.Where(m=>m.Date >= #12m && m.Date <= #lookbackdaymax ).First();

DocumentClient takes too long when queried over a DateTime field

I have the following code to get the list of some objects from a DocumentDB database:
var document = this._client.CreateDocumentQuery<T>(UriFactory.CreateCollectionUri(dbName, collectionName), queryOptions)
.Where(r => r.pDate >= startDate && r.pDate <= endDate);
var result = document.ToList();
pDate is of type DateTime, and stored in the database as string with ISO8601 format.
The query takes unreasonably too long, like 4 to 5 minutes, to return the results back. When I trace the program it is that .ToList() where the program gets stuck. Oddly, the query quickly returns for some specific start and end dates.
The query also quickly comes back with some results if I put the filter on some fields other than pDate.
My settings are consistent with explanations in this document but I still get a very poor performance almost all the time except for those few exceptions.
I have tried several methods mentioned here and there to resolve the issue, but no luck so far. I appreciate any comment or solution to the problem.
It could be because the indexing that is applied on this particular field.
From this link
https://learn.microsoft.com/en-us/azure/cosmos-db/indexing-policies,
you would need an Range index for range or Order by Queries.
The default index policy that is applied to a collection is
"Hash for Strings and Range for Numbers"
Datetimes are stored as strings, so for running range comparison queries or order by queries you would need to set the indexing policy to "Range" for string datatypes with precision to -1.

Linq: filtering a list by time spans in another list

I have two lists of objects. One list has a value and a datetime. The other list has a start and end time. I want to build a new list containing the objects in the first list that fall between any object in the second list's start time and end time plus 8 hours.
I was thinking I could just loop through the list with time spans and use linq to pull out the relevant items in the first list, check for duplicates and if the new list doesn't contain the value add it. That would work but it seems like there should be a way to do this just by using Linq.
Would anyone have an idea on how to do this with just linq?
Something like this?
values.Where(v => times.Any(t => v.DateTime >= t.StartTime
&& v.DateTime <= t.EndTime)
)

How to add empty groups to a Linq query result set?

I have a very simple query which selects items from a table based on matching the month and then grouping by day. These groups are then used as a data source for a repeater which outputs the group elements as entries "per day".
The problem is that days that don't exist (i.e. there's no group for) will naturally not be displayed, so things for the 6th and 8th, when there's nothing for the 7th, will be seen directly next to each other (think of a calendar view). The question is, given my query below, how could I insert groups with no elements, even when there's no entry for that day?
IQueryable events =
Events
.Where(i => i.Date.Month == date.Month)
.GroupBy(i => i.Date.Day);
I can do this figuring out after the fact, but can I account for it to get the result set at once? Or can a previous tried & tested approach be recommended?
Create your result set like this:
var date = ...;
var events = Enumerable.Range(1, DateTime.DaysInMonth(date.Year, date.Month))
.ToDictionary(
day => new DateTime(date.Year, date.Month, day),
day => new List<Event>());
Then insert into it like this:
var query = Events
.Where(e => e.Date.Year == date.Year)
.Where(e => e.Date.Month == date.Month);
foreach (var e in query)
events[e.Date].Add(e);
If you really want to do this server-side as part of the query, you'll either need to (A) send the list of dates you're interested in as part of the query, or (B) use DBMS-specific functions to construct the set of days you're interested in server-side.
Specific to (B) and SQL, there are things like this: Get the first and last date of next month in MySQL
I personally would just do this client-side. The database query gets whatever data your implementation needs to extract from the database; the user gets whatever information your view needs. To query the database for the data you need to create your view, you don't actually need to know the list of dates in your month, so it really shouldn't be part of the query.

linq query with time zones groupby

I have a linq-to-sql query that works by grouping the data it retrieve in days for a particular month:
var Output = from c ....
where .... // this is the month parameter
group c by c.TheTime.Date into daygroups
select new MyModel(){
Prop1 = (from x in daygroups
where....
select x.ID).Count()
}.ToList();
The problem is that this groups by datetime in terms of server time. I'd like to group them by interval of times so that if we're looking at the result with California time, we're really looking at a list of days that starts at midnight PST.
The query returns a count. The solution I've figured out for now would be to return all the raw data between the beginning and the end of the month in a certain timezone, and then rearranging the raw data in days with the correct timezone, and only then do the count.
Is there a better way to do this?
Try grouping by c.TheTime.Date.AddHours(-8).
However, I'm not sure whether that will work correctly.

Categories