shithub: mc

ref: e4505dbcbb4d305d789d41909a1f606144eb5652
dir: /lib/date/fmt.myr/

View raw version
use std

use "types.use"
use "names.use"

pkg date = 
	const fmt	: (d : instant, time : bool	-> byte[:])
	const bfmt	: (buf : byte[:], d : instant, time : bool	-> std.size)
	const ftime	: (f : byte[:], d : instant	-> byte[:])
	const bftime	: (buf : byte[:], f : byte[:], d : instant	-> std.size)
;;

const Datetimefmt	= "%Y-%m-%d %H:%M:%S %z"
const Timefmt	= "%h:%m:%s %z"
const Datefmt	= "%Y-%m-%d %z"

const fmt = {d, time
	if time
		-> ftime(Datetimefmt, d)
	else
		-> ftime(Datefmt, d)
	;;
}

const bfmt = {buf, d, time
	if time
		-> bftime(buf, Datetimefmt, d)
	else
		-> bftime(buf, Datefmt, d)
	;;
}

const ftime = {f, d
	var buf
	var sz

	buf = std.slalloc(2048)
	sz = bftime(buf, f, d)
	-> buf[:sz]
}

const bftime = {buf, f, d
	var c
	var o
	
	o = 0
	while f.len != 0
		(c, f) = std.striter(f)
		if c == '%'
			(c, f) = std.striter(f)
			match c
			| 'a':	o += std.bfmt(buf[o:], "%s", _names.abbrevday[d.day])
			| 'A':	o += std.bfmt(buf[o:], "%s", _names.fullday[d.day])
			| 'b':	o += std.bfmt(buf[o:], "%s", _names.abbrevmon[d.mon])
			| 'B':	o += std.bfmt(buf[o:], "%s", _names.fullmon[d.mon])
			| 'c':	o += bftime(buf[o:], "%Y-%m-%d", d)
			| 'C':	o += std.bfmt(buf[o:], "%02i", d.year % 100)
			| 'd':	o += std.bfmt(buf[o:], "%02i", d.day)
			| 'D':	o += std.bfmt(buf[o:], "%m/%d/%y (wtf america)", d.mon, d.day, d.year)
			| 'e':	o += std.bfmt(buf[o:], "%2i", d.day)
			| 'F':	o += std.bfmt(buf[o:], "%y-%m-%d", d.year, d.mon, d.day)
			/*
			| 'G':	o += std.bfmt(buf[o:], ...?
			| 'g':
			*/
			| 'h':	o += std.bfmt(buf[o:], "%s", _names.abbrevmon[d.mon])
			| 'H':	o += std.bfmt(buf[o:], "%02i", d.h)
			| 'I':	o += std.bfmt(buf[o:], "%02i", d.h % 12)
			| 'j':	o += std.bfmt(buf[o:], "year day... unimplemented.")
			| 'k':	o += std.bfmt(buf[o:], "%i", d.h)
			| 'l':	o += std.bfmt(buf[o:], "%i", d.h % 12)
			| 'm':	o += std.bfmt(buf[o:], "%i", d.mon)
			| 'M':	o += std.bfmt(buf[o:], "%i", d.m)
			| 'n':	o += std.bfmt(buf[o:], "\n")
			| 'O':	o += std.bfmt(buf[o:], "unsupported %O")
			| 'p':	o += std.bfmt(buf[o:], "%s", ["AM", "PM"][d.h/12])
			| 'P':	o += std.bfmt(buf[o:], "%s", ["am", "pm"][d.h/12])
			| 'r':	o += bftime(buf[o:], "%H:%M:%S %P", d) 
			| 'R':	o += bftime(buf[o:], "%H:%M %P", d)
			| 's':	o += std.bfmt(buf[o:], "%l", d.actual)
			| 'S':	o += std.bfmt(buf[o:], "%i", d.s)
			| 't':	o += std.bfmt(buf[o:], "\t")
			| 'u':	o += std.bfmt(buf[o:], "%i", d.wday)
			| 'U':	o += std.bfmt(buf[o:], "week number... unimplemented.")
			| 'x':	o += bftime(buf[o:], Datefmt, d)
			| 'X':	o += bftime(buf[o:], Timefmt, d)
			| 'y':	o += std.bfmt(buf[o:], "%i", d.year % 100)
			| 'Y':	o += std.bfmt(buf[o:], "%i", d.year)
			| 'z':	o += timezone(buf[o:], d.tzoff)
			| 'Z':	o += std.bfmt(buf[o:], "%s", d.tzname)
			| '%':	o += std.bfmt(buf[o:], "%%")
			;;
		else
			o += std.bfmt(buf[o:], "%c", c)
		;;
	;;
	-> o
}

const timezone = {buf, off
	var h, m
	var sep

	sep = "+"
	if off < 0
		off = -off
		sep = "-"
	;;
	off /= 1_000_000
	h = off / 3600
	m = off % 3600
	-> std.bfmt(buf, "%s%02l%02l", sep, h, m)
}