指定期間のなかから条件に一致する日付をリストアップ(F#)
12111 ワード
概要
F#プログラムの練習として「指定された期間のなかから条件を満たした日をリストアップするプログラム」を書きました。
まずは、条件例として「休日に指定される期間/日を除いた全ての月曜日」を与えるものを作成してみました。月曜授業日をリストアップするプログラムになります。
プログラム
DateTime
が何回もでてくるので、type DT = System.DateTime
によって短縮した別型名DT
を与えています(TimeSpan
についても同様です)。
Program.fs
open System
type DT = System.DateTime
type TS = System.TimeSpan
[<EntryPoint>]
let main argv =
// f:開始日 から t:終了日 までの DateTime シーケンス生成
let genDatesSeq (f:DT) (t:DT) =
{ 0 .. (t-f).Days }
|> Seq.map (fun d -> f + TS.FromDays(float d))
let y = 2019
let fromDT = DT(y,4,8) // 期間開始日
let toDT = DT(y,9,30) // 期間終了日
// 祝日や夏休みのセット
let exclusionSet =
set []
|> Set.union (Set.ofSeq( genDatesSeq (DT(y,4,27)) (DT(y,5,6) )))
|> Set.add (DT(y,7,15)) // 海の日
|> Set.union (Set.ofSeq( genDatesSeq (DT(y,8,8)) (DT(y,9,13) )))
|> Set.add (DT(y,8,12)) // 山の日(振替休日)
|> Set.add (DT(y,9,16)) // 敬老の日
|> Set.add (DT(y,9,23)) // 秋分の日
// リストアップ対象日を通過させるフィルタ ここでは休日外の月曜日を選択
let passFilter (p:DT) =
( p.DayOfWeek = DayOfWeek.Monday ) && not ( exclusionSet.Contains p )
// 出力フォーマット
let format = "yyyy/MM/dd (ddd)"
// 日付の出力
do genDatesSeq fromDT toDT
|> Seq.filter passFilter
|> Seq.map (fun p-> p.ToString(format))
|> Seq.iter (fun p -> printfn "%s" p)
Console.ReadKey() |> ignore
0
実行結果
2019/04/08 (月)
2019/04/15 (月)
2019/04/22 (月)
2019/05/13 (月)
2019/05/20 (月)
2019/05/27 (月)
2019/06/03 (月)
2019/06/10 (月)
2019/06/17 (月)
2019/06/24 (月)
2019/07/01 (月)
2019/07/08 (月)
2019/07/22 (月)
2019/07/29 (月)
2019/08/05 (月)
2019/09/30 (月)
発展
2019/04/08 (月)
2019/04/15 (月)
2019/04/22 (月)
2019/05/13 (月)
2019/05/20 (月)
2019/05/27 (月)
2019/06/03 (月)
2019/06/10 (月)
2019/06/17 (月)
2019/06/24 (月)
2019/07/01 (月)
2019/07/08 (月)
2019/07/22 (月)
2019/07/29 (月)
2019/08/05 (月)
2019/09/30 (月)
期間中の第一金曜日をリストアップするためにはフィルタを次のように書き換えます(ここではexclusionSet
で設定した休みを考慮していません)。
let passFilter (p:DT) =
( p.DayOfWeek = DayOfWeek.Friday ) && ( p.Day <= 7 )
プレミアムフライデー(月の最終金曜日)をリストアップするためには、フィルタを次のように書き換えます。
let next m = if m = 12 then 1 else m+1
let passFilter (p:DT) =
( p.DayOfWeek = DayOfWeek.Friday )
&& ( (DT(p.Year, next p.Month ,1)-TS.FromDays(8.)).Day < p.Day )
F#では、等値比較に==
ではなく=
を使用する関係で、慣れるまではlet next m = if m = 12 then 1 else m+1
なんかは非常に読み取りずらいです。括弧をつけると多少は読み取りやすくなるのかな・・・
let next m = ( if ( m = 12) then 1 else ( m + 1 ) )
Author And Source
この問題について(指定期間のなかから条件に一致する日付をリストアップ(F#)), 我々は、より多くの情報をここで見つけました https://qiita.com/code0327/items/e1032cbed7c63601df90著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .