I could swear this was working two days ago, now it throws an exception...
I am checking against some data in a DataTable. I'm basically counting how many times a certain eventID is found within the last 15 minutes. Here's that code:
int startevents = trackingData
.Select("RHEventID = 3 AND RHDateEvent > #" + now + "#" ).Length;
I'm defining the 'now' variable just before that - looks like this:
DateTime now = DateTime.Now.AddMinutes(-15);
However this throws a String was not recognized as a valid DateTime exception. Here is an example of the data in the datatable, in the column for RHDateEvent:
2017-02-14 13:58:27 PM
(edit - yes this is only one date, not two, in the column)
So what am I doing wrong? Do I need to be converting this DateTime somehow?
I'd really recommend to use Linq-To-DataTable instead of the old and limited Select method:
DateTime in15minutes = DateTime.Now.AddMinutes(15);
var matchingRows = from row in trackingData.AsEnumerable()
where row.Field<int>("RHEventID) == 3
&& row.Field<DateTime>("RHDateEvent") > in15minutes
select row;
if you now just need the count use:
int matchingRowCount = matchingRows.Count();
This is more readable, powerful and supports compile time safety.
If your column is a not a DateTime- but a string-column you need to parse it:
...
&& DateTime.Parse(row.Field<string>("RHDateEvent"), CultureInfo.InvariantCulture) > in15minutes
It looks like the date time is duplicated...
2017-02-14 13:58:27 PM 2017-02-14 13:57:27 PM
instead of
2017-02-14 13:58:27 PM
If it's linq to entities use
var startevents = trackingData.Where(e => e.RHEventId = 3 && e.RHDateEvent >= DateTime.Now.AddMinutes(-15)).Count();
Related
This is may be silly question. But I am missing logic here. I have to compare dates with date time with hours and minutes (not with seconds).
IF first field time is older then second field execute condition
right now I am doing if (Convert.ToDateTime(newItem["Modified"]) < Convert.ToDateTime(properties.ListItem["Modified"]))
example if("02/12/2015 11:58" < "02/12/2015 12:01") then execute condition.
You could create new DateTime objects with mostly the same values, but with seconds set to 0. Example:
DateTime date1WithoutSeconds = new DateTime(dt1.Year, dt1.Month, dt1.Day, dt1.Hour, dt1.Minute, 0);
DateTime date2WithoutSeconds = new DateTime(dt2.Year, dt2.Month, dt2.Day, dt2.Hour, dt2.Minute, 0);
bool b = date1WithoutSeconds < date2WithoutSeconds;
You could subtract the two dates, and if the TotalSeconds of the difference is less than 60 AND the minues are the same, then they are equal:
var first = Convert.ToDateTime(newItem["Modified"]);
var second = Convert.ToDateTime(properties.ListItem["Modified"]);
if (first.Subtract(second).TotalSeconds < 60 && first.Minute == second.Minute)
{
Console.WriteLine("They are equal");
}
You should use the DateTime.CompareTo method.
Grab and assign both dates as DateTime objects:
DateTime date = Convert.ToDateTime(newItem["Modified"]);
DateTime compareDate = Convert.ToDateTime(properties.ListItem["Modified"]);
You can now use the CompareTo method of the DateTime object to see if the instance is earlier, the same, or later than the other, returning -1, 0, and 1 respectively.
So, following your example: if("02/12/2015 11:58" < "02/12/2015 12:01"), first date being date and second being compareDate, the code:
date.CompareTo(compareDate);
will return -1, telling you the instance invoking the method is earlier than the object you are comparing it to.
Here is the MSDN.
One more way that should work.
DateTime date1 = Convert.ToDateTime(newItem["Modified"]);
DateTime date2 = Convert.ToDateTime(properties.ListItem["Modified"]));
if( date1.AddSeconds(-date1.Second) < date2.AddSeconds(-date2.Second) ) {
}
But, I would wonder...is it really that you need to ignore the seconds and "floor" the result so that 12:59:00 is the same as 12:59:59 but different than 12:58:59 even though there's only a second of difference...or do you need to know that it's greater than a minute of difference? If you really just want to make sure that it is a minute apart, use TimeSpan (date1 - date2).TotalSeconds > 60
I doubt this is likely, but if your DateTime is a string WITH milliseconds, then do:
if( date1.AddSeconds(-date1.Second).AddMilliseconds(-date1.Millisecond) <
date2.AddSeconds(-date2.Second).AddMilliseconds(-date2.Millisecond) )
{
}
First of all, the sample data you've mentioned in your question doesn't include seconds, so by default Convert.ToDateTime will assign '00' as seconds, so it would compare without the seconds.
But let's say that you do provide seconds in the actual data. You can use the following:
var date1 = Convert.ToDateTime(newItem["Modified"]);
var date2 = Convert.ToDateTime(properties.ListItem["Modified"]);
if (date1.AddSeconds(-date1.Second) < date2.AddSeconds(-date2.Second))
I have data in my database that contains the following filed.
Id | name | RegDate
1 John 2014-09-05
2 mike 2014-09-05
3 Duke 2014-10-14
I'm performing a query to count the number of values where the reg date is equal 09. 09 is the month of the date.
I'm trying to convert the date I store in db in a month format then get a new month of a system date to get the result.
Here is my query in linq but it keeps on giving the wrong count. please I need your help. thanks.
var CountPassengers = (from c in db.CountPassengerManifestViews where c.DepartureDate.Month.ToString()== DateTime.Now.AddMonths(-1).ToString("MM") select c).Count();
I would strongly recommend that you get rid of all the string manipulation. Your query doesn't conceptually have anything to do with strings, so why are you introducing them into the code?
You can write your query as:
int currentMonth = DateTime.Today.AddMonths(-1).Month;
var passengerCount = db.CountPassengerManifestViews
.Count(c => c.DepartureDate.Month == currentMonth);
However, that will only filter by month - it won't filter by month and year, so if you have data from 2013 that would be included too. It's more likely that you want something like:
DateTime oneMonthAgo = DateTime.Today.AddMonths(-1);
DateTime start = oneMonthAgo.AddDays(1 - oneMonthAgo.Day);
DateTime end = start.AddMonths(1);
var passengerCount = db.CountPassengerManifestViews
.Count(c => c.DepartureDate >= start &&
c.DepartureDate < end);
That way you're expressing a range of dates, rather than just extracting the month part.
where c.DepartureDate.Month == DateTime.Now.AddMonths(-1).Month
You don't compare string representation, because it's already converted into DateTime object, so it doesn't make sense to do it your way. This simple change should be enough.
I am not sure why you are doing the string manipulation but if you only want to compare the month part of the two dates then do the following:
where c.DepartureDate.Month== DateTime.Now.AddMonths(-1).Month
I think your code compares Month.ToString() that gives "9" with ToString("MM") that gives "09".
You could also improve by removing ".ToString()":
int lastMonth = DateTime.Now.AddMonths(-1).Month;
var CountPassengers = (from c in db.CountPassengerManifestViews where c.DepartureDate.Month == lastMonth select c).Count();
Regards
Try this
var CountPassengers = (from c in db.CountPassengerManifestViews
where c.DepartureDate.Month.ToString("MM")== DateTime.Now.AddMonths(-1).ToString("MM")
select c).Count();
var month = DateTime.Now.AddMonths(-1).Month;
var CountPassengers = db.CountPassengerManifestViews.Count(c => c.DepartureDate.Month == month);
I would like to compare two dates excluding years.
Ex.
Input: FromDate: 01 March, ToDate: 05 March
then all records between these two dates should be come whether there is any year. It does not matter.
So please anyone can help me in this issue.
Thanks in advance.
If you are using LINQ and you want to create a list from querying the db you could do this?
public IEnumerable<Item> WithinTimeRange(DateTime begin, DateTime end)
{
var items = from a in context.Items
where a.Timestamp.Month.Equals(begin.Month) && a.Timestamp.Day
>= begin.Day && a.Timestamp.Month.Equals(end.Month) && a.Timestamp.Day <= end.Day
select a;
return items.ToList();
}
Personally I would create this method in your repository.
Whether you don't specify language and place where it will be used, I just give ju a hint.
Convert every datetime to a integer as: 10000 + 100 * month + day e.g.: 10306 as today.
Then you can ask for every data between 10301 and 10305 from your question.
I have an IQueryable query which I need to use sometimes in the same method.
This query is based on another one which is passed as parameter.
I need to sum the result of a value multiplied by the number of days between two dates.
parameter query = IQueryable lista;
IQueryable<ChildEntity> query = lista.SelectMany(s => s.ChildEntities).Where(w=>w.IsActive.Equals("Y");
DateTime maxDate = lista.Max(m => m.Date);
decimal value = query.Sum(s => (s.Value) * (maxDate - s.ParentEntity.Date).Days);
which gives the exception:
Specified method is not supported.
I've also tried:
decimal value = query.Sum(s => (s.Value) * SqlMethods.DateDiffDay(maxDate, s.Parent.Date);
tried also SqlFunctions.DateDiff and EntityFunctions.DiffDays and all of these last three gives me this exception:
Method 'System.Nullable`1[System.Int32]
DateDiffDay(System.Nullable`1[System.DateTime], System.Nullable`1[System.DateTime])'
is not supported for execution as SQL.
I do not want to use Enumerable because this can result in a huge number of records.
Is there any other way to find a solution for this?
(by the way, I'm using Devart as provider.)
int days = 0;
DateTime today = DateTime.Now;
DateTime maxDate = lista.Max(m => m.Date);
While (today <= maxDate)
{
today.AddDays(7);
days++
}
Your problem is that the database you are running the query on doesn't have a time-span data type like net does, however most databases store a date as number of days since a official start date, this means that if you convert the dates to a number you can just do straight arithmetic on it
days = ((int)maxdate) - ((int)currentdate)
NOTE:thats sudo not runnable
I have the following code:
DataTable t = new DataTable();
t.Locale = CultureInfo.InvariantCulture;
t.Columns.Add("Date", typeof(DateTime));
DateTime today = DateTime.Now;
DateTime yesterday = today.AddDays(-1);
DateTime tomorow = today.AddDays(1);
t.Rows.Add(yesterday);
t.Rows.Add(today);
t.Rows.Add(tomorow);
string filter = string.Format(CultureInfo.InvariantCulture,
"Date >= #{0}# AND Date <= #{1}#", yesterday, tomorow);
t.DefaultView.RowFilter = filter;
foreach (DataRowView v in t.DefaultView)
Console.WriteLine(v["date"]);
I'm expecting that the filtered t.DefaultView now contains all three "days". But for some reason the last date from the range isn't included. It seems <= operator for DateTime type works like a <.
Where is the problem? Is that a bug? Any suggestions how to overcome that?
Update.
Got some responses about DateTime type and comparison operators. Thanks.
But now I want to direct attention to filter expression.
Ok, say I have the folloving loop:
foreach (DataRow r in t.Rows)
{
DateTime date = (DateTime)r["Date"];
if (yesterday <= date && date <= tomorow)
Console.WriteLine(date);
}
This loop should show the same result like
foreach (DataRowView v in t.DefaultView)
Console.WriteLine(v["date"]);
from the previous example, yes? No! Here <= works as I'm expecting and the result is all three days. Why?
Update #2: solution.
As Joe has noted - the problem is about fractions of a second.
If I format upper and lower bounds with Round-trip date/time pattern (to preserve fractions of a second) - everything works just fine:
string filter = string.Format(CultureInfo.InvariantCulture,
"Date >= '{0}' AND Date <= '{1}'",
yesterday.ToString("o", CultureInfo.InvariantCulture),
tomorow.ToString("o", CultureInfo.InvariantCulture));
The date comparison takes the time into account. So, for instance, "today at midday" is greater than just "today". If you use DateTime.Now, the time is included. So, if DateTime.Now is "today at midday", then tomorrow = today.AddDays(1) is less than "tomorrow at 3PM"... So you need to ignore the time part of the date. You can do that by formatting the date without the time. Also, if you want to check that a date is "less or equal than tomorrow" (regardless of the time), check that it is "strictly less than the day after tomorrow" :
string filter = string.Format(CultureInfo.InvariantCulture,
"Date >= #{0:MM/dd/yyyy}# AND Date < #{1:MM/dd/yyyy}#",
yesterday,
tomorrow.AddDays(1));
The code you posted in your update is not equivalent to the row filter.
Your row filter formats the date using the general format for the current culture. This probably does not include fractions of a second - therefore unless you happen to call DateTime.Now on a second boundary, your tomorrow value will be some fractions of a second beyond the range specified by the filter.
I.e. if your tomorrow value is '2009-12-23 01:02:03.456', your row filter is only taking values up to and including '2009-12-23 01:02:03', a few fractions of a second before the value specified by tomorrow.
If you only want to compare dates, you should use DateTime.Date to truncate the time component from your dates (and use DateTime.Today rather than DateTime.Now for the current date).
Try with
DateTime today = DateTime.Today;
if does not solve, check whether your date field contains time also. there lies your problem.
Update: your second comment.
when you compare with DateTime.Now e.g. Date <= 21.12.2009 14:35:35, it will take all before 14:35 hours and will ignore later rows. Hope this helps you.
See following article to get more idea
http://dotnetguts.blogspot.com/2007/06/understanding-datetime-and-timespan-in.html