1
00:00:05,300 --> 00:00:09,690
so at some point you gonna have to start
dealing with dates and times in your

2
00:00:09,690 --> 00:00:13,280
Python programs and although this
should be easy there are actually

3
00:00:13,280 --> 00:00:18,490
several pitfalls which just a really
they're waiting to trap the unwary

4
00:00:18,490 --> 00:00:22,170
now there is two main sources of problems with dates
and times

5
00:00:22,170 --> 00:00:26,260
localization and daylight saving and
they can really complicates things if

6
00:00:26,260 --> 00:00:30,010
you don't handle them correctly or not
handled correctly now localization

7
00:00:30,010 --> 00:00:34,080
that covers both the time in any
particular place and also the

8
00:00:34,080 --> 00:00:38,220
format used to represent dates in that
particular location and there's not

9
00:00:38,220 --> 00:00:44,100
necessarily any rhyme or reason to
this so as an example in Hoyt Mongolia Lasara

10
00:00:44,100 --> 00:00:49,180
in China and Dhaka in Bangladesh lay on the line running on almost due north-south

11
00:00:49,180 --> 00:00:56,260
but at 10 a.m. in Hoyt is 11 a.m. in
Lhasa and 9 a.m. in Dhaka so the UK

12
00:00:56,260 --> 00:01:01,250
is part of the European Union but most
of Western Europe is one hour ahead now

13
00:01:01,250 --> 00:01:02,560
daylight savings time

14
00:01:02,560 --> 00:01:07,290
abbreviated to DST that involves moving
the clocks forward in spring resulting in

15
00:01:07,290 --> 00:01:11,360
everyone getting up 1 hour earlier to take
advantage of the extra daylight as the

16
00:01:11,360 --> 00:01:14,880
Sun rises earlier in the morning now
clocks are then put back one hour in

17
00:01:14,880 --> 00:01:19,770
autumn but not every country practices
daylight saving though for example the

18
00:01:19,770 --> 00:01:24,060
Philippines don't and that's why I've
explained what it is for you in case you are

19
00:01:24,060 --> 00:01:27,790
not aware of what you know daylight
saving time is and its practiced in

20
00:01:27,790 --> 00:01:32,490
Australia and I we've actually got at some
points in time three different times

21
00:01:32,490 --> 00:01:38,330
zones in Australia covering these and I know at least
that many in the united states in fact

22
00:01:38,330 --> 00:01:42,940
most of Africa India and Asia don't mess
around with their clocks and even in America

23
00:01:42,940 --> 00:01:46,700
some states such as Arizona
don't bother with daylight saving time

24
00:01:46,700 --> 00:01:51,480
at all but in the UK the actual dates
when the clock would changed use to be set

25
00:01:51,480 --> 00:01:55,200
each year by a special meeting of
Admiralty which meant that you wouldn't

26
00:01:55,200 --> 00:01:59,020
be sure you couldn't be sure that when
the change from one year to the next

27
00:01:59,020 --> 00:02:03,180
fortunately countries that do observe
daylight savings now make the dates

28
00:02:03,180 --> 00:02:07,140
known for several years in advance and
that's so that computer operating

29
00:02:07,140 --> 00:02:12,290
systems like Windows and Linux Mac can maintain files with date which are sent

30
00:02:12,290 --> 00:02:16,810
down to individual computers as part of
their normal update process you can imagine the sort of

31
00:02:16,810 --> 00:02:17,930
the chaos

32
00:02:17,930 --> 00:02:21,540
if they didn't know ahead of time when
daylight saving was meant to change your

33
00:02:21,540 --> 00:02:25,150
computer and have the wrong date and time
so for scientific and computer

34
00:02:25,150 --> 00:02:29,240
applications its usual to work in
Coordinated Universal Time that's

35
00:02:29,240 --> 00:02:33,910
abbreviated to UTC is not a misspelling
UTC was chosen as a compromise between

36
00:02:33,910 --> 00:02:38,490
the English and French translations
so in French the abbreviation would have

37
00:02:38,490 --> 00:02:43,680
been TUC for temps universel coordonné not that I can speak French very well as

38
00:02:43,680 --> 00:02:46,550
the English and the French have a long
history of not agreeing on anything

