Home > Net >  Parsed F# DateTime value not equal to the original DateTime value
Parsed F# DateTime value not equal to the original DateTime value

Time:11-16

Consider the following code that converts a DateTime to a string, tries to parse it using the TryParse method on DateTime, and returns an DateTime option indicating whether parsing the string was successful or not:

let dt = DateTime.Now

printfn "%A" dt

let parseDateTime (str: string) =
  match DateTime.TryParse str with
    | (true, v) -> Some v
    | _ -> None
    
let parsedDateTime =
  dt.ToString () |> parseDateTime

match parsedDateTime with
| Some v -> 
  printfn "%A" v
  assert (v = dt)
  
| _ -> ()

The assert statement fails, which I would not expect it to. printfn prints out the same string to the Console which further puzzles me.

If I change the assert statement above to assert (v.ToString() = dt.ToString()) the assert passes as I would have expected when comparing the two DateTime values.

Is there something that I'm missing here when it comes to DateTime equality? I've also tested this using int and Guid (swapping out DateTime.TryParse for Int32.TryParse and Guid.TryParse respectively) and the assert passes as I would expect it to when comparing values for equality.

CodePudding user response:

The resolution of a DateTime value is a single "tick", which represents one ten-millionth of a second. You also need to consider time zone differences. The default output format doesn't include this level of detail. If you want to "round trip" a DateTime, write it out with ToString("o")and then use DateTimeStyles.RoundtripKind when parsing:

open System
open System.Globalization

let parseDateTime (str: string) =
  match DateTime.TryParse(str, null, DateTimeStyles.RoundtripKind) with
    | (true, v) -> Some v
    | _ -> None

let parsedDateTime =
  dt.ToString ("o") |> parseDateTime   // e.g. "2021-11-15T15:36:07.6506924-05:00"
  • Related