11.6. Datetime Timedelta¶
11.6.1. Timedelta object¶
Shifting datetime objects:
>>> from datetime import datetime
>>>
>>>
>>> gagarin = datetime(1961, 4, 12, 6, 7)
>>> armstrong = datetime(1969, 7, 21, 2, 56, 15)
>>>
>>> between_dates = armstrong - gagarin
>>>
>>> str(between_dates)
'3021 days, 20:49:15'
>>> between_dates
datetime.timedelta(days=3021, seconds=74955)
>>> between_dates.days
3021
>>> between_dates.seconds
74955
>>> between_dates.total_seconds() # (days * seconds per day + seconds)
261089355.0
11.6.2. Simple Time Shift¶
>>> from datetime import timedelta, datetime
>>>
>>>
>>> gagarin = datetime(1961, 4, 12)
>>>
>>> gagarin - timedelta(minutes=15)
datetime.datetime(1961, 4, 11, 23, 45)
>>>
>>> gagarin + timedelta(minutes=10)
datetime.datetime(1961, 4, 12, 0, 10)
>>> from datetime import timedelta, datetime
>>>
>>>
>>> armstrong = datetime(1969, 7, 21, 2, 56, 15)
>>>
>>> armstrong - timedelta(hours=21)
datetime.datetime(1969, 7, 20, 5, 56, 15)
>>>
>>> armstrong + timedelta(hours=5)
datetime.datetime(1969, 7, 21, 7, 56, 15)
>>> from datetime import timedelta, date
>>>
>>>
>>> sputnik = date(1957, 10, 4)
>>>
>>> sputnik + timedelta(days=5)
datetime.date(1957, 10, 9)
>>>
>>> sputnik - timedelta(days=3)
datetime.date(1957, 10, 1)
>>> from datetime import datetime, timedelta
>>>
>>>
>>> gagarin = datetime(1961, 4, 12)
>>>
>>> gagarin + timedelta(weeks=2)
datetime.datetime(1961, 4, 26, 0, 0)
>>>
>>> gagarin - timedelta(weeks=3)
datetime.datetime(1961, 3, 22, 0, 0)
11.6.3. Complex Shifts¶
>>> from datetime import timedelta, datetime
>>>
>>>
>>> armstrong = datetime(1969, 7, 21, 2, 56, 15)
>>>
>>> armstrong - timedelta(days=2, hours=21)
datetime.datetime(1969, 7, 18, 5, 56, 15)
>>> from datetime import timedelta, datetime
>>>
>>>
>>> armstrong = datetime(1969, 7, 21, 2, 56, 15)
>>>
>>> duration = timedelta(
... weeks=3,
... days=2,
... hours=21,
... minutes=5,
... seconds=12,
... milliseconds=10,
... microseconds=55)
>>>
>>> duration
datetime.timedelta(days=23, seconds=75912, microseconds=10055)
>>>
>>> armstrong - duration
datetime.datetime(1969, 6, 27, 5, 51, 2, 989945)
11.6.4. Month Shifts¶
>>> from datetime import timedelta, date
>>>
>>>
>>> MONTH = timedelta(days=30.4375)
>>>
>>> gagarin = date(1961, 4, 12)
>>> gagarin - MONTH
datetime.date(1961, 3, 13)
>>> from calendar import _monthlen as monthlen
>>> from datetime import timedelta, date
>>>
>>>
>>> def month_before(dt):
... MONTH = monthlen(dt.year, dt.month)
... return dt - timedelta(days=MONTH)
>>>
>>>
>>> gagarin = date(1961, 4, 12)
>>> month_before(gagarin)
datetime.date(1961, 3, 13)
11.6.5. Duration¶
Period between two datetimes
>>> from datetime import datetime
>>>
>>>
>>> SECOND = 1
>>> MINUTE = 60 * SECOND
>>> HOUR = 60 * MINUTE
>>> DAY = 24 * HOUR
>>> MONTH = 30.4375 * DAY # Average days a month in solar calendar
>>> YEAR = 365.25 * DAY # Solar calendar
>>>
>>>
>>> def duration(td):
... years, seconds = divmod(td.total_seconds(), YEAR)
... months, seconds = divmod(seconds, MONTH)
... days, seconds = divmod(seconds, DAY)
... hours, seconds = divmod(td.seconds, HOUR)
... minutes, seconds = divmod(seconds, MINUTE)
... return {
... 'years': int(years),
... 'months': int(months),
... 'days': int(days),
... 'hours': int(hours),
... 'minutes': int(minutes),
... 'seconds': int(seconds)}
>>>
>>>
>>> gagarin = datetime(1961, 4, 12, 6, 7)
>>> armstrong = datetime(1969, 7, 21, 2, 56, 15)
>>>
>>> td = armstrong - gagarin
>>> td
datetime.timedelta(days=3021, seconds=74955)
>>>
>>> duration(td)
{'years': 8, 'months': 3, 'days': 8, 'hours': 20, 'minutes': 49, 'seconds': 15}
11.6.6. Further Reading¶
11.6.7. Assignments¶
"""
* Assignment: Datetime Timedelta Duration
* Complexity: easy
* Lines of code: 2 lines
* Time: 3 min
English:
1. Calculate how many years passed between Gagarin's launch
and Armstrong's first step on the Moon
2. Assume:
a. year = 365.25 days
b. month = 30.4375 days
3. Result round to one decimal place
4. Run doctests - all must succeed
Polish:
1. Podany jest czas, który upłynął między startem Gagarina
a pierwszym krokiem Armstronga na Księżycu
2. Uwzględnij założenie:
a. rok = 365.25 dni
b. miesiąc = 30.4375 dni
3. Rezultat zaokrąglij jednego miejsca po przecinku
4. Uruchom doctesty - wszystkie muszą się powieść
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> assert type(result) is float, \
'Variable `result` has invalid type, must be a float'
>>> result
8.3
"""
from datetime import datetime
DAY = 1
MONTH = 30.4375 * DAY
YEAR = 365.25 * DAY
GAGARIN = datetime(1961, 4, 12, 6, 7)
ARMSTRONG = datetime(1969, 7, 21, 2, 56, 15)
# Time between GAGARIN and ARMSTRONG
# type: timedelta
duration = ...
# Number of years rounded to 1 decimal place
# type: float
result = ...
"""
* Assignment: Datetime Timedelta Age
* Complexity: easy
* Lines of code: 6 lines
* Time: 5 min
English:
1. How old was Yuri Gagarin when he was launched to space?
2. How old was Neil Armstrong when he made a first step on the Moon?
3. Result round to full years
4. Mind, that there are two different objects: `date` and `datetime`
5. Run doctests - all must succeed
Polish:
1. Ile miał lat Juri Gagarin kiedy wystartował w kosmos?
2. Ile lat miał Neil Armstrong kiedy zrobił pierwszy krok na Księżycu?
3. Rezultat zaokrąglij do pełnych lat
4. Zwróć uwagę, że tam są dwa różne obiekty: `date` i `datetime`
5. Uruchom doctesty - wszystkie muszą się powieść
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> assert type(gagarin_age) is int, \
'Variable `gagarin_age` has invalid type, must be a int'
>>> assert type(armstrong_age) is int, \
'Variable `armstrong_age` has invalid type, must be a int'
>>> gagarin_age
27
>>> armstrong_age
38
"""
from datetime import date, datetime
DAY = 1
MONTH = 30.4375 * DAY
YEAR = 365.25 * DAY
GAGARIN_BIRTHDAY = date(1934, 3, 9)
GAGARIN_LAUNCH = datetime(1961, 4, 12, 6, 7)
ARMSTRONG_BIRTHDAY = date(1930, 8, 5)
ARMSTRONG_STEP = datetime(1969, 7, 21, 2, 56, 15)
# Gagarin's age when he was launched to space
# type: int
gagarin_age = ...
# Armstrong's age when he made a first step on the Moon
# type: int
armstrong_age = ...
"""
* Assignment: Datetime Timedelta Period
* Complexity: easy
* Lines of code: 2 lines
* Time: 5 min
English:
1. Given period is the time between Gagarin launch and Armstrong
first step on the Moon:
* 8 years
* 3 months
* 8 days
* 13 hours
* 19 minutes
* 15 seconds
2. Assumption:
a. year = 365.25 days
b. month = 30.4375 days
3. Define `result: timedelta` representing given period
4. Run doctests - all must succeed
Polish:
1. Podany jest czas, który upłynął między startem Gagarina
a pierwszym krokiem Armstronga na Księżycu:
* 8 lat
* 3 miesięcy
* 8 dni
* 13 godzin
* 19 minut
* 15 sekund
2. Założenie:
a. rok = 365.25 dni
b. miesiąc = 30.4375 dni
3. Zdefiniuj `result: timedelta` reprezentujące dany okres
4. Uruchom doctesty - wszystkie muszą się powieść
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> assert type(result) is timedelta, \
'Variable `result` has invalid type, must be a timedelta'
>>> result
datetime.timedelta(days=3021, seconds=74955)
"""
from datetime import timedelta
SECOND = 1
MINUTE = 60 * SECOND
HOUR = 60 * MINUTE
DAY = 24 * HOUR
MONTH = 30.4375 * DAY
YEAR = 365.25 * DAY
# - 8 years
# - 3 months
# - 8 days
# - 13 hours
# - 19 minutes
# - 15 seconds
# type: timedelta
result = ...
"""
* Assignment: Datetime Timedelta Dict
* Complexity: easy
* Lines of code: 13 lines
* Time: 5 min
English:
1. `DATA` is the time between Gagarin launch and Armstrong
first step on the Moon
2. Assume:
a. year = 365.25 days
b. month = 30.4375 days
3. Define `result: dict[str, int]` representing period
4. Run doctests - all must succeed
Polish:
1. `DATA`, to czas który upłynął między startem Gagarina
a pierwszym krokiem Armstronga na Księżycu
2. Uwzględnij założenie:
a. rok = 365.25 dni
b. miesiąc = 30.4375 dni
3. Zdefiniuj `result: dict[str, int]` reprezentujący okres
4. Uruchom doctesty - wszystkie muszą się powieść
Given:
* 8 years
* 3 months
* 8 days
* 20 hours
* 49 minutes
* 15 seconds
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> assert type(result) is dict, \
'Variable `result` has invalid type, must be a dict'
>>> result.keys()
dict_keys(['years', 'months', 'days', 'hours', 'minutes', 'seconds'])
>>> assert all(type(value) is int for value in result.values()), \
'All elements in `result` must be an int'
>>> result # doctest: +NORMALIZE_WHITESPACE
{'years': 8,
'months': 3,
'days': 8,
'hours': 20,
'minutes': 49,
'seconds': 15}
"""
from datetime import timedelta
SECOND = 1
MINUTE = 60 * SECOND
HOUR = 60 * MINUTE
DAY = 24 * HOUR
MONTH = 30.4375 * DAY
YEAR = 365.25 * DAY
DATA = timedelta(days=3021, seconds=74955)
# dict[str, int]
result = {
'years': ...,
'months': ...,
'days': ...,
'hours': ...,
'minutes': ...,
'seconds': ...,
}