Day Numbers

For reference, this is relatively canonical code for calculating day numbers.

# turn a March 1600 based date into a day number
def daynum(y, m, d):
	# years consist of repeating 5-month periods of 153 days each
	m = divmod(m, 5)
	return 365 * y + y / 4 - y / 100 + y / 400 + \
		153 * m[0] + \
		31 * m[1] - m[1] / 2 + \
		d

# turn a number into a March 1600 based date
def numdate(dnum):
	# over-estimate year
	year = dnum / 365
	day = dnum - daynum(year, 0, 0)
	while day < 0:
		year = year - 1
		day = dnum - daynum(year, 0, 0)

	# over-estimate month
	month = day / 30
	day = dnum - daynum(year, month, 0)
	while day < 0:
		month = month - 1
		day = dnum - daynum(year, month, 0)

	return year, month, day

# turn a date into a March 1600 based date
def to1600(year, month, day):
	month = divmod(month - 3, 12)
	return year + month[0] - 1600, month[1], day - 1

# turn a March 1600 based date into a real date
def from1600(y, m, d):
	m = divmod(2 + m, 12)
	return 1600 + y + m[0], 1 + m[1], 1 + d

def from_date_str(date):
	return daynum(*to1600(*map(int, date.split("-"))))

def to_date_str(d):
	return "%04d-%02d-%02d" % from1600(*numdate(d))

Comments