I have two Columns in Below format in my application (c#)
Month Name Amount
Jan15 ==2000
Feb15 ==457
Mar15 =200
April15 =4666
May15 = 357
Jan16 = 332
feb16 =323
Mar16 =233
these columns are dynamic (any number of columns can cm in Same format)
I need to get the sum of all the amounts where month is after Mar15.
How to achieve that.
Pseudo code
If MonthName >Mar15
amount = sum (amount)
If your DateFormat is always be going to like Jan-14 Feb-14 Mar-14 Apr-14 May-14 Jun-14 then you can try to use the ParseExact to convert it to the DateTime and then apply the SUM on it to get the result you want.
var result = dataList.Where(x => DateTime.ParseExact(x.monthName, "MMM-yy", CultureInfo.InvariantCulture) > DateTime.ParseExact("Mar-15", "MMM-yy", CultureInfo.InvariantCulture))
.Sum(x => x.Amount);
In above case it will give the sum of all amounts which has date greater than Mar-15.
UPDATE
To add the Group BY you can simply add as,
.GroupBy(x=>x.Id).Select(x=> new { Person = x.Key,TotalAmount = x.Sum(x=>x.Amount)})
Related
Im trying to get "greater"/later date from database with query below
Controller
string str = "2019-10-27T20:44:55.323";
DateTime Date = Convert.ToDateTime(str);
var List = (from a in dbcontext.system_notification where a.notification_date > Date select a).ToList();
Output
I still got result from date "2019-10-27T20:44:55.323".
Im expecting to get only Later date from date given since im using ">" operator.
Thank You!!
The DateTime struct represents dates as a 64 bit number that measures the number of “ticks” since a particular start date. Ten million ticks equals one second.
See: https://blogs.msdn.microsoft.com/ericlippert/2010/04/08/precision-and-accuracy-of-datetime/
Now, compare this to the data types of MS SQL:
datetime accuracy: 0.00333 s [ DEFAULT IN EF ]
datetime2 accuracy: 100 ns
So, most likely, the value in your database is actually, sightly, bigger or rounded.
You can test this by checking the delta:
foreach (var dt in List)
{
var delta = Date - dt;
// check the value.
}
You can try this as below:
You should avoid using reserved words or keywords as a variable name.
string str = "2019-10-27T20:44:55.323";
DateTime dt = Convert.ToDateTime(str);
var lst = dbcontext.system_notification.where(x => x.notification_date > dt).ToList();
I am a beginner in c # and I can not find the solution for my problem.
I am creating a personal project that allows me to send reminders, I have a date list and I need to do tasks between two specific dates in real life.
I found how to get the next date from today's date but I can't find how to get the previous one
Here is my sample code
void calc_x_date()
{
List<string> x_dates = new List<string>();
x_dates.Add("10/01/2017");
x_dates.Add("14/02/2017");
x_dates.Add("14/03/2017");
x_dates.Add("11/04/2017");
x_dates.Add("09/05/2017");
x_dates.Add("13/06/2017");
x_dates.Add("04/07/2017");
x_dates.Add("08/08/2017");
x_dates.Add("12/09/2017");
x_dates.Add("10/10/2017");
x_dates.Add("14/11/2017");
x_dates.Add("12/12/2017");
var allDates = x_dates.Select(DateTime.Parse).OrderBy(d => d).ToList();
var todayDate = DateTime.Today;
var nextDate = todayDate >= allDates.Last()
? allDates.Last()
: todayDate <= allDates.First()
? allDates.First()
: allDates.First(d => d >= todayDate);
string NextDate = nextDate.ToString(); // the closest next date from today
//string PreviousDate = // the closest previous date from today
}
Could someone explain me how to find my previous date please ?
Thanks in advance
I'd suggest using List<T>.BinarySearch: that will find the index of the date. If the index is 0 or more, then the exact date was found. If it's negative, then taking ~index will get you the index where the date would have been inserted.
Once you've got that information, it's easy to find the value at the previous index or the next index - but you should consider all the cases of:
Today is before all dates
Today is after all dates
Today is a date between the first and last date in the list, but isn't in the list
Today is equal to the first date
Today is equal to the last date
Today is equal to a date in the list which isn't the first or last date
As asides:
I would strongly encourage you to get in the habit of following .NET naming conventions as early as possible
I'd encourage you not to use strings to represent dates unless you really need to
If you're doing a lot of date/time work, you may find my Noda Time library easier to use correctly than DateTime
Here is a Linq approach
List<string> x_dates = new List<string>();
x_dates.Add("10/01/2017");
x_dates.Add("14/02/2017");
x_dates.Add("14/03/2017");
x_dates.Add("11/04/2017");
x_dates.Add("09/05/2017");
x_dates.Add("13/06/2017");
x_dates.Add("04/07/2017");
x_dates.Add("08/08/2017");
x_dates.Add("12/09/2017");
x_dates.Add("10/10/2017");
x_dates.Add("14/11/2017");
x_dates.Add("12/12/2017");
DateTime today = DateTime.Today;
IEnumerable<DateTime> dt_dates = x_dates.Select(DateTime.Parse);
DateTime prev = dt_dates.Where(x => x < today)
.OrderByDescending(x => x)
.First();
DateTime next = dt_dates.Where(x => x > today)
.OrderBy(x => x)
.First();
alternative solution
DateTime prev = dt_dates.Where(x => x < today).Max();
DateTime next = dt_dates.Where(x => x > today).Min();
Storing dates in string format works. It is however incredibly difficult to do date comparisons. You have to first cast it to numbers, handle the exceptions, etc.
C# has a DateTime object. You can store dates in this and ignore the time. DateTime objects can be compared using the < and > operators.
If you create a class with a start date and an end date, store these objects in a list(of tasks), would that solve your problem? You can also add a text of the task in a string to said object.
I have some dates which are currently stored as a list of strings.
For example:
List<string> dates = new List<string>();
dates.Add("1/10/14");
dates.Add("2/9/14");
dates.Add("1/15/14");
dates.Add("2/3/14");
dates.Add("2/15/14");
(The date is in mm/dd/yy format)
I will take a user's input (also in mm/dd/yy format), but as a string.
Now, I want to find the date in the array that is the next closest after the user input date.
For example, if the user enters "1/13/14", the output should be "1/15/14".
If the user enters "2/5/14", then the next closest date is "2/9/14".
But if the user enter a date that is later than the last date (say "3/1/14", it will STILL return the last date in the array which is "2/15/14")
I know at some point you have to convert to type DateTime, but I couldn't figure out the logic to find such date.
List<string> dates = new List<string>();
dates.Add("1/10/14");
dates.Add("2/9/14");
dates.Add("1/15/14");
dates.Add("2/3/14");
dates.Add("2/15/14");
var allDates = dates.Select(DateTime.Parse).OrderBy(d=>d).ToList();
var inputDate = DateTime.Parse("1/13/14");
var closestDate = inputDate >= allDates.Last()
? allDates.Last()
: inputDate <= allDates.First()
? allDates.First()
: allDates.First(d => d >= inputDate);
For now I'm just parsing strings, but you should handle it separately. This is simple plain LINQ, you can go fancy and do binary search as well.
Here is a solution that uses a Binary Search.
You need to have a list of DateTimes, no question about it. No point in keeping them as strings, parse them on the way into the list if you have to. You can use LINQ to convert all the elements in the list, but that's the only way you'll be able to compare dates with eachother.
Check out the page for BinarySearch to understand why I am using the bitwise operator on the return value.
//build list of random dates
Random r = new Random();
var dates = new List<DateTime>();
for (int i = 0; i < 10; i++)
{
dates.Add(new DateTime(2014, r.Next(1,13), r.Next(1,28)));
}
//sort list (if you don't do this, you'll most likely get the wrong answer)
dates.Sort();
//get input
string input = "1/13/14";
DateTime inputDate = DateTime.Parse(input);
//find nearest
var result = dates.BinarySearch(inputDate);
DateTime nearest;
//get match or next in list.
if(result >= 0)
nearest = dates[result];
else if (~result == dates.Count )
nearest =dates.Last();
else
nearest = dates[~result];
If you need to find the true closest, use this in place of the last if block.
//get match, or true nearest date in list
if(result >= 0) //date was found! Use that index.
nearest = dates[result];
else if (~result == 0) //date not found, smaller than any item in the list. use first index.
nearest = dates.First();
else if(~result == dates.Count) //date was not found, and is greater than all items. Use last index.
nearest = dates.Last();
else //date not found, somewhere in the middle of the list. find the nearest date
{
var daysAfter = dates[~result].Subtract(inputDate); //date after input
var daysBefore = inputDate.Subtract(dates[~result - 1]); //date before input
if(daysAfter < daysBefore)
nearest = dates[~result];
else
nearest = dates[~result - 1];
}
DateTime searchDate = new DateTime(2014,03,01);
var orderedDates = dates
.Select(d => DateTime.ParseExact(d, "M/d/yy", CultureInfo.InvariantCulture))
.OrderBy(d => d).ToList();
var result = orderedDates.FirstOrDefault(d => d > searchDate);
if (result == default(DateTime))
result = orderedDates.Last();
Something like this?
List<string> dates = YourListOfStringsHere() ; // list of strings in MM/dd/yyyy form.
DateTime desiredDate = new DateTime(2014,2,27) ;
DateTime foundDate = dates
.Select( x => DateTime.ParseExact(x,"MM/dd/yyyy",CultureInfo.CurrentCulture))
.Where( x => x >= desiredDate.Date )
.Min()
;
Why you'd be storing date/time values as a string is beyond me. When you load them, why not convert them? That way, they're easier to manipulate, you know you've got clean data. Everything becomes much simpler.
I want to get the count of rows by date for each day this month, like this:
Date count
1/03/2013 18
2/03/2013 41
28/03/2013 12
29/03/2013 14
How to write the query for that?
So, I assume you have some table with a datetime field in which you have the date "1/03/2013" 18 times, meaning you have 18 rows in that table with that date.
Then you should get the count of each day of a month in a year by something like this:
var year = 2013;
var month = 3;
var q = from t in DBContext.TableName
where t.DateField.Year == year && t.DateField.Month == month
group t by t.DateField.Date
into g
select new
{
dateField = g.Key,
countField = g.Count()
};
See also the LINQ to SQL Samples
Any ideas?
I can't come up with any.
I have a list of dates I'm loading in from a csv file and they are saved as all integers, or rather a string of integers (i.e. Jan 1, 2009 = 1012009)
Any ideas on how to turn 1012009 into 1/01/2009?
Thanks!
Since the date is stored as a string, you may want to use ParseExact:
DateTime date = DateTime.ParseExact("28012009", "dMMyyyy", null);
ParseExact will throw an exception if the format doesn't match. It has other overloads, where you can specify more than a single possible format, if that is required. Note that here provider is null, which uses the current culture.
Depending on style you may wish to use TryParseExact.
int date = 1012009;
var month = date / 1000000;
var day = (date / 10000) % 100;
var year = date % 10000;
var formatted = new DateTime(year, month, day).ToString();
This assumes month-day-year; if the numbers are day-month-year, I’m sure you’ll be able to swap the month and day variables to accommodate that.
If you want to customise the date format, you can do so as described in:
Standard Date and Time Format Strings
Custom Date and Time Format Strings
Let 10102009 be dateInt.
string dateString = dateInt.ToString();
int l = dateString.Length;
dateString = dateString.Insert(l-3,"/");
dateString = dateString.Insert(l-6,"/");
You should now have 1/01/2009 in dateString.. You can also try the ParseExact function..