WTF C# DateTime comparison...



  • I found this in a loop to check whether a list of data rows in a table match a specified DateTime object.

    DateTable someTable;
    DateTime startDate; 

    ...

    foreach (DataRow row in someTable) 

    {

    //WTF?

    if (((DateTime)row["StartDate"]).ToShortDateString() + ((DateTime)row["StartDate"]).ToShortTimeString() != startDate.ToShortDateString() + startDate.ToShortTimeString())

    }



  • That is pretty :-)



  • I don't see the problem if this is an internatiolized application.  You may never know what format your date time values may take, and depending on how they are saved you may still not know.  The only option in that case is to use the shown functions to convert it to the local default for validation and the datetime object does not have a single call to convert both date and time to thier proper short forms.

    Of course while this may not be a WTF, the reason it is done here might be.  In a properly internationalized application you store the values in your local format but convert them for display to the user.  If the user enters a value you convert it back to your localized version before saving it to the database.  This way you always know what your database values look like.  This code assumes that the database values may be in any format and need to be localized.



  • [quote user="KattMan"]

    I don't see the problem if this is an internatiolized application.  You may never know what format your date time values may take, and depending on how they are saved you may still not know.  The only option in that case is to use the shown functions to convert it to the local default for validation and the datetime object does not have a single call to convert both date and time to thier proper short forms.

    Of course while this may not be a WTF, the reason it is done here might be.  In a properly internationalized application you store the values in your local format but convert them for display to the user.  If the user enters a value you convert it back to your localized version before saving it to the database.  This way you always know what your database values look like.  This code assumes that the database values may be in any format and need to be localized.

    [/quote]

     On a cursory inspection, this code:

    if (((DateTime)row["StartDate"]).ToShortDateString() + ((DateTime)row["StartDate"]).ToShortTimeString() != startDate.ToShortDateString() + startDate.ToShortTimeString())

    could be replaced with:

    if (((DateTime)row["StartDate"]) != startDate)

     



  • [quote user="KattMan"]

    I don't see the problem if this is an internatiolized application.  You may never know what format your date time values may take, and depending on how they are saved you may still not know.  The only option in that case is to use the shown functions to convert it to the local default for validation and the datetime object does not have a single call to convert both date and time to thier proper short forms.

    Of course while this may not be a WTF, the reason it is done here might be.  In a properly internationalized application you store the values in your local format but convert them for display to the user.  If the user enters a value you convert it back to your localized version before saving it to the database.  This way you always know what your database values look like.  This code assumes that the database values may be in any format and need to be localized.

    [/quote]

     It's hard to detect sarcasm on the internets, but I really hope you're joking. It's clear from the code that the DateTimes are saved as locale-independent DateTimes in the database. The code is not assuming the data may be in any format, as it will not work in any other format.

     Also, the nature of the comparison is locale-independent. Since no culture is specified in the ToXXXString calls, they will use the current thread culture and be entirely equivalent for any culture, with the unlikely exception that the string concatenation may cause some dates to be non-uniquely created in some cultures.

    On a scale of 1 to 10, this is a WTF.


     



  • Actually I was not joking and it also is not clear.

    Note the specific cast to a DateTime type, this leads me to beleive that the data from the row is in some other format, perhaps string, but there is not enough info to know what that format is.  This is the basis of my presumption that this could very well be an internationalized application.

    Granted after this cast, it should be in a localized form as the cast will use the local settings for the cast, so the other posters responce is correct, just compare the casted value to the generated datetime value so I did miss that simplification.

    Other than that my initial idea stands, convert the entered data first, and save it to the database in your localized form, preferably in a DateTime field so no cast will be necessary.



  • @KattMan said:

    Actually I was not joking and it also is not clear.

    Note the specific cast to a DateTime type, this leads me to beleive that the data from the row is in some other format, perhaps string, but there is not enough info to know what that format is.  This is the basis of my presumption that this could very well be an internationalized application.

    Granted after this cast, it should be in a localized form as the cast will use the local settings for the cast, so the other posters responce is correct, just compare the casted value to the generated datetime value so I did miss that simplification.

    Other than that my initial idea stands, convert the entered data first, and save it to the database in your localized form, preferably in a DateTime field so no cast will be necessary.

    A DataTable has DataRows, and DataRows basically just hold generic [i]objects[/i] in the long run. You have to cast or convert the object to what you expect it to be.



  • [quote user="KattMan"]

    Actually I was not joking and it also is not clear.

    Note the specific cast to a DateTime type, this leads me to beleive that the data from the row is in some other format, perhaps string, but there is not enough info to know what that format is.  This is the basis of my presumption that this could very well be an internationalized application.

    Granted after this cast, it should be in a localized form as the cast will use the local settings for the cast, so the other posters responce is correct, just compare the casted value to the generated datetime value so I did miss that simplification.

    Other than that my initial idea stands, convert the entered data first, and save it to the database in your localized form, preferably in a DateTime field so no cast will be necessary.

    [/quote]

    KattMan, 

    The database column is SQL DateTime.  ADO.NET will convert this to C#'s DateTime automatically for you.

    You cannot cast a string to DateTime in C#.  You would need to use DateTime.Parse()

    However, because the code specifies the column name via string and not as part of a specific type, you don't know what kind of object it is until Run-Time (aka Late Binding.)

    The cast to DateTime is not the WTF per se.  ToShortDateString/ToShortTimeString is the WTF.

    (Although, we will note that DateTime.CompareTo() takes an Object argument...so why cast?)

     



  • [quote user="webzter"]

     On a cursory inspection, this code:

    if (((DateTime)row["StartDate"]).ToShortDateString() + ((DateTime)row["StartDate"]).ToShortTimeString() != startDate.ToShortDateString() + startDate.ToShortTimeString())

    could be replaced with:

    if (((DateTime)row["StartDate"]) != startDate)

    [/quote]

    Even better: 

    if (startDate.CompareTo(row["StartDate"]) != 0)

    //Noting of course, that CompareTo will throw exceptions if the row isn't actually a DateTime.  However, so would the cast :)



  • The databaseColumn is SQL DateTime.

    OK, but with the given code I can't assume that.

    You cannot cast a string to DateTime in C#.

    True, but you can cast a number, so once again since it is a cast I have to assume it might be something else until I can prove otherwise.  Like you said, it will be converted automatically if it were already a DateTime.

    And I already admitted the alternative was better and it is replacing the ToShorts.  Do not fault me for not having knowledge you held back and assumed we would all know.  I have learned that things are not always what they should be (numerical indexes always coming back as strings, the "it will always be a number" needing prefaced with 0's so it is really a string, etc.) so I can not assume given the above code that the Table data is a SQL DateTime field unless it is proven to be such.



  • [quote user="KattMan"]

    The databaseColumn is SQL DateTime.

    OK, but with the given code I can't assume that.

    You cannot cast a string to DateTime in C#.

    True, but you can cast a number, so once again since it is a cast I have to assume it might be something else until I can prove otherwise.  Like you said, it will be converted automatically if it were already a DateTime.

    And I already admitted the alternative was better and it is replacing the ToShorts.  Do not fault me for not having knowledge you held back and assumed we would all know.  I have learned that things are not always what they should be (numerical indexes always coming back as strings, the "it will always be a number" needing prefaced with 0's so it is really a string, etc.) so I can not assume given the above code that the Table data is a SQL DateTime field unless it is proven to be such.

    [/quote]

    Even without knowing that the column is a datetime, the conversion to datetime happens fine with the cast. Basically, they're casting a column as a datetime twice, once to get the short date and once to get the short time. They then concate that into a string and then compare the string against the datetime field short date and time (which was also concatenated).

    Obviously, anything beyond the original cast would be silly.



  • [quote user="Benanov"]

    Even better: 

    if (startDate.CompareTo(row["StartDate"]) != 0)

    //Noting of course, that CompareTo will throw exceptions if the row isn't actually a DateTime.  However, so would the cast :)

    [/quote]

    Stylistically, it just depends on what you feel is better. I, personally, like the equality operator but others would think the cast is messy.

    I suppose startDate.Equals((DateTime)row["StartDate"]) would work as well.



  • [quote user="KattMan"]

    The databaseColumn is SQL DateTime.

    OK, but with the given code I can't assume that.

    You cannot cast a string to DateTime in C#.

    True, but you can cast a number, so once again since it is a cast I have to assume it might be something else until I can prove otherwise.  Like you said, it will be converted automatically if it were already a DateTime.

    And I already admitted the alternative was better and it is replacing the ToShorts.  Do not fault me for not having knowledge you held back and assumed we would all know.  I have learned that things are not always what they should be (numerical indexes always coming back as strings, the "it will always be a number" needing prefaced with 0's so it is really a string, etc.) so I can not assume given the above code that the Table data is a SQL DateTime field unless it is proven to be such.

    [/quote]

    If the date field in sql isn't stored in a sql datetime type, that's pretty much a WTF right there, regardless of the fact that the casts assumed it was or would result in error.

    There was no reason to assume that, with the given code, that it might NOT be datetime type.  Regardless, either way the given code was a WTF.



  • [quote user="webzter"]

    Stylistically, it just depends on what you feel is better. I, personally, like the equality operator but others would think the cast is messy.

    I suppose startDate.Equals((DateTime)row["StartDate"]) would work as well.

    [/quote]

    Since we're going for equality, might as well minimize the number of comparisons.  .Equals() FTW.
     


Log in to reply