David Brower
David Brower

Reputation: 3048

Pattern Matching with DateTime.MinValue?

I am writing an F# service that uses Quartz.Net to poll another service (that has been written in C#):

[<PersistJobDataAfterExecution>]
[<DisallowConcurrentExecution>]
type PollingJob() = 
    interface IJob with 
        member x.Execute(context: IJobExecutionContext) = 
           let uri = "http://localhost:8089/"
           let storedDate = context.JobDetail.JobDataMap.GetDateTime("LastPoll") 
           //this works...
           let effectiveFrom = (if storedDate = DateTime.MinValue then System.Nullable() else System.Nullable(storedDate))

           let result = someFunction uri effectiveFrom

           context.JobDetail.JobDataMap.Put("LastPoll", DateTime.UtcNow) |> ignore

The context is passed to the Execute function by Quartz for every poll and contains a dictionary. The first time the service runs the value for LastPoll will be the default DateTime value i.e. 01/01/0001 00:00:00. Then the next time the scheduler runs LastPoll will contain the time of the last poll.

I can create a Nullable<DateTime> using the if..then..else construct (above) but when I try to use pattern matching I get a compiler error with a squiggly under DateTime.MinValue:

This field is not a literal and cannot be used in a pattern

The code I am trying to use is as follows:

//this doesn't...
let effectiveFrom = 
    match storedDate with 
    | DateTime.MinValue -> System.Nullable()
    | _ -> System.Nullable(storedDate)

Upvotes: 3

Views: 176

Answers (1)

Pash101
Pash101

Reputation: 641

You are using pattern matching slightly incorrectly.

The below should work:

    let effectiveFrom = 
        match storedDate with 
        | d when d = DateTime.MinValue -> System.Nullable()
        | _                            -> System.Nullable(storedDate)

When you want to test equality as part of a pattern match, you need to use a when clause (see here - https://fsharpforfunandprofit.com/posts/match-expression/)

Upvotes: 3

Related Questions