locked
Trying to do a date comparison in MVC razor form... is it possible? RRS feed

  • Question

  • User2130491911 posted

    So in MS Access you had a really awesome function called between.

    You could write something like  Year([SalesDate]) = Year(Date()) and Month([SalesDate]) <= Month(Date()) and Day([SalesDate]) <= Day (Date())

    I am trying to do a greater than or equal to comparison in MVC Razor so I can switch text colours.

    here is what I have so far and it not looking good... I found something that references date compare

    and I see there you can use just > or < but that omits the possible equal to option... is this an oversight by microsolf?

                @{ if ((DateTime.Compare(@item.MC_CONTESTANT_DOB,1/1/2002) == 1) && (DateTime.Compare(@item.MC_CONTESTANT_DOB, 1 / 1 / 2002) == 1))
                    {
    
                        @Html.DisplayFor(modelItem => item.MC_CONTESTANT_DOB)
    
                    }
                    else
                    {
    
                        @Html.DisplayFor(modelItem => item.MC_CONTESTANT_DOB)
    
    
                    }
    
    
    
                </td>

    When I try >= in razor mvc it states that <= can be used. 

    Any ideas?

    :

    Tuesday, September 29, 2020 11:34 PM

Answers

  • User1686398519 posted

    Hi AppDev01, 

    1. You need to convert string type to DateTime type.
      • You can use the Convert.ToDateTime method to convert the specified value to a DateTime value.
    2. The DateTime.Compare() method in C# is used for comparison of two DateTime instances.
      1. In other words, the second parameter should be of DateTime type.
      2. It returns an integer value.

        • DateTime.Compare(date1, date2)

          1. <0 :If date1 is earlier than date2
          2. =0: If date1 is the same as date2
          3. >0 :If date1 is later than date2

    Here is the solution:

    @model IEnumerable<DailyMVCDemo2.Models.Test>
    @* First *@
    <table class="table">
        <tr>
            @foreach (var item in Model)
            {
                <td>
                    @{ if ((DateTime.Compare(@item.MC_CONTESTANT_DOB, Convert.ToDateTime("1/1/2002")) >= 0))
                        {
    
                            <font color="green">
                                @Html.DisplayFor(modelItem => item.MC_CONTESTANT_DOB)
                            </font>
                        }
                        else
                        {
                            <font color="blue">
                                @Html.DisplayFor(modelItem => item.MC_CONTESTANT_DOB)
                            </font>
                        }
                    }
                </td>
            }
        </tr>
    </table>
    @* Second *@
    <table class="table">
        <tr>
            @foreach (var item in Model)
            {
                <td>
                    @{ if (@item.MC_CONTESTANT_DOB >= Convert.ToDateTime("1/1/2002"))
                        {
    
                            <font color="green">
                                @Html.DisplayFor(modelItem => item.MC_CONTESTANT_DOB)
                            </font>
                        }
                        else
                        {
                            <font color="blue">
                                @Html.DisplayFor(modelItem => item.MC_CONTESTANT_DOB)
                            </font>
                        }
                    }
                </td>
            }
        </tr>
    </table>

    Here is the result.

    Best Regards,

    YihuiSun

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, September 30, 2020 2:28 AM
  • User-474980206 posted

    assuming item.MC_CONTESTAND_DOB is a DateTime, and you use and instead of an or its:

    @if (item.MC_CONTESTANT_DOB >= DateTime.Parse("1/1/2002") && @item.MC_CONTESTANT_DOB <= DateTime.Parse("12/31/2007")) {
         /* some code here*/
    } 

    if item.MC_CONTESTAND_DOB is a string, then just like vb, you need to convert it to a DateTime.

    note: you don't need the razor @ prefix for item, because you are in a c# statement.

    in C# 9 (.net 5) you can write as:

    @if (item.MC_CONTESTANT_DOB is >= DateTime.Parse("1/1/2002") && <= DateTime.Parse("12/31/2007")) {
          /* some code here*/
    }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, October 1, 2020 2:53 AM

All replies

  • User2130491911 posted

    Also not sure how to deal with this... I assume this is telling me that it has no idea what to do if there is no value for date when I try this?

                @{ if ( @item.MC_CONTESTANT_DOB >"1/31/2001")

    I get this silly error

    Error	CS0019	Operator '>' cannot be applied to operands of type 'DateTime?' and 'string'	
    

    I get the same error when I  try using .value

              @{ if ( @item.MC_CONTESTANT_DOB.Value >"1/31/2001")

    Wednesday, September 30, 2020 1:46 AM
  • User2130491911 posted

    Well I got this to compile using this :

                @{ if ( @item.MC_CONTESTANT_DOB >= DateTime.Parse("1/1/2002") || @item.MC_CONTESTANT_DOB <= DateTime.Parse("12/31/2007"))

    Not sure if it is correct... but it compiles ...if its wrong the QA people will fix it LOL

    Wednesday, September 30, 2020 2:10 AM
  • User1686398519 posted

    Hi AppDev01, 

    1. You need to convert string type to DateTime type.
      • You can use the Convert.ToDateTime method to convert the specified value to a DateTime value.
    2. The DateTime.Compare() method in C# is used for comparison of two DateTime instances.
      1. In other words, the second parameter should be of DateTime type.
      2. It returns an integer value.

        • DateTime.Compare(date1, date2)

          1. <0 :If date1 is earlier than date2
          2. =0: If date1 is the same as date2
          3. >0 :If date1 is later than date2

    Here is the solution:

    @model IEnumerable<DailyMVCDemo2.Models.Test>
    @* First *@
    <table class="table">
        <tr>
            @foreach (var item in Model)
            {
                <td>
                    @{ if ((DateTime.Compare(@item.MC_CONTESTANT_DOB, Convert.ToDateTime("1/1/2002")) >= 0))
                        {
    
                            <font color="green">
                                @Html.DisplayFor(modelItem => item.MC_CONTESTANT_DOB)
                            </font>
                        }
                        else
                        {
                            <font color="blue">
                                @Html.DisplayFor(modelItem => item.MC_CONTESTANT_DOB)
                            </font>
                        }
                    }
                </td>
            }
        </tr>
    </table>
    @* Second *@
    <table class="table">
        <tr>
            @foreach (var item in Model)
            {
                <td>
                    @{ if (@item.MC_CONTESTANT_DOB >= Convert.ToDateTime("1/1/2002"))
                        {
    
                            <font color="green">
                                @Html.DisplayFor(modelItem => item.MC_CONTESTANT_DOB)
                            </font>
                        }
                        else
                        {
                            <font color="blue">
                                @Html.DisplayFor(modelItem => item.MC_CONTESTANT_DOB)
                            </font>
                        }
                    }
                </td>
            }
        </tr>
    </table>

    Here is the result.

    Best Regards,

    YihuiSun

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, September 30, 2020 2:28 AM
  • User2130491911 posted

    First many thanks for trying to help me. I CANNOT believe it take this much source code to do such a simple thing. MVC is silly.

    Let me ask in your sample above first and second... are they two different examples or if I want to compare my dates I have to re do the forloop for all my fields?

    Or are these to different examples

            <td>
    
                @{ if (@item.MC_CONTESTANT_DOB >= DateTime.Parse("1/1/2002") || @item.MC_CONTESTANT_DOB <= DateTime.Parse("12/31/2007"))
                    {
                                           
                        @Html.DisplayFor(modelItem => item.MC_CONTESTANT_DOB)
    
                    }
                    else if (@item.MC_CONTESTANT_DOB >= DateTime.Parse("1-1-2008") || @item.MC_CONTESTANT_DOB <= DateTime.Parse("12/31/2013"))
                    {
    
                        @Html.DisplayFor(modelItem => item.MC_CONTESTANT_DOB)
    
    
                    }
                    else
                    {
    
                        @Html.DisplayFor(modelItem => item.MC_CONTESTANT_DOB)
                    }
            </td>

    My jaw will hit the bloody floor if you tell me that to compare these 2 date ranges I have to write the for loop many many times as I have  many fields on this form.

    I may have to tell the client that colour change may not be possible,

    I have 4 dates I need to compare... so this means I need to have 8 for loops????

    Wednesday, September 30, 2020 2:57 AM
  • User303363814 posted

    Converting your first line of 'code' to words you get

    if Born after the beginning of 2002 or born before the end of 2007

    That would be everyone. (not sure why that makes MVC silly)

    It looks like you want a few branches

    if (!DOB.HasValue) {

    Do something for case where DOB is null

    } else if (DOB.Value.Year < 2008) {

       Do something with the ~teenagers

    } else if (DOB.Value.Year < 2014) {

       Do something with the ~primary schoolers

    } else {

       Do something with the ~preschoolers

    }

    You may want more branches or fewer branches. 

    (When you code tries to compare a Date with a String, what would you prefer the error message to be?  "Cannot apply '>' to DateTime? and string" seems self explanatory)

    ('I get the same error when " ... no you don't.  Read the message very carefully!)

    Wednesday, September 30, 2020 3:48 AM
  • User2130491911 posted

    Hi Paul I say its silly because I have a good bit of distain for mvc. I think its over complicated because simple things like this become impossible task that make no commonsense.  In webforms this would be a snap.

    As for the error it does not makes make much  since to me as it seems very cryptic.. but im not a hardcore programmer... I am not sure what you mean no you don't....but my issue is that I thought the comparison would be straight forward land simple like it is in Ma access or even like it is in sql. Which I think I make just do this in sql and set a flag for each line Item. That way I will not need to  right a complex bit of code. 

    But future reference my question is now this... I have to compare 1/1/2002 - 1/1/2007 and 1/1/2008 - 1/1/2013 lets say.

    So for all those days will I need to write all those forloops for just that field or for all the fields on the form?? I am sure its now pretty clear why I don;t want to write so much complex code to handle this.

    So I have only one field that I need to colour shift... the other I do not... so its not clear from the great example what I need to do in regards to that as I have like 15 fields to 30 fields on the index page but I only need one field to change colours.

    Thanks for any help that can be provided 

    Wednesday, September 30, 2020 4:11 AM
  • User303363814 posted

    You want to compare by the Year component.  Take the Year component and compare.  I really have no idea how it could be the slightest bit simpler.

    I have given you the answer.  Do you still have a problem?  If you do, then show you current code which has the problem, explain what you are trying to do and what is happening.

    If you have disdain for MVC, that does not make it silly!  What makes the message cryptic - details please!  Do you know what an operator is?  Do you know what data types are?  Without the basics you are always going to struggle - calling things names only hinders your education.

    Wednesday, September 30, 2020 4:28 AM
  • User-474980206 posted

    your issue is with C#, not mvc. C# does not support DateTime literals, so to define a DateTime value you use DateTime.Parse() or Convert. Also as C# is strongly typed you can not compare a DateTime to a string. You can compare DateTimes to each other:

     if (item.MC_CONTESTANT_DOB > DateTime.Parse("1/1/2002"))
                        

    you can even add and substract dates.

      var d1 = DateTime.Parse("12/1/2020");
      var d2 = DateTime.Parse("11/1/2020");
      var d3 = d1 - d2;

    Wednesday, September 30, 2020 3:23 PM
  • User2130491911 posted

    Hi Bruce that will not work and no I don't...there are at least 3 different people that have asked this very forum this question and they were not told they have issues with C#.

    Your sample would work but there is no way to account for dates that fall on the endpoints ... I am trying to do basically a sql between statement.

    So my criteria is to check dates that fall between 2 dates... DATE_X >= 1/1/2002 AND DATE_X <=1/1/2007

    and I am trying to do this in a mvc razor form which makes it extra tricky as I am needing to change the font colours...

    I thought it would be a simple bit of source to do that...but the person that was kind enough to post a example kind of lost me because it appears that you have to keep writing out the foreloop over and over for every date....Hence me calling MVC silly.

    That simple thing become very complex if I have to keep writing that foreloop over an over especially if I have a bunch of fields which I do.

    Based on the example.. if my date criteria changes I would have to change my source in 8 to 8 places.... that can't be the right way to do this.

    Here is the code behind for the mvc razor view...

    <p>
        @Html.ActionLink("ADD NEW CONTESTANT", "Create")
    </p>
    <table class="table">
        <tr>
            <th>
    
            </th>
            <th>
                @Html.DisplayNameFor(model => model.MC_CONTESTANT_ID)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.MC_CONTESTANT_FIRST_NAME)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.MC_CONTESTANT_LAST_NAME)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.MC_CONTESTANT_DOB)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.MC_CONTESTANT_APPLICATION_DATE)
            </th>
    
    
            <th></th>
        </tr>
    
        @foreach (var item in Model)
        {
        <tr>
            <th>
                @Html.ActionLink("DETAILS", "Details", new { id = item.MC_CONTESTANT_ID })
                <br />
                @Html.ActionLink("EDIT", "Edit", new { id = item.MC_CONTESTANT_ID })
            </th>
            <td>
                @Html.DisplayFor(modelItem => item.MC_CONTESTANT_ID)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.MC_CONTESTANT_FIRST_NAME)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.MC_CONTESTANT_LAST_NAME)
            </td>
    
            @*ADD COLOUR LOGIC*@ 
    
            <td>
    
                @{ if (@item.MC_CONTESTANT_DOB >= DateTime.Parse("1/1/2002") || @item.MC_CONTESTANT_DOB <= DateTime.Parse("12/31/2007"))
                    {
                                           
                        @Html.DisplayFor(modelItem => item.MC_CONTESTANT_DOB)
    
                    }
                    else if (@item.MC_CONTESTANT_DOB >= DateTime.Parse("1-1-2008") || @item.MC_CONTESTANT_DOB <= DateTime.Parse("12/31/2013"))
                    {
    
                        @Html.DisplayFor(modelItem => item.MC_CONTESTANT_DOB)
    
    
                    }
                    else
                    {
    
                        @Html.DisplayFor(modelItem => item.MC_CONTESTANT_DOB)
                    }
            </td>
                    
    
    
    
            <td>
                @Html.DisplayFor(modelItem => item.MC_CONTESTANT_APPLICATION_DATE)
            </td>
    
    
        </tr>
    
        }
    
    </table>

    In other programming languages like vb you can do neat stuff like this without much issues

     @{ if (@item.MC_CONTESTANT_DOB >= DateTime.Parse("1/1/2002") || @item.MC_CONTESTANT_DOB <= DateTime.Parse("12/31/2007"))
                    {

    Wednesday, September 30, 2020 9:56 PM
  • User303363814 posted

    You have been told three times what to do!  You keep posting the same faulty VB code, which in this case would be character for character identical to the C# code. If all you want to do is make the same mistake in C# that you make in your beloved VB, then what is stopping you?

    Is there a particular reason why you waste your time asking for help and then just keep posting the same nonsense logic?

    (Even if you did have to modify your code in eight places how long would that take in comparison with the amount of time you have spent posting?)

    Wednesday, September 30, 2020 11:06 PM
  • User-474980206 posted

    assuming item.MC_CONTESTAND_DOB is a DateTime, and you use and instead of an or its:

    @if (item.MC_CONTESTANT_DOB >= DateTime.Parse("1/1/2002") && @item.MC_CONTESTANT_DOB <= DateTime.Parse("12/31/2007")) {
         /* some code here*/
    } 

    if item.MC_CONTESTAND_DOB is a string, then just like vb, you need to convert it to a DateTime.

    note: you don't need the razor @ prefix for item, because you are in a c# statement.

    in C# 9 (.net 5) you can write as:

    @if (item.MC_CONTESTANT_DOB is >= DateTime.Parse("1/1/2002") && <= DateTime.Parse("12/31/2007")) {
          /* some code here*/
    }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, October 1, 2020 2:53 AM
  • User2130491911 posted

    ?? I am not even sure what you are on about. Someone asked me to post what I had. if I still had the issue.

    UPDATE: IT was you Paul that ask me to post what I had..and now you rail against me for doing what you asked...some people LOL

    From Paul"

    "  Do you still have a problem?  If you do, then show you current code which has the problem, explain what you are trying to do and what is happening."

    I don;' get the rudeness of some computer centric people when it comes to help forums. I guess it easier to be rude than it is to be nice...

    as for nonsense logic? well I am trying to understand the logic left in the example... I guess by your standards paul you are not allowed to ask a follow up question. when you don't understand the logic that is shared in an example. 

    Since you can't seem to read... I will write my question about the example again... do you have to keep writing foreloops over and over again just to make this colour thing work. IF this is the case. I may have to tell my client this can't be done. They would not know any better.

    So calm yourself down Paul. Geez!

    You can keep your lame insults to yourself... it just makes you look small and kinda of silly...

    Thursday, October 1, 2020 3:13 AM
  • User2130491911 posted

    Thank you!!! That is what I am trying to do... I thought it could be done... I just had some bits out of place...

    Gosh many many thanks! 

    That foreloop structure looked scary... there was no way my tiny brain could wrap itself around that. But I do appreciate  that example and the wonderful animation that went with it.

    Thursday, October 1, 2020 3:19 AM
  • User2130491911 posted

    This worked just like I needed it too... Many thanks!!

    Friday, October 2, 2020 10:10 PM