39
00:02:46,550 --> 00:02:51,960
UTC was chosen as a compromise and you
may also find UTC interestingly enough

40
00:02:51,960 --> 00:02:54,900
referred to also Zulu time now

41
00:02:54,900 --> 00:02:59,910
dates and times in computer applications and
they're usually stored as UTC together

42
00:02:59,910 --> 00:03:05,850
with an offset to represent the number
of hours ahead of or behind UTC and a flag

43
00:03:05,850 --> 00:03:10,930
to indicate if daylight savings time applies
unless you can be sure that your program

44
00:03:10,930 --> 00:03:15,830
will only ever be used in your current
time zone and frankly with the world

45
00:03:15,830 --> 00:03:19,520
wide internet it's really a bad
assumption to do that though what you should do

46
00:03:19,520 --> 00:03:22,250
is adopt this method rather than
storing local time in other

47
00:03:22,250 --> 00:03:27,990
words you should really be storing your
dates as UTC and with that offset as I mentioned for

48
00:03:27,990 --> 00:03:34,320
a particular time zone and now how does this relate to Python well the Python standard library provides three

49
00:03:34,320 --> 00:03:39,160
modules to help us deal with dates and
times and that's the time date time and

50
00:03:39,160 --> 00:03:43,070
calendar modules generally if you just
dealing with elapsed time and that would

51
00:03:43,070 --> 00:03:46,160
be things like timing how long a program
takes to execute

52
00:03:46,160 --> 00:03:50,310
and we will be doing that shortly then the time
module will be all we need but if you dealing

53
00:03:50,310 --> 00:03:54,460
with actual dates and times and date time
would be more useful now the help for the

54
00:03:54,460 --> 00:03:59,240
time model doesn't include a link so what I'm going to do is open up the link and put the

55
00:03:59,240 --> 00:04:05,680
link in the Resources section so open up a browser and we ill refer to this a few times so it can be useful

56
00:04:05,680 --> 00:04:10,600
to have a look at this page so as can see
this is the documentation for the time

57
00:04:10,600 --> 00:04:15,100
and we will as i mentioned with refer to this will come
back to this a few times so some of the

58
00:04:15,100 --> 00:04:20,519
documentation like what we've seen in the
past with Python can be confusing and

59
00:04:20,519 --> 00:04:24,690
the reason particularly with time in
Python is that it discusses the underlying

60
00:04:24,690 --> 00:04:28,840
c libraries Python uses to provide this time support

61
00:04:28,840 --> 00:04:34,430
because c was closely tied to UNIX
systems documentation also talks about

62
00:04:34,430 --> 00:04:39,360
UNIX systems a lot but most functions
also work on windows in order to make our

63
00:04:39,360 --> 00:04:43,260
code portable across operating systems
we're not going to look at any UNIX only

64
00:04:43,260 --> 00:04:46,350
functions were going to restrict
ourselves to the general

65
00:04:46,350 --> 00:04:51,350
functions at work on all operating systems
and we've discussed most of the terms in

66
00:04:51,350 --> 00:04:55,410
the terminology convention section of
the document but we haven't

67
00:04:55,410 --> 00:04:59,540
mentioned rather epok so that
c libraries work by storing the number

68
00:04:59,540 --> 00:05:04,470
of seconds since start date and that's
referred to generously as the epoc and in Python

69
00:05:04,470 --> 00:05:09,250
on Linux Windows and Mac this is
January 1 1970 now

70
00:05:09,250 --> 00:05:13,840
dates before these are represented by negative number although with that said there is a warning that dates

71
00:05:13,840 --> 00:05:17,490
before the start of the epoch may not be
handled but if your dealing with historical

72
00:05:17,490 --> 00:05:22,180
dates and it's actually probably a good
idea to store them as strings in a

73
00:05:22,180 --> 00:05:27,530
standard format such as you know y y
y y dash mm dash dd otherwise

74
00:05:27,530 --> 00:05:31,610
storing and manipulating dates as strings is not really a good idea and

75
00:05:31,610 --> 00:05:36,820
it's note worth noting  that a 32 bit signed
integer will overflow up to two billion 147

76
00:05:36,820 --> 00:05:42,550
483648 and
that many seconds after first of January

