calendar.sf 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. #!/usr/bin/ruby
  2. #
  3. ## https://rosettacode.org/wiki/Calendar#Sidef
  4. #
  5. require('DateTime')
  6. define months_per_col = 3
  7. define week_day_names = <Mo Tu We Th Fr Sa Su>
  8. define month_names = <Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec>
  9. func fmt_month (year, month) {
  10. var str = sprintf("%-20s\n", month_names[month-1])
  11. str += week_day_names.join(' ')+"\n"
  12. var dt = %s<DateTime>
  13. var date = dt.new(year => year, month => month)
  14. var week_day = date.day_of_week
  15. str += (week_day-1 `of` " " -> join(" "))
  16. var last_day = dt.last_day_of_month(year => year, month => month).day
  17. for day (date.day .. last_day) {
  18. date = dt.new(year => year, month => month, day => day)
  19. str += " " if (week_day ~~ (2..7))
  20. if (week_day == 8) {
  21. str += "\n"
  22. week_day = 1
  23. }
  24. str += sprintf("%2d", day)
  25. ++week_day
  26. }
  27. str += " " if (week_day < 8)
  28. str += (8-week_day `of` " " -> join(" "))
  29. str += "\n"
  30. }
  31. func fmt_year (year) {
  32. var month_strs = 12.of {|i| fmt_month(year, i+1).lines }
  33. var str = (' '*30 + year + "\n")
  34. for month (0..11 `by` months_per_col) {
  35. while (month_strs[month]) {
  36. for i (1..months_per_col) {
  37. month_strs[month + i - 1] || next
  38. str += month_strs[month + i - 1].shift
  39. str += ' '*3
  40. }
  41. str += "\n"
  42. }
  43. str += "\n"
  44. }
  45. return str
  46. }
  47. print fmt_year(ARGV ? Number(ARGV[0]) : 1969)