Home > Software engineering >  Iterating through a calendar in F#
Iterating through a calendar in F#

Time:10-28

for (int ctr = 1; ctr <= gregorianCalendar.GetMonthsInYear(gregorianCalendar.GetYear(startOfYear)); ctr  ) {
    Console.Write(" {0,2}", ctr);
    Console.WriteLine("{0,12}{1,15:MMMM}",
                      gregorianCalendar.GetDaysInMonth(gregorianCalendar.GetYear(startOfMonth), gregorianCalendar.GetMonth(startOfMonth)),
                      startOfMonth);
    startOfMonth = gregorianCalendar.AddMonths(startOfMonth, 1);
}

I was trying to write the same code in F# but I don't know what {0, 2} and {0,12}{1,15:MMMM} is, what they do and what F# equivalent of these are. The main target here is F# equivalent of C# code above. But, I would be glad if you explain formats above shortly.

Notes:

  • gregorianCalendar is an instance of System.Globalization.GregorianCalendar.
  • startOfYear is an instance of DateTime which has value of DateTime(2023, 1, 1).
  • startOfMonth is an instance of DateTime which has value same as value of startOfYear at initialization. It's used to loop through months.

CodePudding user response:

{0, 2} and {0,12}{1,15:MM} are codesnippetimg

CodePudding user response:

If you want a literal translation into F#, it looks very similar:

open System
open System.Globalization

let gregorianCalendar = GregorianCalendar()
let startOfYear = DateTime(2023, 1, 1)
let mutable startOfMonth = startOfYear

for ctr = 1 to gregorianCalendar.GetMonthsInYear(gregorianCalendar.GetYear(startOfYear)) do
    Console.Write(" {0,2}", ctr)
    Console.WriteLine("{0,12}{1,15:MMMM}",
                      gregorianCalendar.GetDaysInMonth(gregorianCalendar.GetYear(startOfMonth), gregorianCalendar.GetMonth(startOfMonth)),
                      startOfMonth)
    startOfMonth <- gregorianCalendar.AddMonths(startOfMonth, 1)

However, many F# developers prefer to avoid mutable variables and side-effects. So the following is more idiomatic:

    // compute month starts with no side-effects
let nMonths = gregorianCalendar.GetMonthsInYear(gregorianCalendar.GetYear(startOfYear))
let startsOfMonths =
    (startOfYear, [| 1 .. nMonths-1 |])
        ||> Array.scan (fun startOfMonth _ ->
            gregorianCalendar.AddMonths(startOfMonth, 1))

    // write results to console
for ctr = 1 to nMonths do
    let startOfMonth = startsOfMonths[ctr-1]
    Console.Write(" {0,2}", ctr)
    Console.WriteLine("{0,12}{1,15:MMMM}",
                        gregorianCalendar.GetDaysInMonth(gregorianCalendar.GetYear(startOfMonth), gregorianCalendar.GetMonth(startOfMonth)),
                        startOfMonth)
  • Related