Skip to content

Instantly share code, notes, and snippets.

@bhavanki
Created November 4, 2012 03:24
Show Gist options
  • Save bhavanki/4009989 to your computer and use it in GitHub Desktop.
Save bhavanki/4009989 to your computer and use it in GitHub Desktop.
Python script to report the current time in Ur, the world of Glitch.
#!/usr/bin/python
import calendar
from datetime import datetime
from optparse import OptionParser
import sys
# Define command line options: -D, -f, -F.
op = OptionParser()
op.add_option('-D', '--date', dest='date_to_use',
help='UTC date to use instead of now, as %Y%m%d%H%M')
op.add_option('-f', '--format', dest='output_format',
help='format string for output')
op.add_option('-F', '--format-help', dest='format_help',
action='store_true', default=False,
help='show help for formatting and exit')
options, args = op.parse_args(sys.argv[1:])
def print_format_help():
print '''A format string defines how the date and time should be presented.
Formats are specified with tokens similar to strftime(3).
%A weekday name
%B month name
%d day of month (01-73)
%h holiday, or empty string if not a holiday
%H hour of day (00-23)
%I 12-hour clock hour of day (01-12)
%j day of year (001-308)
%m month number (01-12)
%n newline character
%M minute (00-59)
%p 12-hour clock period (am, pm)
%r number of seconds since the Glitch epoch
%S second (00-59)
%w weekday number (0-7)
%Y year
%% literal percent sign
Recurse is treated as a twelfth month with one day. It has no weekday name.
The default format string is: %Y-%m-%d %H:%M:%S
'''
if options.format_help:
print_format_help()
sys.exit()
# When is "now" for the script? If -D used, parse it, otherwise use right now.
if options.date_to_use:
nowdt = datetime.strptime(options.date_to_use + " UTC", '%Y%m%d%H%M %Z')
else:
nowdt = datetime.utcnow()
now = calendar.timegm(nowdt.utctimetuple())
# How many real seconds have elapsed since the game epoch?
epoch = 1238562000 # 2009-04-04T05:00:00-0500
sec = now - epoch
epoch_seconds = sec * 6
# These are conversions from real seconds to game time units.
sec_per_year = 4435200
sec_per_day = 14400
sec_per_hour = 600
sec_per_minute = 10
year = sec // sec_per_year
sec = sec - (sec_per_year * year)
day = sec // sec_per_day
sec = sec - (sec_per_day * day)
hour = sec // sec_per_hour
sec = sec - (sec_per_hour * hour)
minute = sec // sec_per_minute
sec = sec - (sec_per_minute * minute)
# Convert sec to game seconds.
sec = sec * 6
# Convert the given zero-based day of the year to a tuple representing the
# zero-based month number and the day (one-based).
def convert_day(day):
# Lengths of each month, in days.
monthlens = (29, 3, 53, 17, 73, 19, 13, 37, 5, 47, 11, 1)
cd = 0
for i, v in enumerate(monthlens):
cd = cd + v;
if (cd > day):
month = i
day = day + 1 - (cd - monthlens[i])
return (month, day)
return (0, 0)
month_number, day_of_month = convert_day(day)
# Find the zero-based weekday number for the given year and zero-based day.
def find_day_of_week(year, day):
# There are 308 game days in a game year. However, Recurse doesn't count as
# a weekday.
weekdays_per_year = 307
# There are 8 game days in a game week.
days_per_week = 8
days_since_epoch = day + (weekdays_per_year * year)
return days_since_epoch % days_per_week
day_of_week = find_day_of_week(year, day)
# Convert the zero-based day of the week to its name.
def find_day_name(day_of_week):
days = ('Hairday', 'Moonday', 'Twoday', 'Weddingday', 'Theday', 'Fryday',
'Standday', 'Fabday')
return days[day_of_week]
day_name = find_day_name(day_of_week)
# Convert the zero-based month to its name.
def find_month_name(month_number):
months = ('Primuary', 'Spork', 'Bruise', 'Candy', 'Fever', 'Junuary',
'Septa', 'Remember', 'Doom', 'Widdershins', 'Eleventy',
'Recurse')
return months[month_number]
month_name = find_month_name(month_number)
# Recurse is weird because it's not a weekday.
if month_name == 'Recurse':
day_name = ''
day_of_week = 0
# In case we need it, figure out the 12-hour clock version of the time.
if hour > 12:
hour12 = hour - 12
period = 'pm'
else:
period = 'am'
if hour == 0:
hour12 = 12
else:
hour12 = hour
# Figure out the holiday for the zero-based month number and day (one-based).
def find_holiday(month_number, day_of_month):
holidays = {
'AlphCon' : (0, 5),
'Lemadan' : (1, 2),
'Pot Twoday' : (2, 3),
'Root 1' : (3, 2),
'Root 2' : (3, 3),
'Root 3' : (3, 4),
'Sprinkling' : (3, 11),
'Croppaday' : (5, 17),
'Belabor Day' : (6, 1),
'Zilloween' : (7, 37),
'Recurse Eve' : (10, 11)
}
for h, md in holidays.iteritems():
if month_number == md[0] and day_of_month == md[1]:
return h
return ''
holiday = find_holiday(month_number, day_of_month)
# Fill in the output format string, and dump it out.
if (options.output_format):
string_out = options.output_format
else:
string_out = '%Y-%m-%d %H:%M:%S'
string_out = string_out.replace('%%', '%')
string_out = string_out.replace('%A', day_name)
string_out = string_out.replace('%B', month_name)
string_out = string_out.replace('%d', '{0:#02}'.format(day_of_month))
string_out = string_out.replace('%h', holiday)
string_out = string_out.replace('%H', '{0:#02}'.format(hour))
string_out = string_out.replace('%I', '{0:#02}'.format(hour12))
string_out = string_out.replace('%j', '{0:#03}'.format(day + 1))
string_out = string_out.replace('%m', '{0:#02}'.format(month_number + 1))
string_out = string_out.replace('%M', '{0:#02}'.format(minute))
string_out = string_out.replace('%p', period)
string_out = string_out.replace('%r', str(epoch_seconds))
string_out = string_out.replace('%S', '{0:#02}'.format(sec))
string_out = string_out.replace('%w', '{0:#01}'.format(day_of_week))
string_out = string_out.replace('%Y', str(year))
string_out = string_out.replace('%n', '\n')
print string_out
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment