f#:用于计算日期之间差异的程序

时间:2015-10-28 17:42:51

标签: f#

我编写了计算两个日期之间差异的程序的一部分,但我无法添加闰年的控制(((年%4 = 0)&&((年%100< > 0)||(年%400 = 0))))。例如:如果我的输入是01 01 2001和01 01 2005,我输入输出1460,但2004年是闰年,所以我的输出应该是1461。 这是我的计划:

let rec month_length (month : int) (year : int) : int =
    match month with
    | 0 -> failwith "Wrong month"
    | _ when month > 12 -> failwith "Wrong month'"
    | 1 -> 31
    | 2 -> month_length (month - 1) year + 28
    | 4 | 6 | 9 | 11 -> 30 + month_length (month - 1) year 
    | n -> 31 + month_length (n - 1) year 

let data_to_day (day : int) (month : int) (year : int) : int =
    if month = 1 then day
    else day + month_length (month - 1) year

let data_difference (day1 : int) (month1 : int) (year1 : int) (day2 : int) (month2 : int) (year2 : int) : int =
    let dy = year1 - year2
    data_to_day day1 month1 year1 - data_to_day day2 month2 year2 + (dy * 365)

有没有人有任何想法? 提前谢谢!

1 个答案:

答案 0 :(得分:2)

正如上面评论中 Functional_S 所建议的,代码不能补偿闰年。

假设不使用以下任何库是修改后的代码。它不是优雅的解决方案,但它是处理闰年/月的一种方式。

let feb_month_days year =
    if ((year % 4 = 0) && ((year % 100 <> 0) || (year % 400 = 0))) then 29
    else 28

let year_days year =
    if ((year % 4 = 0) && ((year % 100 <> 0) || (year % 400 = 0))) then 366
    else 365

let rec month_length (month : int) (year : int) : int =
    match month with
    | 0 -> failwith "Wrong month"
    | _ when month > 12 -> failwith "Wrong month'"
    | 1 -> 31
    | 2 -> month_length (month - 1) year + (feb_month_days year)
    | 4 | 6 | 9 | 11 -> 30 + month_length (month - 1) year 
    | n -> 31 + month_length (n - 1) year 

let data_to_day (day : int) (month : int) (year : int) : int =
    if month = 1 then
        day
    else
        day + month_length (month - 1) year

let data_difference (day1 : int) (month1 : int) (year1 : int) (day2 : int) (month2 : int) (year2 : int) : int =
    let dy = year1 - year2
    let range_year_1 = year1 - 1
    let range_year_2 = year2 + 1
    let year2_days = (year_days year2) - (data_to_day day2 month2 year2)
    let year1_days = data_to_day day1 month1 year1
    let between_year_days = seq {for y in range_year_2..range_year_1 do yield year_days y} |> Seq.sum
    year2_days + year1_days + between_year_days

printfn "%A" (data_difference 01 01 2005 01 01 2001) // gives back 1461

它与上面的代码几乎相同,并添加了'feb_month_days'和'year_days'函数