Skip to content

Instantly share code, notes, and snippets.

@Kelketek
Created September 12, 2022 01:31
Show Gist options
  • Save Kelketek/dbfeb4568b5806fe0eabe5129211f09b to your computer and use it in GitHub Desktop.
Save Kelketek/dbfeb4568b5806fe0eabe5129211f09b to your computer and use it in GitHub Desktop.
Example game datetime functions
from typing import Literal, Dict
# Our lowest resolution is in hours.
HOUR_LENGTH = 1
DAY_LENGTH = 24
SEASON_LENGTH = DAY_LENGTH * 30
YEAR_LENGTH = SEASON_LENGTH * 4
TimeKey = Literal['year', 'season', 'day', 'hour']
# Could use a DataClass or a TypedDict, but that would be distracting to the point I'm trying to show
# which is how the math works and how this approach handles edge cases.
DateDict = Dict[TimeKey, int]
def time_delta(*, hours: int = 0, days: int = 0, seasons: int = 0, years: int = 0) -> int:
"""
Return a value that represents the number of hours for however many hours, days, seasons, and years
forward we wish to travel.
"""
return sum([
hours,
days * DAY_LENGTH,
seasons * SEASON_LENGTH,
years * YEAR_LENGTH,
])
def break_down_time(time_value: int) -> DateDict:
"""
Break time down into a dict of integer values.
"""
resolved: Dict[TimeKey, int] = {}
remainder = time_value
key: TimeKey
for key, divisor in [('year', YEAR_LENGTH), ('season', SEASON_LENGTH), ('day', DAY_LENGTH)]:
resolved[key] = (remainder // divisor) + 1 # The date begins at year 1, Not year 0.
remainder = remainder % divisor
resolved['hour'] = remainder
return resolved
def date_dict_to_string(date_dict: DateDict) -> str:
"""
Given a current time value, return the resolved datetime.
"""
# We can remove this if we decide to do military time.
post_time_marker = 'AM'
hours = date_dict['hour']
if hours > 12:
post_time_marker = 'PM'
hours -= 12
if hours == 0:
# Midnight.
hours = 12
return f'Year {date_dict["year"]}, Season {date_dict["season"]}, Day {date_dict["day"]}, {hours} {post_time_marker}'
def timestamp_to_string(timestamp: int) -> str:
"""Given an integer timestamp, return the display string."""
return date_dict_to_string(break_down_time(timestamp))
if __name__ == '__main__':
current_time = 0
print(timestamp_to_string(current_time))
current_time += time_delta(hours=5, days=3, seasons=0, years=1)
print(timestamp_to_string(current_time))
current_time += time_delta(seasons=5)
print(timestamp_to_string(current_time))
current_time += time_delta(days=45, hours=12)
print(timestamp_to_string(current_time))
arbitrary_date = {'year': 1, 'season': 2, 'day': 5, 'hour': 3}
print(date_dict_to_string({'hour': 3, 'day': 5, 'year': 1, 'season': 2}))
# Turning a date dict back into an int is an exercise left to the reader, but time_delta is 90% of the way there
# already.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment