awkrs 0.4.14

Awk implementation in Rust with broad CLI compatibility, parallel records, and experimental Cranelift JIT
Documentation
# Date math via Zeller's congruence + a tiny calendar generator.
# Input lines:
#   "DOW <yyyy> <mm> <dd>"       day-of-week:  prints "yyyy-mm-dd is <weekday>"
#   "CAL <yyyy> <mm>"            print a month calendar (Sun–Sat columns)
#   "DIFF <y1> <m1> <d1> AND <y2> <m2> <d2>"
#                                 print "<a> to <b> = <n> days"
# Algorithm: days-from-epoch using a Gregorian formula good for AD 1+.

function is_leap(y) { return ((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0) }

function days_in_month(y, m,   d) {
  if (m == 2) return is_leap(y) ? 29 : 28
  if (m == 4 || m == 6 || m == 9 || m == 11) return 30
  return 31
}

function day_of_week(y, m, d,   K, J, h) {
  # Zeller for Gregorian. Output: 0=Sat ... 6=Fri. We rotate to 0=Sun.
  if (m < 3) { m += 12; y-- }
  K = y % 100
  J = int(y / 100)
  h = (d + int(13 * (m + 1) / 5) + K + int(K / 4) + int(J / 4) + 5 * J) % 7
  return (h + 6) % 7   # rotate: 0=Sun, 6=Sat
}

function fixed_from_gregorian(y, m, d,   y0) {
  # Days from 0000-12-31. Used only for differences, so the exact epoch
  # doesn't matter — only deltas are reported.
  y0 = y - 1
  return 365 * y0 + int(y0 / 4) - int(y0 / 100) + int(y0 / 400) \
       + int((367 * m - 362) / 12) \
       + (m <= 2 ? 0 : (is_leap(y) ? -1 : -2)) \
       + d
}

function wd_name(d,   names) {
  split("Sun Mon Tue Wed Thu Fri Sat", names, " ")
  return names[d + 1]
}

function month_name(m,   names) {
  split("January February March April May June July August September October November December", names, " ")
  return names[m]
}

function cal(y, m,   start, n, c, w, row) {
  printf "    %s %d\n", month_name(m), y
  print "Su Mo Tu We Th Fr Sa"
  start = day_of_week(y, m, 1)
  n = days_in_month(y, m)
  row = ""
  for (c = 0; c < start; c++) row = row "   "
  w = start
  for (c = 1; c <= n; c++) {
    row = row sprintf("%2d ", c)
    w++
    if (w % 7 == 0) { sub(/ $/, "", row); print row; row = "" }
  }
  if (row != "") { sub(/ $/, "", row); print row }
}

$1 == "DOW" {
  y = $2 + 0; m = $3 + 0; d = $4 + 0
  printf "%04d-%02d-%02d is %s\n", y, m, d, wd_name(day_of_week(y, m, d))
  next
}
$1 == "CAL" {
  cal($2 + 0, $3 + 0)
  next
}
$1 == "DIFF" {
  y1 = $2 + 0; m1 = $3 + 0; d1 = $4 + 0
  y2 = $6 + 0; m2 = $7 + 0; d2 = $8 + 0
  diff = fixed_from_gregorian(y2, m2, d2) - fixed_from_gregorian(y1, m1, d1)
  if (diff < 0) diff = -diff
  printf "%04d-%02d-%02d to %04d-%02d-%02d = %d days\n", y1, m1, d1, y2, m2, d2, diff
  next
}