shithub: mc

ref: 8a7f47695be3621942b0b951913814185617fbf0
dir: /lib/date/fmt.myr/

View raw version
use std

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

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

	const fmt	: (f : byte[:], d : instant	-> byte[:])
	const bfmt	: (buf : byte[:], f : byte[:], d : instant	-> byte[:])
;;


const fmt = {f, d
	var buf

	buf = std.slalloc(2048)
	-> bfmt(buf, f, d)
}

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

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)
}