Search code examples
c#blazorwebassembly

Compare different date format


I am doing a search by date. Even though below dates are Same, they wouldn't return true, as the time from Json is different from the time returned by datetimepicker.

I want to compare only by date, not the time. Below should be true:

Date selected by user -> 2022-11-26T00:00:00 Date I get from Json -> 26.11.2022 12:42:09

How can I compare this and return true. Thank you.

 private DateTime dateSelectedByUser = DateTime.Today;
 public async Task DateOnChange(ChangeEventArgs args)
{
    var value = args.Value.ToString();
    dateSelectedByUser = value == string.Empty ? DateTime.Today : DateTime.Parse(value);
    result = items.Where(item=> item.date == dateSelectedByUser ).ToArray();
 }

Thank you.


Solution

  • How can I compare this and return true

    How to handle DateTime is a really nasty interview question. It will catch most programmers out.

    Let's look at your code.

    Your input type is set to date i.e. date without time, but your datatype is set to DateTime. Though you get no errors or warnings, in reality you've crossed a type error boundary. If you store date1 now and date2 now, date1 == date2 will always return false. Unless you stored them at precisely the same point in time (which is impossible on the same machine), they will be different.

    There's some modern C# (and database) coding rules to follow:

    1. If you're only interested in date use the DateOnly type.
    2. Otherwise use DateTimeOffset.

    Though I'm sure I'll get comments from those who disagree, all the other TimeDate stuff is to maintain backwards compatibility with old C# which was too simplistic with date time!

    Here's a simple Demo page based on the code you provided. There's no indication where a json date fits in so that's DateFromSomewhereElse.

    @page "/"
    
    <PageTitle>Index</PageTitle>
    
    <h1>Hello, world!</h1>
    
    <input class="form-control mb-3" type="date" @bind-value=this.MyDate />
    
    <div class="@this.AlertCss"> Dates Are the Same: @this.DatesAreSame </div >
    
    @code {
        private DateOnly MyDate = DateOnly.FromDateTime(DateTime.Now);
    
        private DateTime DateFromSomewhereElse = DateTime.Now;
    
        private bool DatesAreSame => MyDate == DateOnly.FromDateTime(DateFromSomewhereElse);
    
        private string AlertCss => this.DatesAreSame
            ? "alert alert-success"
            : "alert alert-danger";
    
    }
    

    For those pre C#10:

    Create extension methods for DateTime and DateTimeOffset to get the midnight values:

    public static class DateTimeExtensions
    {
        public static DateTime AsDateOnly(this DateTime value) 
            => new DateTime(value.Year, value.Month, value.Day);
    
        public static DateTime AsDateOnly(this DateTimeOffset value)
            => new DateTime(value.Year, value.Month, value.Day);
    }
    

    And then the test page:

    @page "/"
    
    <PageTitle>Index</PageTitle>
    
    <h1>Hello, world!</h1>
    
    <input class="form-control mb-3" type="date" @bind-value=this.MyDate />
    
    <div class="@this.AlertCss"> Dates Are the Same: @this.DatesAreSame </div >
    
    @code {
        private DateTimeOffset MyDate = DateTimeOffset.Now;
    
        private DateTimeOffset DateFromSomewhereElse = DateTimeOffset.Now;
    
        private bool DatesAreSame => MyDate.AsDateOnly() == DateFromSomewhereElse.AsDateOnly();
    
        private string AlertCss => this.DatesAreSame
            ? "alert alert-success"
            : "alert alert-danger";
    }