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.
Related
So I wanted to Blackout all dates from 2000 from present in the WPF Calendar that aren't in a Datetime list.
My thought was to blackout all dates individually from 2000 to now and then remove each date from the blackout Date Collection.
This Code adds dates fine but it doesn't work to remove the dates from the collection.
var DateList = FI.Select(x => x.LastWriteTime.Date).Distinct().ToList();
for (var day = new DateTime(2000,1,1); day.Date <= DateTime.Now.Date; day = day.AddDays(1))
{
Calendar.BlackoutDates.Add(new CalendarDateRange(day));
}
foreach (DateTime k in Datelist)
{
Calendar.BlackoutDates.Remove(new CalendarDateRange(k));
}
I compared the date range from the blackout date collection and the newly created one from the current iteration of the list but it says they aren't equivalent.
Comparison seen here
Thank you for the assistance.
CalendarDateRange class lets you specify a start date and end date for the range, you don't have to add a CalendarDateRange for every day.
https://msdn.microsoft.com/en-us/library/system.windows.controls.calendardaterange(v=vs.110).aspx
Also, there are a lot of code examples on the Calendar.BlackoutDates documentation :
https://msdn.microsoft.com/en-us/library/system.windows.controls.calendar.blackoutdates(v=vs.110).aspx
var DateList = FI.Select(x => x.LastWriteTime.Date).Distinct().ToList();
//Add all dates between DateTime.MinValue and the day before your DateList min value.
Calendar.BlackoutDates.Add(new CalendarDateRange(DateTime.MinValue, DateList.Min().AddDays(-1)));
** EDIT **
After reading your comment, it seems that I've misunderstood your issue. You're trying to remove a new instance of CalendarDateRange, which is different than the CalendarDateRange instance that was added to the collection, even though they have the same start and end values.
Replace your foreach block with this one to fix your issue :
foreach (var k in DateList)
{
while (Calendar.BlackoutDates.Any(bd => bd.Start.Date == k.Date))
{
Calendar.BlackoutDates.Remove(Calendar.BlackoutDates.FirstOrDefault(bd => bd.Start.Date == k.Date));
}
}
I can really use some help wrapping my head around a problem I'm having querying data according to a SQL Date field.
I am storing the Date in UTC format using the following code:
objFitCalendarDto.Day = objFitCalendarDto.Day.ToUniversalTime();
That line assigns the date to the model that is inserted into the db through Entity Framework.
Now, my query is supposed to retrieve a row based on a date. So, I should be able to get the row for today, tomorrow, yesterday, and so on.
To do this, I'm using the method to search between two dates, a start date and an end date as follows:
DateTime dayBegin = DateTime.Today.Date.AddDays(dayOffset);
DateTime dayEnd = DateTime.Today.Date.AddDays(dayOffset + 1);
The purpose of dayOffset is to specify which day. If Offset is 0, then I am searching for Today. If dayOffset is 1, then I am searching for rows with tomorrow's date.
Now, since I stored the data originally in UTC, I am assuming that I must search for it in UTC as well. So before executing my query, I convert the dates to UTC like so:
dayBegin = TimeZoneInfo.ConvertTimeToUtc(dayBegin);
dayEnd = TimeZoneInfo.ConvertTimeToUtc(dayEnd);
Then I execute my query like so:
var query = (from f in Db.FitCalendars
where f.FitProgramId == programId &&
f.DayAsDate >= dayBegin && f.DayAsDate < dayEnd
select f);
problem is, it doesn't work. I have a row with the date, "2016-01-26" when I look at it in SQL Manager. However, it only returns from a query on yesterday's date. Today is 2016-01-26, by the way. Clearly I'm not getting this UTC concept. Can anyone see what I'm doing wrong here? I was assuming that if I stored everything as UTC and then before querying I converted my dates for the query to UTC, that everything should work.
UPDATE
Let's try like this:
As soon as you are storing only date part (SQL 'date' type), you
need to compare also only dates.
Instead of
DateTime dayBegin = DateTime.Today.Date.AddDays(dayOffset);
dayBegin = TimeZoneInfo.ConvertTimeToUtc(dayBegin);
let's just do
DateTime dayBegin = DateTime.UtcNow.Date.AddDays(dayOffset);
dayBegin in that case will be date with time anyway (time is 12:00:00 AM). It means, we need to truncate it with DbFunctions. We need equality check here.
var query = (from f in Db.FitCalendars
where f.FitProgramId == programId &&
f.DayAsDate == DbFunctions.TruncateTime(dayBegin)
select f);
END OF UPDATE
I believe that problem is that you comparing dates with times. In your case you need to compare only dates, as far as I understand. As a solution - use DbFunctions TruncateTime function. It can be used within linq queries - like in your code.
https://msdn.microsoft.com/en-us/library/system.data.entity.dbfunctions.truncatetime(v=vs.113).aspx
So, complete solution would be
var query = (from f in Db.FitCalendars
where f.FitProgramId == programId &&
DbFunctions.TruncateTime(f.DayAsDate) >= DbFunctions.TruncateTime(dayBegin) && DbFunctions.TruncateTime(f.DayAsDate) < DbFunctions.TruncateTime(dayEnd)
select f);
var carID = taxBDO.Customer_Id;
Customer customerInDb = (from p in TaxEnitites.Customers
where p.Customer_Id == carID
select p).FirstOrDefault();
if (customerInDb.Date_Taxed < 365)
{
}
I have retrieve a date from my db that I have set up, however I can not figure out to use an if statement t use this date from my database to check if this date is more that a year ago,
any help would be appreciated
Thanks
You can add negative one years to today and compare:
customerInDb.Date_Taxed < DateTime.Now.AddYears(-1)
Yes. You can compute a timespan between now and then and fetch the total number of days.
DateTime.Now.Subtract(customerInDb.Date_Taxed).TotalDays > 365
Crowcoder has already given a solution which will work in most cases.
But, dateTime.Now has the Time component as well! So, if
customerInDb.Date_Taxed = {15/11/2014 00:05:30}
DateTime.Now = {15/11/2015 00:22:30}
Then
Date_Taxed < DateTime.Now.AddYears(-1) => true
Though it's on the same date last year. And this calculation will depend on the current time, so you'll get different results at different time of the day.
If you want this, then fine. Else, you can compare just the Date part as
var isMoreThanYearAgo = customerInDb.Date_Taxed.Date < DateTime.Now.AddYears(-1).Date;
Also, check customerInDb for null before you call this, as you are getting this as a result of FirstOrDefault().
After searching through stack overflow, I cant seem to find a solution. I've put together a chart (Chart.js) and I need to grab days of the current week bind that to the chart and match any days date to one stored in my db thus brining back all data based on that date.
So if anyone could give me any pointers on fetching List from the current week, that would be awesome.
I hope this is clear enough please feel free to ask more questions. Sorry no code struggling to get started. For me DateTime is an absolute nightmare to work with.
Regards,
You can use the DayOfWeek property of DateTime:
new DateTime(2014,11,16).DayOfWeek
So... to deal with a list of dates, first, let's make a list of dates:
var startDate = DateTime.Today;
var endDate = startDate.AddDays(7);
//the number of days in our range of dates
var numDays = (int)((endDate - startDate).TotalDays);
List<DateTime> myDates = Enumerable
//creates an IEnumerable of ints from 0 to numDays
.Range(0, numDays)
//now for each of those numbers (0..numDays),
//select startDate plus x number of days
.Select(x => startDate.AddDays(x))
//and make a list
.ToList();
and get the days of the week:
List<string> myDaysOfWeek = myDates.Select(d => d.DayOfWeek.ToString()).ToList();
if you want the week to start on (say) the previous Monday, you could alter startDate as follows:
startDate = startDate
.AddDays(-(((startDate.DayOfWeek - DayOfWeek.Monday) + 7) % 7));
This works because we can treat the enumeration values of enum DayOfWeek as numbers, so we can subtract Monday(value 1) from Sunday(value 0), which gives -1... then we do a bit of a jiggle to wrap this value to 6 using modulo maths. If you subtract the resulting value (measured in days) from the start date, you end up on the previous Monday.
If you want to know the days of the current week, you need to:
Get the current day
Convert it to an integer
Subtract that many days from the current date. That gives you the date for Sunday.
Create a list, starting with Sunday.
So:
var now = DateTime.Now;
var currentDay = now.DayOfWeek;
int days = (int)currentDay;
DateTime sunday = now.AddDays(-days);
var daysThisWeek = Enumerable.Range(0, 7)
.Select(d => sunday.AddDays(d))
.ToList();
Hello I am currently trying to array.find all the dates before the current date. I have tried both using the datetime.now as well as creating a seperate variable for current date in my struct but i keep getting "Cannot implicitly convert type 'Assignment_3.Program.Hire' to 'System.DateTime". I'm sure the solution is quite simple but as a novice it does escape from me. If you need any more of the code I will be happy to provide
struct Hire
{
public int CustomerNo;
public int DVDNo;
public DateTime HireDate;
public int NoNights;
public DateTime CurrentDate = DateTime.Now;
}
DateTime result = Array.Find(hiredetails, Hire => Hire.HireDate <= Hire.CurrentDate);
Array.Find<T> returns the element matching the criteria. In you case since it is an array of Hire type, it will return element of type Hire, which you cannot assign to DateTime. You can do:
List<DateTime> allDates = hiredetails.Where(hire=> hire.HireDate <= hire.CurrentDate)
.Select(r=> r.HireDate)
.ToList();
You can also return IEnumerable<DateTime> and exclude ToList() from the above statement.
Not really sure if you need this but instead of keeping the current date inside the object you can have that in your local variable and pass that in your query like:
DateTime currentDate = DateTime.Now;
List<DateTime> allDates = hiredetails.Where(hire=> hire.HireDate <= currentDate)
.Select(r=> r.HireDate)
.ToList();
Do not store current date in a structure, use local variable instead, solution would look like:
var currentDate = DateTime.Now;
var result = hiredetails.Select(h => h.HireDate).Where(d => d <= currentDate);