datetime, time and calendar updated

Dates and Times      
Three modules cover almost everything you can think of in dates and times (except a good validating date input routine). Examples below assume you have imported the module with “import module_name”. [In particular we tested and found that “from datetime import *” does NOT work in some instances.]

The modules are:

    1) datetime
    2) time
    3) calendar

Below you will find brief explanations and examples of common uses of these 3 modules that try not to go “deep geek”.  It is really easy to get into a lot of messy stuff when dealing with time and dates.  Please note we try to use the whole path for clarity – especially with intermixed class examples.

The datetime Module – 
     “Types” – (classes –  maybe think of them as sub-modules)
          a. date
          b. datetime
          c. timedelta
          d. time
          [e. tzinfo – not covered here, timezone info not directly instantiated
          f. timezone – not covered here, a subclass of tzinfo with instances being a fixed offset from UTC}

The date Class – probably the most commonly used class:

TO CREATE A DATETIME.DATE INSTANCE: (datetime.date(year, month, day)

mybirthday = datetime.date(1948, 1, 19)
print(str(mybirthday)) … will yield: 1948-01-19

date methods                             date attributes         instance methods                             instance attributes
.today()                                      .min                         .replace(year=,month=,day=)             .year
.fromtimestamp(timestamp) *1*4 .max                        .timetuple()                                        .month
.fromordinal(ordinal)  *2              .resolution                 .toordinal()                                         .day
                                                                                  .weekday()   ->day of wk as int (Monday is 0)
                                                                                  .isoweekday()   ->day of wk as int (Monday is 1)
                                                                                  .isocalendar()   -> 3-tuple, (ISO year, ISO week number, ISO weekday)
                                                                                  .isoformat()   -> returns YYYY-MM-DD format
                                                                                  .__str__()   -> same as isoformat
                                                                                  .ctime()   -> equivalent to time.ctime, i.e., “Sat Jun 16 00:00:00 2018”
                                                                                  .strftime(format)   -> formatted date *3 see format table under time
                                                                                  .__format__(format)   -> formatted date

*1 fromtimestamp (a timestamp integer – seconds since 1969-12-31
*2 fromordinal (an integer => 1 representing days since 0001-01-01
*3 for example, print(datetime.date.strftime(mytoday, “%A %b %d, %Y”)) … will yield something like: Saturday Jun 16, 2018
*4 The user needs to be aware that fromtimestamp only work on dates from 1970 through 2038 – called the “current epoch”:

For Example:
GET TODAY’S DATE, month, day, or year:

today = datetime.date.today()
print(today)

… could yield, for example: 2018-06-15

Once you have the date in variable “today”, the month, day and year are instance attributes:

print(today.month, today.day, today.year, sep="/")

… will yield a standard American business date format, for example: “6/15/2018”

Or you can use the .strftime() instance method with you own format – assume instance “testday2”

print(testday2.strftime('%m/%d/%Y'))

… will yield something like : 06/17/2018

MODIFY A DATE INSTANCE with REPLACE (year, month, day, hour, minute, second, microsecond)

mybirthday = mybirthday.replace(year=1995, day=20)
print("mybirthday changed to: ", str(mybirthday))

… will yield for example: mybirthday changed to: 1995-01-20

GET THE ORDINAL DAY OF THE WEEK FOR A DATE: (an ordinal is a sequential integer)

import datetime as dt
today = dt.date.today()
weekdict = {0:"Monday",1:"Tuesday", 2:"Wednesday", 3:"Thursday", 4:"Friday", 5:"Saturday", 6:"Sunday"}
print("The date is: ", str(today))
wkday = str(today.weekday())
print("The ordinal day of the week is: "+ wkday)
print("Note Monday is 0, Sunday is 6")
print("...so today is a " + weekdict[int(wkday)])

… will yield something like
The date is: 2018-08-08
The ordinal day of the week is: 2
Note Monday is 0, Sunday is 6
…so today is a Wednesday

 

The datetime class combines date and time data. In ways ‘datetime.datetime’ mirrors ‘datetime.date’.

TO CONSTRUCT A DATETIME.DATETIME INSTANCE: – It can be created “manually”, for example: 

 

mydt = datetime.datetime(2018,7,4,hour=22,minute=15,second=30)
print("Fireworks will be: "+ mydt.strftime('%B %dth at %I:%M %p'))

… will yield: Fireworks will be: July 04th at 10:15 PM <-no way to get rid of the 0 in 4th

We can also use datetime.datetime.combine to couple a datetime.date and a datetime.time, like:

print("Creating datetime value for Monty Python's Birthday")
print("1st aired October 5, 1969, at 9:30 PM")
print("Creating date part:")
mpdate = datetime.date(1969, 10, 5)
print(mpdate)
print("Creating time part:")
mptime = datetime.time(21, 30)
print(mptime)
print("Putting them together with datetime.datetime method '.combine(date,time,tzifo):")
mpbd = datetime.datetime.combine(mpdate, mptime)
print(mpbd)

… try the code – don’t forget to import datetime – and you will (hopefully) get:

Creating datetime value for Monty Python’s Birthday
1st aired October 5, 1969, at 9:30 PM
Creating date part:
1969-10-05
Creating time part:
21:30:00
Putting them together with datetime.datetime method ‘.combine(date,time,tzifo):
1969-10-05 21:30:00

 

datetime methods                    datetime attributes            instance methods                   instance attributes
.today() *1a                               .min                                      .date()                                        .year
.now(tz=None) *1b                    .max                                     .time()                                        .month
.utcnow *1c                               .resolution                            .timetz()                                     .day
.fromtimestamp(timestamp, tz=none) *2                               .replace(year=,month=, etc.)    .hour
.utcfromtimestamp(timestamp)                                              .astimezone(tz=None)             .minute
.fromordinal(ordinal) *3 also must be >1                               .utcoffset()                                .second
.combine(date,time,tzinfo) see instance                                .dst()                                        .microsecond
.strptime(datestring, format) see format table under time      .tzname()                                 .tzinfo
.                                                                                              .timetuple()                              .fold
.                                                                                              .utctimetuple()
.                                                                                              .toordinal()
.                                                                                              .timestamp()
.                                                                                              .weekday() -> Monday is day 0
.                                                                                              .isoweekday()
.                                                                                              .isocalendar()
.                                                                                              .isoformat()
.                                                                                              .__str__()
.                                                                                              .ctime()
.                                                                                              .strftime(format) see format table under time
.                                                                                              .__format__()

*1a 2018-06-17 07:51:25.923555 
*1b the same if time zone is None – higher precision
*1c utcnow() – same result, naive object
*2 .fromtimestamp(time.time()) – same result  [timestamp = time.time()] 
*3 the corresponding proliptic Gregorian ordinal date

Examples of Selected Instance Method Results:
testday = datetime.datetime.today()
print(“testday is: “, str(testday))                      testday is: 2018-06-17 16:11:38.887853
print(testday.date())                                        2018-06-17
print(testday.time())                                        16:11:38.887853
print(testday.timetz())                                     16:11:38.887853
print(testday.timetuple())                                time.struct_time(tm_year=2018, tm_mon=6,                       tm_mday=17, tm_hour=16,  tm_min=11, tm_sec=38, tm_wday=6, tm_yday=168, tm_isdst=-1)
print(testday.timetuple().tm_wday)                 6
print(testday.utctimetuple())                            time.struct_time(tm_year=2018, tm_mon=6,                       tm_mday=17, tm_hour=16, tm_min=11, tm_sec=38, tm_wday=6, tm_yday=168, tm_isdst=0)
print(testday.toordinal())                                 736862
print(testday.timestamp())                              1529266298.887853
print(testday.weekday())                                 6
print(testday.isoweekday())                            7
print(testday.isocalendar())                             (2018, 24, 7)
print(testday.isoformat())                                2018-06-17T16:11:38.887853
print(testday.__str__())                                  2018-06-17 16:11:38.887853
print(testday.ctime())                                     Sun Jun 17 16:11:38 2018
print(testday.strftime(‘%A %B %d %I:%M’))  Sunday June 17 04:11    * see format table under time*

GET CURRENT DATE AND TIME TOGETHER:

print("now yields, for example: ",datetime.datetime.now()

… now yields, for example: 2018-06-15 20:01:40.704132

CREATE and COMPARE TIME OBJECTS :(but comparison is all – no addition or subtraction):

starttime = datetime.time(hour=10, minute=16,second=20, microsecond=412800)
print(starttime)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; … will yield 10:16:20.412800
lasttime = datetime.time(hour=10, minute=16,second=20, microsecond=612800)
print("Is last time later than start time? ", lasttime&amp;gt;starttime)

… will yield >>> Is last time later than start time? True

TO GET THE CURRENT HOUR: (also works for minute, second, microsecond)

mytime = datetime.datetime.now()
print("the hour is: " + str(mytime.hour))

… will yield for example: 20

timedelta – is the difference between start and ending points. To use some functions, you must
understand timedelta instance objects. Note there is no “years” attribute, timedelta only deals in
days, seconds, and microseconds internally!

Only one instance method: datetime.timedelta.total_seconds()

For example, to set a date when a loan comes due in 6 months from today:

GET A DATE 180 DAYS IN THE FUTURE:

start = datetime.date.(2019, 1, 1)
duration = datetime.timedelta(days=180)
enddate = start + duration
print(enddate)

… will yield: 2019-06-30&amp;amp;lt;/span&amp;amp;gt;

GET A LENGTH OF TIME SINCE A DAY IN THE PAST:

start = datetime.date(1948,1,19)
end = datetime.date.today()
timedelta = end - start
print(timedelta) 

… will yield, for example: 25715 days, 0:00:00

time – A local time – works with time instances you construct yourself, appears of limited practical value.
TO CONSTRUCT A DATETIME.TIME INSTANCE: is pretty straightforward using:
datetime.time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None, fold=0)

target_time = datetime.time(hour=13, minute=15, second=30, microsecond=555555, tzinfo=None, fold=0)
print(target_time) … will yield 13:15:30.555555

time (class) attributes        instance attributes        instance methods
.min                                    .hour                               .replace(hour=, minute=, second=,
.                                                                                microsecond=, tzinfo=, fold=)
.max                                   .minute                            .isoformat(timespec=’auto’) *1
.resolution                           .second                            .__str__()
                                          .microsecond                    .strftime(format)
                                          .tzinfo                              .__format__(format)
                                          .fold                                .utcoffset()
                                                                                .dst()
                                                                                .tzname() -> return timezone name of a                                                                                                        datetime object
*1 besides ‘auto’, timespec options are ‘hours’, ‘minutes’, ‘seconds’, ‘milliseconds’, ‘microseconds’ – new in 3.6

GET JUST HOUR AND MINUTES FROM YOUR TIME INSTANCE: (see target_time above)
The instance method .isoformat give you lots of options about how much info you want returned.

print(target_time.isoformat(timespec='minutes'))&amp;lt;/span&amp;gt;

… will return something like: 13:15 if run right after you create the target_time instance above

The time Module – Note: see https://docs.python.org/3/library/time.html#module-time for a ton of information and explanation on terminology and conventions not duplicated here. Its important stuff. “import time” is assumed.

Summary of Selected Functions:
Simple Output Functions:
.asctime() – return localtime or convert a tuple or struct_time to a string like
                                                                ‘Sun Jun 20 23:21:05 1993’
.ctime([secs]) – convert seconds since epoch float to local time string … yields something like
                                                                ‘Mon Jun 18 20:06:08 2018’.
.get_clock_info( ‘clock’: time.clock(), ‘monotonic’: time.monotonic(), ‘perf_counter’: time.perf_counter(), ‘process_time’: time.process_time(), ‘time’: time.time())
.gmtime([secs]) – time since epoch to struct_time
.localtime([secs]) – time since epoch to local time
.mktime(t) – inverse of localtime, t is a Tuple or struct_time argument like gmtime returns
.monotonic() – value of a clock that cannot go backwards
.perf_counter() – value of a clock with highest resolution
.process_time() – sum of system and user CPU time for current process
.time() – returns seconds since the epoch as float

Examples of simple output:
print(‘asctime(): ‘, time.asctime())                                  asctime():Mon Jun 18 12:04:35 2018
print(‘ctime(): ‘, time.ctime())                                         ctime(): Mon Jun 18 12:04:35 2018
print(‘clock(): ‘, time.clock() )                                         clock(): 3.950621966169244e-07
print(“get_clock_info(‘clock’): “, time.get_clock_info(‘clock’)
get_clock_info(‘clock’): namespace(adjustable=False,implementation=’QueryPerformanceCounter()’,
monotonic=True, resolution=3.950621966169244e-07)
print(“gmtime(): “, time.gmtime())                  gmtime(): time.struct_time(tm_year=2018, tm_mon=6,                               tm_mday=18,  tm_hour=16, tm_min=4, tm_sec=35, tm_wday=0, tm_yday=169, tm_isdst=0)
print(“localtime():”, time.localtime())                localtime(): time.struct_time(tm_year=2018, tm_mon=6,                            tm_mday=18, tm_hour=12, tm_min=4, tm_sec=35, tm_wday=0, tm_yday=169, tm_isdst=1)
print(“localtime(1000000):”, time.localtime(1000000))
localtime(1000000): time.struct_time(tm_year=1970, tm_mon=1, tm_mday=12, tm_hour=8, tm_min=46,                         tm_sec=40, tm_wday=0, tm_yday=12, tm_isdst=0)
print(“mktime(t): “, time.mktime(time.localtime()))       mktime(t): 1529337875.0
print(“monotonic(): “, time.monotonic())                       monotonic(): 3009.406
print(“perf_counter(): “, time.perf_counter())                perf_counter(): 0.10937178394680566
print(“process_time(): “, time.process_time())             process_time(): 0.546875

Specialty Functions:
.sleep(secs) – suspend execution
.strftime(format[, t]) – convert tuple or struct_time representing a time as returned by gmtime() or localtime() to a string
.strptime(string[, format]) – parse a string according to a format
The strftime and strptime functions need the following tables for reference. Both use the format symbols. The strftime
function takes in a struct_time (or a tuple) and the strptime produces a struct_time result. See example under datetime.date.

Symbol  Meaning                                           Symbol Meaning
%a        Locale’s abbreviated weekday name.   %S       Second as a decimal number [00,61].
%A        Locale’s full weekday name.               %U       Week # of the year (Sunday – first day of the week) as float
%b        Locale’s abbreviated month name.      %w       Weekday as a decimal number [0(Sunday),6].
%B        Locale’s full month name.                  %W      Week # of the year (Monday – first day of the week) as float
%c         Locale’s appropriate date and time representation.
%x         Locale’s appropriate date representation.
%d         Day of the month as a decimal number [01,31].
%X         Locale’s appropriate time representation.
%H         Hour (24-hour clock) as a decimal number [00,23].
%y         Year without century as a decimal number [00,99].
%I         Hour (12-hour clock) as a decimal number [01,12].
%Y        Year with century as a decimal number.
%j         Day of the year as a decimal number [001,366].
%z         Time zone offset indicating a pos or neg difference from UTC/GMT
%m       Month as a decimal number [01,12].
%Z        Time zone name (null if no time zone exists).
%M        Minute as a decimal number [00,59]. %% A literal ‘%’ character.
%p        Locale’s equivalent of either AM or PM.

Class struct_time – time value returned by gmtime, localtime, strptime – has these accessible index #’s and names:
Index, Attribute Name
0 tm_year
1 tm_mon
2 tm_mday
3 tm_hour
4 tm_min
5 tm_sec
6 tm_wday
7 tm_yday
8 tm_isdst
N/A tm_zone
N/A tm_gmtof
Notes: Constants are not addressed in this document.

The Calendar Module – Note: The calendar module slices and dices calendar information in ways for which we cannot imagine an actual use – but they are there is you need them.
The module provides methods addressing calendar information, simple text calendars, and HTML calendars – the HTML class is beyond the scope of this summary. Assume ‘import calendar’.

Class calendar.Calendar
Note: the module allows for setting Sunday as the first day of the week (standard in North America) but defaults to Monday. However, the command “calendar.setfirstweekday(calendar.Sunday)” does NOT appear to have any effect on subsequent instances – i.e., it doesn’t work as far as we can tell. Fortunately, after creating an instance, the instance command for it works:
cal = calendar.Calendar() <-note the capitalization!
cal.setfirstweekday(calendar.SUNDAY)

Class calendar.Calendar Instance Methods:

iterweekdays() – an iterator for the weekday numbers that will be used for one week. itermonthdates(year, month) – an iterator for the month month (1–12) in the year year. itermonthdays2(year, month) – an iterator for the month ‘month’ in the year ‘year’ similar to itermonthdates().
itermonthdays(year, month) – an iterator for the month ‘month’ in the year ‘year’ similar to itermonthdates().
monthdatescalendar(year, month) – a list of the weeks that are lists of seven datetime.date objects.
monthdays2calendar(year, month) – a list of the weeks that are lists of seven tuples of day numbers and weekday numbers.
monthdayscalendar(year, month) – a list of the weeks in the month month of the year as full weeks. (numbers)
yeardatescalendar(year, width=3) – the data for the specified year ready for formatting.
yeardays2calendar(year, width=3) – like yeardatescalendar()) but entries in the week lists are tuples of day numbers and weekday numbers.
yeardayscalendar(year, width=3) – likeyeardatescalendar()), entries in the week lists are day numbers.

Class calendar.TextCalendar(firstweekday=0)
This is the really fun class of the module.
TextCalendar Instances – these four work together as pairs

formatmonth(theyear, themonth, w=0, l=0) – a month’s calendar in a multi-line string, w is the width of the centered date columns, l specifies the number of lines that each week will use.
prmonth(theyear, themonth, w=0, l=0) – print a month’s calendar as returned by formatmonth().

formatyear(theyear, w=2, l=1, c=6, m=3) – a m-column calendar for an entire year as a multi-line string, w and l as explained above, c is for spaces between month columns.
pryear(theyear, w=2, l=1, c=6, m=3) – print the calendar for an entire year as returned by formatyear().

For example: (***Special Note: MUST use a monospace font for this to work)
txtcal = calendar.TextCalendar(firstweekday=6)
calstr = txtcal.formatmonth(2018,6)
print(calstr)
… will yield:

June 2018
Su Mo Tu We Th Fr Sa
                         1   2
 3   4   5   6   7   8   9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30