is there a more functionally idiomatic way of generating valid dates in f#?
One way to work around invalid dates is not to generate them in the first place: find the number of days between the boundary dates, generate a random integer from this range and then add that number of days to the start date:

let generateDate (min : Date) max =
    let totalDays = int (max - min).TotalDays
    let generatedDays = rnd.Next(0, totalDays)
    let generatedDate = min.AddDays(float generatedDays)
    generatedDate

let generateDateByYear minYear maxYear =
    generateDate (Date(minYear, 1, 1)) (Date(maxYear, 1, 1))

let generateBirthDate() = generateDateByYear 1904 1954

let sampleDobs = [for i in 1 .. 1000 -&gt; generateBirthDate()]