12 people like it.

Print a calendar

How to print a formatted calendar to the console using F#

  1: 
  2: 
  3: 
  4: 
  5: 
  6: 
  7: 
  8: 
  9: 
 10: 
 11: 
 12: 
 13: 
 14: 
 15: 
 16: 
 17: 
 18: 
 19: 
 20: 
 21: 
 22: 
 23: 
 24: 
 25: 
 26: 
 27: 
 28: 
 29: 
 30: 
 31: 
 32: 
 33: 
 34: 
 35: 
 36: 
 37: 
 38: 
 39: 
 40: 
 41: 
 42: 
 43: 
 44: 
 45: 
 46: 
 47: 
 48: 
 49: 
 50: 
 51: 
 52: 
 53: 
 54: 
 55: 
 56: 
 57: 
 58: 
 59: 
 60: 
 61: 
 62: 
 63: 
 64: 
 65: 
 66: 
 67: 
 68: 
 69: 
 70: 
 71: 
 72: 
 73: 
 74: 
 75: 
 76: 
 77: 
 78: 
 79: 
 80: 
 81: 
 82: 
 83: 
 84: 
 85: 
 86: 
 87: 
 88: 
 89: 
 90: 
 91: 
 92: 
 93: 
 94: 
 95: 
 96: 
 97: 
 98: 
 99: 
100: 
101: 
102: 
103: 
104: 
105: 
106: 
107: 
108: 
109: 
110: 
111: 
112: 
113: 
114: 
115: 
116: 
117: 
118: 
119: 
120: 
121: 
122: 
123: 
124: 
125: 
126: 
127: 
128: 
129: 
130: 
131: 
132: 
133: 
134: 
135: 
136: 
137: 
138: 
139: 
140: 
141: 
142: 
143: 
144: 
145: 
146: 
147: 
148: 
149: 
let printCalendar (month, year) =
    let dayOfWeek (month: int32, year: int32) =
        let t =  [|0; 3; 2; 5; 0; 3; 5; 1; 4; 6; 2; 4|]
        let y = if month < 3 then year - 1 else year
        let m = month
        let d = 1
        (y + y / 4 - y / 100 + y / 400 + t.[m - 1] + d) % 7
        //0 = Sunday, 1 = Monday, ...

    let lastDayOfMonth (month: int32, year: int32) =
        match month with
        | 2 -> if (0 = year % 4 && (0 = year % 400 || 0 <> year % 100)) then 29 else 28
        | 4 | 6 | 9 | 11 -> 30
        | _ -> 31

    let min (x: int32, y: int32) = if x < y then x else y

    let ld = lastDayOfMonth(month, year)
    let dw = 7 - dayOfWeek(month, year)
    let xss = [[1..dw];
               [dw + 1..dw + 7];
               [dw + 8..dw + 14]; 
               [dw + 15..dw + 21]; 
               [dw + 22..min(ld, dw + 28)]; 
               [min(ld + 1, dw + 29)..ld]]

    let list2string xs lineFormatMask = 
        let ys = (xs |> List.map (fun x -> sprintf "%2d " x))
        let mkString = ys |> List.fold (fun s x -> s + x) ""
        sprintf lineFormatMask mkString

    let printRange xs = (printfn "%s") << (list2string xs)
    let printLeft xs = printRange xs "%-21s"
    let printRight xs = printRange xs "%21s"
    
    //pt-BR
    //let months = [|"Jan"; "Fev"; "Mar"; "Abr"; "Mai"; "Jun"; "Jul"; "Ago"; "Set"; "Out"; "Nov"; "Dez"|]
    //en-US
    let months = [|"Jan"; "Feb"; "Mar"; "Apr"; "May"; "Jun"; "Jul"; "Aug"; "Sep"; "Oct"; "Nov"; "Dec"|]
    //(21 - 3) / 2 + 3 = 12 => 3 == String.length months.[month - 1]
    printfn "%12s" months.[month - 1]
    //pt-BR
    //printfn " D  S  T  Q  Q  S  S"
    //en-US
    printfn " S  M  T  W  T  F  S"
    printRight (xss |> List.head)
    (xss |> List.tail) |> List.iter (fun xs -> printLeft xs)

[1..12] |> List.iter (fun i -> printCalendar(i, 2015)) 

(*

         Jan
 S  M  T  W  T  F  S
             1  2  3
 4  5  6  7  8  9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

         Feb
 S  M  T  W  T  F  S
 1  2  3  4  5  6  7
 8  9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28


         Mar
 S  M  T  W  T  F  S
 1  2  3  4  5  6  7
 8  9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

         Apr
 S  M  T  W  T  F  S
          1  2  3  4
 5  6  7  8  9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30

         May
 S  M  T  W  T  F  S
                1  2
 3  4  5  6  7  8  9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
         Jun
 S  M  T  W  T  F  S
    1  2  3  4  5  6
 7  8  9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

         Jul
 S  M  T  W  T  F  S
          1  2  3  4
 5  6  7  8  9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

         Aug
 S  M  T  W  T  F  S
                   1
 2  3  4  5  6  7  8
 9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
         Sep
 S  M  T  W  T  F  S
       1  2  3  4  5
 6  7  8  9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30

         Oct
 S  M  T  W  T  F  S
             1  2  3
 4  5  6  7  8  9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

         Nov
 S  M  T  W  T  F  S
 1  2  3  4  5  6  7
 8  9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30

         Dec
 S  M  T  W  T  F  S
       1  2  3  4  5
 6  7  8  9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31

*)
val printCalendar : month:int32 * year:int32 -> unit

Full name: Script.printCalendar
val month : int32
val year : int32
val dayOfWeek : (int32 * int32 -> int32)
Multiple items
val int32 : value:'T -> int32 (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int32

--------------------
type int32 = System.Int32

Full name: Microsoft.FSharp.Core.int32
val t : int []
val y : int32
val m : int32
val d : int
val lastDayOfMonth : (int32 * int32 -> int)
val min : (int32 * int32 -> int32)
val x : int32
val ld : int
val dw : int
val xss : int list list
val list2string : (int list -> Printf.StringFormat<(string -> 'a)> -> 'a)
val xs : int list
val lineFormatMask : Printf.StringFormat<(string -> 'a)>
val ys : string list
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val map : mapping:('T -> 'U) -> list:'T list -> 'U list

Full name: Microsoft.FSharp.Collections.List.map
val x : int
val sprintf : format:Printf.StringFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
val mkString : string
val fold : folder:('State -> 'T -> 'State) -> state:'State -> list:'T list -> 'State

Full name: Microsoft.FSharp.Collections.List.fold
val s : string
val x : string
val printRange : (int list -> Printf.StringFormat<(string -> string)> -> unit)
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val printLeft : (int list -> unit)
val printRight : (int list -> unit)
val months : string []
val head : list:'T list -> 'T

Full name: Microsoft.FSharp.Collections.List.head
val tail : list:'T list -> 'T list

Full name: Microsoft.FSharp.Collections.List.tail
val iter : action:('T -> unit) -> list:'T list -> unit

Full name: Microsoft.FSharp.Collections.List.iter
val i : int
Raw view Test code New version

More information

Link:http://fssnip.net/pA
Posted:9 years ago
Author:Fabio Galuppo
Tags: list , calendar