Introduction
Working with datetime can be a bit daunting and challenging, and handling datetime in Python is no exception. Python's built-in datetime
module introduced us to several classes - date
, datetime
, time
, timezone
and timedelta
, and several external libraries have spawned to address the issues present in the official module, such as Arrow.
In this guide, we'll take a look at how to humanize datetime objects in Delorean - a library built upon pytz which is the standard library for solving problems relating to time zones, and dateutil which is used to calculate deltas between any 2 given datetime objects.
Installing Delorean Setting Up a Virtual Environment
Delorean is available for installation via pip
. It is generally advisable to work in a virtual environment because it enables you to organize dependencies required by different projects isolated.
On Linux, or MacOS to create a virtual environment, we'd run:
$ python3 -m venv env
$ source env/bin/activate
$ python3 -m pip install delorean
Alternatively, on Windows we can run:
$ virtualenv env
$ .\env\Scripts\activate
$ python3 -m pip install delorean
Humanizing Delorean Datetime Objects with humanize()
While Epoch timestamps are extremely precise and great for digital devices - they're not too understandable by humans. We don't have a cognitive awareness of such scales. Additionally, we don't naturally comprehend dates the way computers do, except for some more rare occasions. Most people might not have known what date it is, were it not for the constant clock and calendar built into most digital devices - from stationary to mobile.
For most of the time, we've been dealing with time in reference to where we are now. When did you see your friend? On the 12th of July, 2021, or yesterday? The humanize()
function takes a factual date, and turns it into what people would use while conveying the time of an event:
import delorean
datetime_strings = ["Thu July 12 2021", "June 5th, 2021", "April 28th, 2052"]
for date in datetime_strings:
delorean_object = delorean.parse(date)
human_date = delorean_object.humanize()
print(human_date)
These date strings are parsed into Delorean objects and then humanized:
4 hours from now
a month ago
30 years from now
This is a great feature for annotating the time before or until events on applications. For example, you might tell a user that they've received a notification a day ago, or that a concert is coming up in a month. This can also be switched between if the event is, say, older than N days.
To do this, we'd measure if a date has occurred more than N days before the current date, using timedelta
and adjust the message appropriately:
import delorean
# Dates denote events, such as notifications.
# First event occurred recently before writing this guide.
# The second event occurred a bit over a month before that.
datetime_strings = ["Thu July 12 2021", "June 5th, 2021"]
for index, date in enumerate(datetime_strings):
delorean_object = delorean.parse(date)
current_time = delorean.Delorean()
if (current_time-delorean_object) < datetime.timedelta(5):
human_date = delorean_object.humanize()
print(f'Event {index} happened', human_date)
else:
print(f'Event {index} happened on', delorean_object.date)
This results in:
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
Event 0 happened 14 hours ago
Event 1 happened on 2021-06-05
This makes a lot of sense, because if you tell someone that something happened yesterday, there's not much thought required to make that out. But if you say that something happened a month ago, they'll likely look at the calendar to get a feel of when that was.
Humanize Relative Dates with Delorean
Delorean also makes it easy to reference dates in relation to another date in a very intuitive and human-like way.
See you this time next Friday.
This is well understood by people, but tedious to code by hand using timedelta
. Using a combination of next_
and last_
with days of the week, months or even years, we can calculate and create Delorean objects based on already existing datetimes:
from delorean import Delorean
dt_tm = Delorean()
nxt_fri = dt_tm.next_friday()
print("Friday next week: ", nxt_fri)
# Date for Two Fridays ago
two_fridays_ago = dt_tm.last_friday(2)
print("Friday two weeks ago: ", two_fridays_ago)
# Get Two Fridays from now at midnight
two_fridays_from_now_at_midnight = dt_tm.next_friday(2).midnight
print("Two Fridays from now at midnight: ", two_fridays_from_now_at_midnight)
# Get this time next month
next_month = dt_tm.next_month()
print("This time next month: ", next_month)
# Get this time next year, at midnight
next_month = dt_tm.next_year().midnight
print("This time next month: ", next_month)
To get the date of a day of the week more than just last or next week - we pass in a number denoting the number of weeks we're traversing. The same goes for days, months or years:
Friday next week: Delorean(datetime=datetime.datetime(2021, 7, 16, 19, 25, 34, 427028), timezone='UTC')
Friday two weeks ago: Delorean(datetime=datetime.datetime(2021, 7, 2, 19, 25, 34, 427028), timezone='UTC')
Two Fridays from now at midnight: 2021-07-23 00:00:00+00:00
This time next month: Delorean(datetime=datetime.datetime(2021, 8, 11, 19, 25, 34, 427028), timezone='UTC')
This time next month: 2022-07-11 00:00:00+00:00
Conclusion
In this guide, we've taken a look at how to humanize Delorean datetime objects in Python. Humanization is the process of converting datetime instances to a more human format - using words and relative time frames. Given the relativity of these time frames, it makes sense to humanize dates in some cases, while not in others.