77
00:05:42,550 --> 00:05:47,580
1970 is sometime in February
2038 so the bottom line is the

78
00:05:47,580 --> 00:05:53,200
dates this is not going to work as of
Feb 2038 because we are going to be overflowing with 32bit integer

79
00:05:53,200 --> 00:05:58,470
so physically the computer wont be able to store the
right number to sort of track forward

80
00:05:58,470 --> 00:05:59,980
but hopefully by then

81
00:05:59,980 --> 00:06:04,120
we still got a bit of time all of these
computers will be at least 64 bit but if

82
00:06:04,120 --> 00:06:08,530
you happen to be using 32 bit operating
system now in 20 odd years time I'll

83
00:06:08,530 --> 00:06:13,260
be asking but secondly we're dealing with
dates with them if you are going to be using that ok so a

84
00:06:13,260 --> 00:06:17,490
lot of theory there it is time to get in to do
some code so let's go and see some of

85
00:06:17,490 --> 00:06:23,690
the time functions in action so go back to IntelliJ
and open up and I've

86
00:06:23,690 --> 00:06:32,390
created a new project going to create a
new Python file and call it datecalc

87
00:06:32,390 --> 00:06:36,250
could just have been called literally
anything and lets print some time

88
00:06:36,250 --> 00:06:39,280
structures from the epoch date or the
system that we're running

89
00:06:39,280 --> 00:06:47,630
on my system is on a Mac so we can
start by typing...

90
00:06:47,630 --> 00:07:01,960
....

91
00:07:01,960 --> 00:07:11,450
...lets run that and we'll talk about each of the options

92
00:07:11,450 --> 00:07:17,590
so line 3 specifies the number of seconds is 0 so
essentially that's gonna represent the

93
00:07:17,590 --> 00:07:22,330
start of the epoch now the GMT time
function is also used to convert this

94
00:07:22,330 --> 00:07:28,300
into tuple in GMT time always works in
UTC so to get the local time we

95
00:07:28,300 --> 00:07:31,890
can use the local time function like you
can see on line 5 and that converts

96
00:07:31,890 --> 00:07:37,530
the time in seconds as the start of the epock as well into a tuple and you can see the first print out you

97
00:07:37,530 --> 00:07:40,400
can see that's clearly a tuple and its got the information relating to the

98
00:07:40,400 --> 00:07:47,530
dates the first example from line 3 output remember I mentioned that Jan 1st 1970

99
00:07:47,530 --> 00:07:51,550
and because we specified 0 its come back to
that date automatically and the second

100
00:07:51,550 --> 00:07:55,990
example local time it's picked up on the
fact that today in Australia is the 13th of

101
00:07:55,990 --> 00:07:57,800
January

102
00:07:57,800 --> 00:08:03,360
so the date is 13th month is one in 2016
and it's even got the time there

103
00:08:03,360 --> 00:08:10,960
13 49 15 obviously 1:49 in the afternoon

104
00:08:10,960 --> 00:08:15,080
essentially because we didn't specify
the epoch it's defaulting to today's date and we

105
00:08:15,080 --> 00:08:19,370
could have also if you wanted to because you can see the third
example time.time and that's

106
00:08:19,370 --> 00:08:23,430
actually printed out the number of
seconds since the start of an epoch

107
00:08:23,430 --> 00:08:27,750
that's the number of seconds since the
first the first 1970 so

108
00:08:27,750 --> 00:08:33,450
we could have change the line on the code on line 5 and if we wanted to

109
00:08:33,450 --> 00:08:35,490
we could have made that time....

110
00:08:35,490 --> 00:08:39,690
...to call the time function and run that

111
00:08:39,690 --> 00:08:46,100
and you can see we got the similar results there so the
documentation states that GM time

112
00:08:46,100 --> 00:08:50,500
and local time convert the number of
seconds into a struct_time

113
00:08:50,500 --> 00:08:55,720
and that's actually named tuple so we are going to be looking at how to create our owned named tuples

114
00:08:55,720 --> 00:08:59,930
later in the course this is a good
opportunity to see how to use them so

115
00:08:59,930 --> 00:09:04,410
they just like order tuples that
we've seen previously in the course but also

116
00:09:04,410 --> 00:09:09,190
they allow the individual items in a
tuple to be accessed using a name and

117
00:09:09,190 --> 00:09:12,090
that can be very useful way to make
a code much more readable

118
00:09:12,090 --> 00:09:17,410
what will do is we will assign the current local time to a
variable which can be a tuple and use

119
00:09:17,410 --> 00:09:29,670
both methods to access the individual items so you can see what I mean so I'm going to delete those two examples I'm going to put...

120
00:09:29,670 --> 00:10:17,970
....

121
00:10:17,970 --> 00:10:25,340
...so we can print the year here

122
00:10:25,340 --> 00:10:30,240
and will just run this first so run that and I made a typo so just change that, that should be

123
00:10:30,240 --> 00:10:40,560
underscore here and try running it again and you can see we got the
year and we got two ways of out putting it 2016 the

124
00:10:40,560 --> 00:10:45,370
month and the day and that is the correct date because we've
selected local time or using local

125
00:10:45,370 --> 00:10:49,610
time in Australia's as I'm recording the
video so you can basically print the year using

126
00:10:49,610 --> 00:10:53,620
the tuple either the way we previously
seen using index 0 so that's this first

127
00:10:53,620 --> 00:10:59,380
example time_here 0 in square brackets but we can also use
the name so it's time_here

128
00:10:59,380 --> 00:11:05,200
.tm_year and that's the named
tuple so there's no practical

129
00:11:05,200 --> 00:11:09,060
difference between the two ways but
using the name does make it more obvious

130
00:11:09,060 --> 00:11:13,930
which fields are being accessed because obviously you contrast
time_here

131
00:11:13,930 --> 00:11:19,230
is 0 in square brackets as year that's a lot harder than trying to figure out that is a year but this second part here

132
00:11:19,230 --> 00:11:23,440
time_here.tm_year you
probably think ok this must be the

133
00:11:23,440 --> 00:11:27,190
year so other than the fact that it's
easy to read there is no other differences no

134
00:11:27,190 --> 00:11:30,530
other reason or practical difference
between the two ways because both

135
00:11:30,530 --> 00:11:34,420
methods really do return the same value
so name tuples are very useful and we will look at

136
00:11:34,420 --> 00:11:38,340
how to create our own as I mentioned after
we have covered classes and that is going to be

137
00:11:38,340 --> 00:11:40,700
later in the course but for now whenever you see a

138
00:11:40,700 --> 00:11:44,740
named tuple mention in the documentation
you can treat it just like an ordinary

139
00:11:44,740 --> 00:11:48,470
tuple with the advantage of accessing
the individual fields I should say in the

140
00:11:48,470 --> 00:11:53,870
tuple by their names so to have a look at how we can measure elapse time Python we are going to create a very

141
00:11:53,870 --> 00:11:58,390
simple reaction time game once the game
has started it is gonna wait for a random number

142
00:11:58,390 --> 00:12:01,870
of seconds before displaying a message
on the screen and that's going to

143
00:12:01,870 --> 00:12:06,380
measure the time it takes the player to
press enter so let us start typing some of the code

144
00:12:06,380 --> 00:12:10,850
because Python does provide a
number of ways to measure the elapse time

145
00:12:10,850 --> 00:12:19,160
so we are gonna look at each one in turn so we are going to comment out the code we got in here

146
00:12:19,160 --> 00:12:26,820
actually I'll leave the import in because we need that actually what I'll do is start typing down here so we are going to put...

147
00:12:26,820 --> 00:12:39,310
....

148
00:12:39,310 --> 00:12:57,560
....you can see we are specifying a random delay

149
00:12:57,560 --> 00:13:09,370
between 1 and 6 and we are going to sleep for that
many seconds so...

150
00:13:09,370 --> 00:13:20,810
...now we are going to ask them to press Enter
to stop....

151
00:13:20,810 --> 00:13:30,380
...so we are going to basically recording the start
time before enter was press and then end

152
00:13:30,380 --> 00:13:34,690
time afterwards and from there we can figure out how long
it took so from there we can put...

153
00:13:34,690 --> 00:14:02,470
.....

154
00:14:02,470 --> 00:14:09,040
.....same output but we are going to change
the parameter we are passing to...

155
00:14:09,040 --> 00:14:11,310
......

