Learn Python Series (#22) - Handling Dates and Time Part 2

in #utopian-io7 years ago (edited)

Learn Python Series (#22) - Handling Dates and Time Part 2

python_logo.png

Full additional iPython tutorial sample code file included here:
https://github.com/realScipio/learn-python-series/blob/master/datetime-02.ipynb

What Will I Learn?

  • You will learn about the datetime module and its most-used classes and their methods;
  • about date/time arithmetic using timedelta's, which is really interesting and fun for me at least!
  • about the methods timetuple() and strftime() & strptime()forming a "conversion bridge" between time and datetime instances;
  • and most importantly, by going over all methods and techniques discussed in Parts 1 & 2 of the Handling Dates and Time subseries, hopefully you're able to know the answer - for yourself - what are the differences between the time and datetime modules, and when to use which.

Requirements

  • A working modern computer running macOS, Windows or Ubuntu;
  • An installed Python 3(.6) distribution, such as (for example) the Anaconda Distribution;
  • The ambition to learn Python programming;

Difficulty

Intermediate

Curriculum (of the Learn Python Series):

Learn Python Series (#22) - Handling Dates and Time Part 2

In the previous tutorial of the Learn Python Series regarding the handling of dates and time (part 1) we already learned that both the time module as well as the datetime module provide functionality for handling dates and times. The time module has some more focus on support for UNIX timestamps, and in this episode (part 2) we're going to discuss in which specific areas the datetime modules shines.

Let's begin!

The datetime module

As compared to the time module, the datetime module - instead of mostly working with 9-tuples / time_structs and timestamps / epoch integers (ticks) - has a more modular / object-oriented type of interfacing. I will talk about the following classes, which are included in the datetime module:

  • datetime.time: representing time, independent of its date;
  • datetime.date: representing dates only, independent of time;
  • datetime.datetime: for a combination of date & time on some date;
  • datetime.timedelta: for dealing with differences of 2 date objects or 2 time objects.

The datetime.time class

import datetime

t1 = datetime.time(20, 1, 59, 123456)
print(t1)
20:01:59.123456

The variable t1 is now a datetime.time instance, which has attributes. These are:

hour = t1.hour
minute = t1.minute
second = t1.second
microsecond = t1.microsecond
timezone_info = t1.tzinfo

print('Hour: ', hour)
print('Minute: ', minute)
print('Second: ', second)
print('Microsecond: ', microsecond)
print('Timezone info: ', timezone_info)
Hour:  20
Minute:  1
Second:  59
Microsecond:  123456
Timezone info:  None

The datetime.date class

In order to create a date instance, just pass in 3 values (year, month, day) as the arguments for datetime.date().

d1 = datetime.date(2012, 12, 31)
print(d1)
2012-12-31

Variable d1 is now a datetime.date instance, which has (defaault) attributes as well, being:

year = d1.year
month = d1.month
day = d1.day

print('Year: ', year)
print('Month: ', month)
print('Day: ', day)
Year:  2012
Month:  12
Day:  31

datetime.date.today() method

If you want to create a current day date instance, use the datetime.date.today() class method:

today = datetime.date.today()
print(today)
2018-05-02

datetime.date.timetuple() method

You can still use 9-tuples / timestructs on datetime.date instances by calling the datetime.date.timetuple() method. The exact same 9-tuple / time_struct attributes, as I've explained in Handling Dates and Time Part 1 regarding the time module are available for the datetime module as well via the datetime.date.timetuple() method, like so:

today_tt = today.timetuple()

year = today_tt.tm_year
month = today_tt.tm_mon
month_day = today_tt.tm_mday
hour = today_tt.tm_hour
minute = today_tt.tm_min
second = today_tt.tm_sec
week_day = today_tt.tm_wday
year_day = today_tt.tm_yday
daylight_savings = today_tt.tm_isdst

print('Year: ', year)
print('Month: ', month)
print('Day of Month: ', month_day)
print('Hour: ', hour)
print('Minute: ', minute)
print('Second: ', second)
print('Day of Week: ', week_day)
print('Day of Year: ', year_day)
print('Daylight savings: ', daylight_savings)
Year:  2018
Month:  5
Day of Month:  2
Hour:  0
Minute:  0
Second:  0
Day of Week:  2
Day of Year:  122
Daylight savings:  -1

datetime.date.ctime() method

There's also a ctime() method, like in the time module, returning a date/time string representation. But because the datetime.date class doesn't deal with time, the time components returned are that of midnight:

today_ctime = today.ctime()
print(today_ctime)
Wed May  2 00:00:00 2018

datetime.date.replace() method

A convenient way to create new date instances by using an existing date instance as a starting point, is the replace() method:

today = datetime.date.today()
print('Today: ', today.ctime())

a_month_from_today = today.replace(month=6)
print('A month from today: ', a_month_from_today.ctime())

a_year_from_today = today.replace(year=2019)
print('A year from today: ', a_year_from_today.ctime())
Today:  Wed May  2 00:00:00 2018
A month from today:  Sat Jun  2 00:00:00 2018
A year from today:  Thu May  2 00:00:00 2019

The datetime.datetime class

You probably guessed it: the datetime.datetime class is best used when you're dealing with date/time values in which relevant values for both date and time are present.

datetime.datetime.now() / datetime.datetime.today()

Works the same as the datetime.date.today() method, but now includes a time component as well:

now = datetime.datetime.today()
print(now)
2018-05-02 21:40:46.430434

datetime.datetime.combine()

Another pretty handy method is combine(): it creates a datetime instance by combining one date instance plus 1 time instance, like so:

some_date = datetime.date(2015, 9, 14)
some_time = datetime.time(14, 53, 0)
combined_datetime = datetime.datetime.combine(some_date, some_time)

print('some_date: ', some_date)
print('some_time: ', some_time)
print('combined_datetime: ', combined_datetime)
some_date:  2015-09-14
some_time:  14:53:00
combined_datetime:  2015-09-14 14:53:00

The datetime.timedelta class

A really nice class - at least I think it's cool! - is the datetime.timedelta class. It's possible to execute basic arithmetic on date / datetime instances, for example calculate how many dats are in between two dates, by subtracting them:

today = datetime.date.today()
some_day  = datetime.date(2012, 10, 10)

diff_days = today - some_day
print(diff_days)
2030 days, 0:00:00

By subtracting two dates, you (implicitly) create a timedelta instance.

print(type(diff_days))
<class 'datetime.timedelta'>

And you can use a timedelta to do arithmetic to produce another date!

You can create timedeltas, in multiple time units, yourself, like so:

one_week = datetime.timedelta(weeks=1)
one_day = datetime.timedelta(days=1)
one_hour = datetime.timedelta(hours=1)
one_minute = datetime.timedelta(minutes=1)
one_second = datetime.timedelta(seconds=1)
one_millisecond = datetime.timedelta(milliseconds=1)
one_microsecond = datetime.timedelta(microseconds=1)

print('one_week: ', one_week)
print('one_day: ', one_day)
print('one_hour: ', one_hour)
print('one_minute: ', one_minute)
print('one_second: ', one_second)
print('one_millisecond: ', one_millisecond)
print('one_microsecond: ', one_microsecond)
one_week:  7 days, 0:00:00
one_day:  1 day, 0:00:00
one_hour:  1:00:00
one_minute:  0:01:00
one_second:  0:00:01
one_millisecond:  0:00:00.001000
one_microsecond:  0:00:00.000001

Performing date arithmetic using timedeltas

Now the fun part begins, by combining date / time / datetime instances with timedeltas and regular math operators!

today = datetime.date.today()
print('Today: ', today)

one_week = datetime.timedelta(weeks=1)

last_week = today - one_week
print('Last week: ', last_week)

next_week = today + one_week
print('Next week: ', next_week)

print('Days in between next and last week: ', next_week - last_week)
Today:  2018-05-02
Last week:  2018-04-25
Next week:  2018-05-09
Days in between next and last week:  14 days, 0:00:00

Because timedelta objects can work with floats, integers, and other timedelta objects, you can create interesting combinations.

How about this for getting creative with timedelta arithmetic?

vp_recharge_period = datetime.timedelta(days=1) * 0.1
powerdown_period = datetime.timedelta(weeks=13)
num_votes_during_powerdown = powerdown_period / vp_recharge_period

print('vp_recharge_period: ', vp_recharge_period)
print('powerdown_period: ', powerdown_period)
print('num_votes_during_powerdown: ', num_votes_during_powerdown)
vp_recharge_period:  2:24:00
powerdown_period:  91 days, 0:00:00
num_votes_during_powerdown:  910.0

datetime object string formatting & parsing

In the previous tutorial, regarding the time module, we've in-depth covered the usage of time.strftime() (for string formatting) and time.strptime() (for date/time string parsing). The same type of methods are also available on the datetime class.

For those that haven't read the previous tutorial regarding time.strftime() and time.strptime(), I'll briefly demonstrate how to use the same methods in a date.strftime() and date.strptime() context.

We define a date/time format string, create a datetime object (now) and convert between the two, proving the same now is used for variables s (string) and p (parsed).

format_string = "%A, %d %b %Y (%H:%M:%S)"
now = datetime.datetime.today()
s = now.strftime(format_string)
p = datetime.datetime.strptime(s, format_string)
print('strftime:', s)
print('strptime:', p)
strftime: Wednesday, 02 May 2018 (23:32:58)
strptime: 2018-05-02 23:32:58

Nota bene: Since we've also covered the datetime.date.timetuple() method, I'm sure you'll be able to conveniently make use of the most handy methods available on both the time and datetime classes, while at the same time being able to convert between the two.

PS: A word or two about the datetime.tzinfo class

The datetime module is able to work with time zones as well, but as subclasses of the datetime.tzinfo class, which is abstract, and therefore you need to provide your own implementations to make the methods work. It can be ... "tricky", to say the least. You could also say that working with timezones via the datetime module is oftentimes considered "a nightmare" by many Pythonistas.

But no worries! The next Learn Python Series episode is about the external date/time package Maya, which makes your life a whole lot easier, including handling timezones.

What did we learn, hopefully?

In this episode, we went over the "ins-and-outs" of the datetime module and its classes and methods. Some of the methods are pretty straightforward (such as combine() and replace()) yet powerful to use. The most "fun" part - at least I think so - about the datetime module, is the datetime.timedelta class. Because it allows you to do date/time arithmetic using floats, integers and other timedeltas, you can get pretty creative with it in just a few lines of code!

Nota bene: One of the core take-aways I wanted to address here, by first going over in-depth regarding the time module, and then doing the same for the datetime module, is that although they overlap to a certain extent - which became clear, hopefully, by me discussing al those methods - is that both modules have their specific strengths. And, because of the timetuple() method and the strftime() & strptime() methods, forming a "conversion bridge" between the time module and the datetime module, you can freely choose to combine whatever you want!

Thank you for your time!

Sort:  

Hey @scipio

We're already looking forward to your next contribution!

Decentralised Rewards

Share your expertise and knowledge by rating contributions made by others on Utopian.io to help us reward the best contributions together.

Utopian Witness!

Vote for Utopian Witness! We are made of developers, system administrators, entrepreneurs, artists, content creators, thinkers. We embrace every nationality, mindset and belief.

Want to chat? Join us on Discord https://discord.me/utopian-io

Thank you @utopian-io! Bleep! Bleep!

Thank you for the contribution It has been approved.


Need help? Write a ticket on https://support.utopian.io.
Chat with us on Discord.

[utopian-moderator]

Thank you too! :-)

this is very valuable info in your posts. It makes me wish i was less busy to learn python script.

Thanks for the kind words

Hey this is great! Do you mind if I link to this tutorial from my own? I will be adding it to utopian.io soon and I'd like to include it as a refrence link at the bottom for those who don't understand the date and time manipulations my code uses. I'd like to link to a few others in this series as well such as handling strings and lists and using import. Let me know. Are you on discord?

Feel free to link to any of my Learn Python Series episodes!

The explanation of the differences really helped me understand them a bit better.

I was actually coding not too long ago and ran into issues trying to parse dates and times. This helped a ton.

Good! :-)

Toda I learned about the methods timetuple() and strftime() & strptime()forming a "conversion bridge" between time and datetime instances. Thanks to you for the valuable post.

Did you seriously copy-paste that line from my tutorial, just to post this comment???

I really love your post.

My post loves you too!

Dear @scipio,
Thank you so much for posting so beautiful.
SIR was very good for your posting. Because you get many benefits with the right information, so thank you very much for posting so beautiful and helping others by providing such information in the future.

Coin Marketplace

STEEM 0.22
TRX 0.27
JST 0.041
BTC 104664.06
ETH 3858.84
SBD 3.32