D.Iple
D.Iple

Reputation: 95

Find a date from a specific list of date

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

Upvotes: 1

Views: 1980

Answers (3)

fubo
fubo

Reputation: 46005

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();

Upvotes: 0

fstam
fstam

Reputation: 699

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.

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1504172

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

Upvotes: 2

Related Questions