156
00:14:11,310 --> 00:14:22,790
.....

157
00:14:22,790 --> 00:14:34,220
...so that is our program and lets talk about
some of the code firstly the on line

158
00:14:34,220 --> 00:14:39,590
12 the from time using import
statement in that form is very useful

159
00:14:39,590 --> 00:14:43,690
when experimenting with different
implementations of files and modules but

160
00:14:43,690 --> 00:14:47,090
generally speaking you wouldn't leave
that in production code so one reason is that

161
00:14:47,090 --> 00:14:51,390
it can be very hard for anyone else to know that
my_timer is actually the time

162
00:14:51,390 --> 00:14:54,730
functions from the standard library and that
probably expected to be your own

163
00:14:54,730 --> 00:14:58,700
function until they go back to the start
of the code and check the imports so once

164
00:14:58,700 --> 00:15:02,860
again remember that your modules can contain hundreds of
lines of code and in this example it's

165
00:15:02,860 --> 00:15:06,220
obviously very quick because its all in one
screen but you do want to consider

166
00:15:06,220 --> 00:15:10,680
maintenance of your code down the
track now the reaction game is pretty simple

167
00:15:10,680 --> 00:15:14,410
uses the random module to generate a
random number of seconds between one and

168
00:15:14,410 --> 00:15:18,720
six which you can see on line 17 and then
on line 18 it uses time.sleep

169
00:15:18,720 --> 00:15:21,750
where it actually basically sleeps with that amount of time

170
00:15:21,750 --> 00:15:27,000
when it wakes up it stores the current time in start time and displays a message using input

171
00:15:27,000 --> 00:15:32,200
so when the player presses
enter then time is stored now because we have used

172
00:15:32,200 --> 00:15:36,120
the time function we can print the start and end times in the player's local time so the

173
00:15:36,120 --> 00:15:42,520
STR if time that stands for string from
time that can be used to format the

174
00:15:42,520 --> 00:15:46,280
local time tuple into a more readable
form according to a format string its

175
00:15:46,280 --> 00:15:52,450
pass to it so there is a table in the documentation will go and have a look at it shortly but why don't we give this program a bit of a run first to see

176
00:15:52,450 --> 00:16:04,600
what it actually does and we will talk about it more
press enter to start

177
00:16:04,600 --> 00:16:13,680
you can see what happened there it started
14:01:19 and finished to 14:01:20 so

178
00:16:13,680 --> 00:16:19,110
my reaction time is point 79 of a second
so just under a second so I'm not fully

179
00:16:19,110 --> 00:16:26,340
asleep let's try again a bit slower there and you can see I was .98 second at

180
00:16:26,340 --> 00:16:30,190
that time but you can see that seems to be working
and the local time can confirm that

181
00:16:30,190 --> 00:16:32,920
that is the right time if we click on
this and have a look

182
00:16:32,920 --> 00:16:38,310
Wednesday 2:01 p.m. as you can see so that is working so getting back to the documentation string

183
00:16:38,310 --> 00:16:48,690
for time let's go have a look at that
will search for strft click on that and you can see these various

184
00:16:48,690 --> 00:16:54,770
options and we used the %X in uppercase locale's
appropriate time representation so

185
00:16:54,770 --> 00:16:59,170
we just telling it this case that we only want
the time component out of the string effectively

186
00:16:59,170 --> 00:17:03,550
out of the date to be shown on the
screen so that's a basic example of this

187
00:17:03,550 --> 00:17:06,869
problems with this program though I'll show you one
quickly and then I'm going to end the

188
00:17:06,869 --> 00:17:11,890
video and will continue on the next one but
one of the first problems we got is I can press enter twice there

189
00:17:11,890 --> 00:17:19,700
and then wait for it to wake up and you can see
their my reaction time is points .0001580

190
00:17:19,700 --> 00:17:23,880
that's because I already pressed enter
twice and the computer accepted that

191
00:17:23,880 --> 00:17:28,050
enter in advance and that's why I was able
to do it so quickly so there's a problem

192
00:17:28,050 --> 00:17:31,610
with that in that I can cheat and also another
problem but we'll start talking about

193
00:17:31,610 --> 00:17:34,760
both of those issues and also how to correct those in the
next video

