cannot get a timespan to add to a datetime - c#

I really have tried on this one, it seems so simple.
c#, using linq.
I have a linq query:
var allNewStops = (from stops in rDb.DistributionStopInformations
where stops.CustomerNo == 91000 && stops.StopSignature != "" && stops.ActualServiceDate == dateToCheck
select new
{
stopName = stops.StopName,
signature = stops.StopSignature,
customerRefNumber = stops.CustomerReference,
dateOfStop = stops.ActualServiceDate,
timeOfStop = stops.ActualArrivalTime
}).Distinct();
Which seems to work fine, I need the dateOfStop to be combined with the timeOfStop -- preferably in the query, but afterwards is fine also.
I have tried:
DateTime combined = stopinfo.dateOfStop.Add;
but Add states it is a unknown medthod of datetime
It does show what dateOfStop is a DateTime and timeOfStop is a TimeSpan.
I have tried about 4 dozen different combinations of everything I can think of.
What am I doing wrong??
Thank you!
Joe

From what I saw it seemed like you tried to use Add wrongly as Add needs a parameter (a parameterless version does not exist). That aside as I don't know the exact data layout I made sure to convert the variables explizitely in case they are objects, but if they are already of the appropriate datatype then they can be used without the (DateTime) and (TimeSpan):
var allNewStops = (from stops in rDb.DistributionStopInformations
where stops.CustomerNo == 91000 && stops.StopSignature != "" && stops.ActualServiceDate == dateToCheck select stops)
.AsEnumerable().Select(stops => new {
stopName = stops.StopName,
signature = stops.StopSignature,
customerRefNumber = stops.CustomerReference,
dateOfStop = stops.ActualServiceDate,
timeOfStop = stops.ActualArrivalTime,
combinedStop = ((DateTime)stops.ActualServiceDate).Add((TimeSpan)stops.ActualArrivalTime)
}).Distinct();

DateTime aNewDateTime = theOldDate.Add(aTimeSpan);

If your dateOfStop is from the type DateTime and timeOfStop is a TimeSpan, there should be no problem adding it like this:
DateTime combined = dateOfStop.Add(timeOfStop);

Related

Convert two strings and compare them with each other

I used two strings, one for today's date and one for the database, which is the date that users register. I want to convert these two strings to a solar date and compare them.
This code works well and I converted the first variable correctly and I can compare it
PersianDateTime now = PersianDateTime.Now;
string s = now.ToString("yyyy/MM/dd");
PersianDateTime persianDate = PersianDateTime.Parse(s);
But this code gives an error because it becomes a condition
var ActivitysNotToDo = _context.Activitys.Where(a => a.MasoolAghdamUserID == user.Id && PersianDateTime.Parse(a.ActvityAghdamDate) < persianDate).ToList();
An error occurred in this code. Please also see the photo
PersianDateTime.Parse(a.ActvityAghdamDate)
If the first code works for you, then:
Maybe you can modify this line:
var ActivitysNotToDo = _context.Activitys.Where(a => a.MasoolAghdamUserID == user.Id && PersianDateTime.Parse(a.ActvityAghdamDate) < persianDate).ToList();
For this:
var ActivitysNotToDo = _context.Activitys.Where(a => a.MasoolAghdamUserID == user.Id && PersianDateTime.Parse(Convert.ToDateTime(a.ActvityAghdamDate).ToString("yyyy/MM/dd")) < persianDate).ToList();
DateTime.Parse(); function need string parameter so you have to pass string parameter in your expression.
DateTime now = DateTime.Now;
string s = now.ToString("yyyy/MM/dd");
DateTime.Parse(s);
DateTime.Parse(now.ToString()); // Conversion required
Try following code.
PersianDateTime.Parse(a.ActvityAghdamDate.Value.ToString("yyyy/MM/dd"))
or
PersianDateTime.Parse(Covert.ToDateTime(a.ActvityAghdamDate).ToString("yyyy/MM/dd"))
Implicit client evaluation has been disabled from EF Core 3. You can change your code like below:
var data= _context.Activitys.Where(a => a.MasoolAghdamUserID == user.Id)
.AsEnumerable();
var ActivitysNotToDo = data.Where(a => PersianDateTime.Parse(a.ActvityAghdamDate)<persianDate)
.ToList();
The C# Compare() method is used to compare first string with second string lexicographically. If both strings are equal, it returns 0.

Short Date in Linq

I want my query to stop displaying time and just the date. This is what I've tried to far:
Query= (from z in ctx.Interactions
where z.ActivityDate <= StartDateTo
&& z.ActivityDate >= EndDateTo
&& z.Indepth == false
select new
{
Date = new DateTime(z.ActivityDate.Year, z.ActivityDate.Month, z.ActivityDate.Day),
Subject = z.Subject
}).ToList();
And
Query= (from z in ctx.Interactions
where z.ActivityDate <= StartDateTo
&& z.ActivityDate >= EndDateTo
&& z.Indepth == false
select new
{
Date = z.ActivityDate.Date,
Subject = z.Subject
}).ToList();
And both didn't work.
LINQ to Entities does not recognize the method 'System.String ToString(System.String)' method, and this method cannot be translated into a store expression. when trying to apply a string method.
You can use anyDate.ToString("ddMMyyyy");//any preferred format.
Not sure if that is what you are looking for!
Your queries return objects with Date & Subject properties.
In the Date property you are passing a DateTime object. In order to display the short date you have a "ToShortDateString()" function on a date.
If you dont want to work with a date and prefer selecting a string, then do the conversion inside the linq query.
Use this if you want to return strings:
var q = (from z in ctx.Interactions
where z.ActivityDate <= StartDateTo && z.ActivityDate >= EndDateTo && z.Indepth == false
select new { Date = z.ActivityDate.Date.ToShortDateString(), Subject = z.Subject }).ToList();
You would need to perform the formatting at the time of the binding. As you don't show the actual binding code, it is hard to specifically address your situation but lets look at what happens in your query:
Query= (from z in ctx.Interactions
where z.ActivityDate <= StartDateTo && z.ActivityDate >= EndDateTo && z.Indepth == false
select new { Date = z.ActivityDate.Date, Subject = z.Subject }).ToList();
Once LINQ handles this query, the resulting Query variable should be of type List<DateTime>. The way you have the query working you would return a list of DateTimes in a format like this:
2014-04-23 00:00:00
2014-03-28 00:00:00
etc...
In order to bind this without the time value, you need to call ToString() on each element (or the desired element) of the list at the time of binding.
Assuming you are using a ListBox or something similar you could write the following:
foreach (var date in myList) //this is the resultant list from the query
{
listBox1.Items.Add(date.ToString("MM/dd/yyyy");
}
If you are literally binding to a DataSource property, you will need to convert your List<DateTime> to a List<string> with the formatted values.
ToShortDateString() may help you.
Query= (from z in ctx.Interactions
where z.ActivityDate <= StartDateTo
&& z.ActivityDate >= EndDateTo
&& z.Indepth == false
select new
{
Date = z.ActivityDate.ToShortDateString(),
Subject = z.Subject
}).ToList();
convert date into string like below
string stringDate=string.empty;
stringDate=Convert.ToDateTime("2014-04-23 00:00:00").ToShortDateString();
it will give output like
2014-04-23

New to programming how to make this code more concise

Hi this is my first question so apologies if it is really basic - I am very new to programming!!!
Using c# in MVC I am trying to select object which has a Date property from entitymodel context. This date then selects the relevant Weight object and so on to get my list of "Set" objects.
The code works and does what I want but would like some general guidance on how to make this code more concise. Here is the code:
public ActionResult showDiary(string datein)
{
LocalTestEntities1 dblists = new LocalTestEntities1();
DateTime date = Convert.ToDateTime(datein);
IEnumerable<ExerciseDiary> diary = from o in dblists.ExerciseDiaries where o.Date == date select o;
var mydiary = diary.ToList();
ExerciseDiary thediary = mydiary[0];
IQueryable<Weight> weights = from o in dblists.Weights where o.DiaryID == thediary.ID select o;
var selectedWeight = weights.ToList();
Weight weight = selectedWeight[0];
IEnumerable<Set> sets = from x in dblists.Sets where x.WeightId == weight.WeightID select x;
return View(sets);
}
It seems that I am taking too many steps here. I know that I am only returning one object to diary. Is there a way to get this object from dblists without sending to an IEnumerable?
Using the First() method will make things a little more concise:
public ActionResult showDiary(string datein)
{
using (LocalTestEntities1 dblists = new LocalTestEntities1())
{
DateTime date = Convert.ToDateTime(datein);
var thediary = (from o in dblists.ExerciseDiaries
where o.Date == date
select o).First();
var weight = (from o in dblists.Weights
where o.DiaryID == thediary.ID
select o).First();
var sets = (from x in dblists.Sets
where x.WeightId == weight.WeightID
select x).ToList();
}
return View(sets);
}
You should also wrap your LINQ to Entities data access in a using block so it's properly disposed of.
There's always many ways to do things, but... I think the easiest way would be to use First() since you are always just grabbing the first result in a list.
Another way to make it a little cleaner is to put your LINQ statements on multiple lines like I did for sets.
You can also use var, which some people like and others don't to have the compiler infer the type. I did this with sets below. I feel it cleans up the code a bit when you have large declarations with IEnumerable and generics.
public ActionResult showDiary(string datein)
{
LocalTestEntities1 dblists = new LocalTestEntities1();
DateTime date = Convert.ToDateTime(datein);
ExerciseDiary thediary = dblists.ExerciseDiaries.First(o => o.Date == date);
Weight weight = dblists.Weights.First(o.DiaryID == thediary.ID);
var sets = from x in dblists.Sets
where x.WeightId == weight.WeightID
select x;
return View(sets);
}
IMO this is easier to read than what you had in your answer above.
Be careful using First() because it will throw an exception if there are no records.
public ActionResult showDiary(string datein)
{
using( var dblists = new LocalTestEntities1())
{
var date = Convert.ToDateTime(datein);
var thediary = dblists.ExerciseDiaries.First(o => o.Date == date);
var weight = dblists.Weights.First(o => o.DiaryID ==thediary.ID);
var sets = dblists.Sets.Where(x => x.WeightId == weight.WeightID).AsEnumerable();
return View(sets);
}
}
Warning: If it's possible the data wont always be there. Use FirstOrDefault instead and check for null values.

Good way to sort object by date property in anonymous type?

I have the following code:
var resultArticles = from a in articleItems
select new
{
Title = a.Title,
ArticleDate = a[Constants.FieldNames.ArticleStartDate] != null ?
((DateTime)a[Constants.FieldNames.ArticleStartDate]).ToString(Constants.Date.Format): string.Empty,
ByLine = a[Constants.FieldNames.Byline],
FileRef = SPUtility.ConcatUrls(web.Url, a.Url)
};
var sortedArticles = resultArticles.OrderBy(a => a.ArticleDate).ToList();
rptArticles.DataSource = sortedArticles;
rptArticles.DataBind();
I guess there must be a better way to sort/order here because if I have the dates (dd/mm/yyy)
12.01.2011
11.02.2011
10.02.2011
13.01.2011
08.02.2011
it only sorts by the day and don't take the month into consideration so the result in sortedArticles is as follows:
08.01.2011
10.02.2011
11.02.2011
12.01.2011
13.01.2011
I obviously want to display the latest article first, i.e. 11.02.2011
Any suggestions?
Thanks in advance.
The problem is that in your Select, you're calling ToString on your date field. As a result ArticleDate is being projected as a string. This is why it's not sorting correctly.
Projecting the ArticleDate as a nullable Date is probably your best bet
var resultArticles = from a in articleItems
select new
{
Title = a.Title,
ArticleDate = a[Constants.FieldNames.ArticleStartDate] != null ?
((DateTime)a[Constants.FieldNames.ArticleStartDate]) : default(DateTime?),
ByLine = a[Constants.FieldNames.Byline],
FileRef = SPUtility.ConcatUrls(web.Url, a.Url)
};
Also, for something simple like this, you can use the more concise "dot notation"
var resultArticles = articleItems.Select(a => new {
Title = a.Title,
ArticleDate = a[Constants.FieldNames.ArticleStartDate] != null ?
((DateTime)a[Constants.FieldNames.ArticleStartDate]) : default(DateTime?),
ByLine = a[Constants.FieldNames.Byline],
FileRef = SPUtility.ConcatUrls(web.Url, a.Url)
};
At this point you can sort this collection by ArticleDate, which will be stored as a true Date, instead of a string
resultArticles.OrderBy(a => a.ArticleDate).ToList();
Use the following syntax
var q = from el in dataSource orderby el.SortField select new {
//your projection
};
The point here is to sort during the selection in one query.
Edit
By using this statement you sort by actual DateTime and project string representation.

How do I format date literals in dynamic linq?

I am using dynamic Linq to return data for user-input search criteria. My query is working fine except for the user selected dates. My current code is:
StringBuilder whereClause = new StringBuilder();
if (startDate.HasValue || endDate.HasValue)
{
DateTime searchStartDate = startDate.HasValue ? startDate.Value : DateTime.MinValue;
DateTime searchEndDate = endDate.HasValue ? endDate.Value : DateTime.MaxValue;
whereClause.AppendFormat("Date >= {0} && Date <= {1}",
searchStartDate.Date.ToUniversalTime(),
searchEndDate.Date.ToUniversalTime());
}
if (whereClause.Length > 0)
{
return (from p in this.repository.GetQueryable<Party>() select p)
.Where(whereClause.ToString())
.ToList();
}
The query falls over because the comparison is being done between a DateTime field and a Int32 field, meaning the query has interpreted my date literals as integers.
How should I be formatting the dates?
Use
.Where("Date >= #0 && Date <= #1",
searchStartDate.Date.ToUniversalTime(),
searchEndDate.Date.ToUniversalTime())
instead.
In reply to Val's comment:
OK, then you can do:
whereClause.AppendFormat("Date.ToString() >= \"{0}\" && Date.ToString() <= \"{1}\"",
searchStartDate.Date.ToUniversalTime(),
searchEndDate.Date.ToUniversalTime());
You have to convert the Date in the query to a string and then compare it a quoted string literal. Without the quotes the parser is inerpreting the numbers inserted into the where clause as integers - what should explain the error you originally got.
Why are you parsing strings in a LINQ expression? The entire point of LINQ is to avoid that.
var q = from p in this.repository.GetQueryable<Party>() select p;
if (startDate.HasValue || endDate.HasValue)
{
var searchStartDate = startDate.HasValue ? startDate.Value : DateTime.MinValue;
var searchEndDate = endDate.HasValue ? endDate.Value : DateTime.MaxValue;
return
q.Where (p=> p.Date >= searchStartDate.ToUniversalTime()
&& p.Date <= searchEndDate.ToUniversalTime()).ToList();
}
return q.ToList();
UPDATE:
In response to comments: I'm building that one at run-time. The question isn't run-time vs compile-time; it's "in strings" vs "in code". StringBuilder lets you append text; LINQ lets to chain lamdbas. It all works out the same --- except your code is type-safe and syntax checked using lambdas.
To demostrate this concept further, the following code compiles & runs fine, and allows to you to change the Where clause based on the values of oddsOnly and lowerLimit.
int[] nums = {1,2,3,4,5,6,7,8,9,10};
bool oddsOnly = true;
bool lowerLimit = 5;
var q = from i in nums select i;
if (oddsOnly)
q = q.Where( n=> n%2 == 1);
if (lowerLimit != 0)
q = q.Where( n=> n >= lowerLimit);
foreach(var i in q)
Console.WriteLine(i);
Depending on how you set those values, it will use zero, one or both of the where clauses.
The Dynamic LINQ string would need to look something like:
"Date >= DateTime(2015, 10, 21)"
This is mentioned in the documentation in the DynamicQuery project in the download mentioned at http://weblogs.asp.net/scottgu/dynamic-linq-part-1-using-the-linq-dynamic-query-library.
Note, there isn't a new before the DateTime constructor.
I tried this and it works. I'm using Telerik's RadGrid control for ASP.NET AJAX. The grid builds the filter string and I needed to add the filter to my query to get the filter to execute in the database using LINQ to Entities. The problem is that the generated filter needed to be altered a little for it to work with LINQ to Entities as opposed to LINQ to Objects. It was doing a DateTime.Parse() which isn't supported in LINQ to Entities.

Categories