Skip to content

Commit e84cb65

Browse files
committed
final changes
1 parent badc19d commit e84cb65

File tree

5 files changed

+343
-1
lines changed

5 files changed

+343
-1
lines changed
Lines changed: 341 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,341 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
6+
<meta name="viewport" content="width=1024, user-scalable=no">
7+
8+
<title>Python300 week 06, datetime</title>
9+
10+
<!-- Required stylesheet -->
11+
<link rel="stylesheet" media="screen" href="deckjs/core/deck.core.css">
12+
13+
<!-- Extension CSS files go here. Remove or add as needed. -->
14+
<link rel="stylesheet" media="screen" href="deckjs/extensions/goto/deck.goto.css">
15+
<link rel="stylesheet" media="screen" href="deckjs/extensions/menu/deck.menu.css">
16+
<link rel="stylesheet" media="screen" href="deckjs/extensions/navigation/deck.navigation.css">
17+
<link rel="stylesheet" media="screen" href="deckjs/extensions/status/deck.status.css">
18+
<link rel="stylesheet" media="screen" href="deckjs/extensions/scale/deck.scale.css">
19+
20+
<!-- Style theme. More available in /themes/style/ or create your own. -->
21+
<link rel="stylesheet" media="screen" href="deckjs/themes/style/swiss.css">
22+
<!-- Transition theme. More available in /themes/transition/ or create your own. -->
23+
<link rel="stylesheet" media="screen" href="deckjs/themes/transition/horizontal-slide.css">
24+
25+
<!-- Basic black and white print styles -->
26+
<link rel="stylesheet" media="print" href="deckjs/core/print.css">
27+
28+
<!-- Required Modernizr file -->
29+
<script src="deckjs/modernizr.custom.js"></script>
30+
</head>
31+
<body>
32+
<div class="deck-container">
33+
34+
<!-- Begin slides. Just make elements with a class of slide. -->
35+
<section class="slide">
36+
<h2>System Development with Python</h2>
37+
<h3>Week 6 :: datetime, time, pytz</h3>
38+
<p>Joseph Sheedy</p>
39+
<p><i>[email protected]</i></p>
40+
<p>Git repository: <a href="https://github.com/UWPCE-PythonCert/Python300-SystemDevelopmentWithPython-Spring-2014" target="_blank">https://github.com/UWPCE-PythonCert/Python300-SystemDevelopmentWithPython-Spring-2014</a></p>
41+
</section>
42+
43+
<section class="slide">
44+
<h2>datetime, time, pytz</h2>
45+
<h3>What's so hard about representing time? </h3>
46+
<p>Humans are mostly accustomed to communicating in their local timezone.
47+
<p>There are hundreds of them, whose definitions change
48+
<p>What happens to your application when it's deployed to a server running in a different timezone?
49+
<p>The length of a day is not constant, and <a target="_blank" href="http://en.wikipedia.org/wiki/Leap_second">leap seconds</a> have been inserted frequently
50+
<p>Daylight savings time challenges
51+
</section>
52+
53+
<section class="slide">
54+
<h2><a target="_blank" href="http://en.wikipedia.org/wiki/Daylight_saving_time">DST</a></h2>
55+
<p>Daylight savings time creates discontinuities in a time series
56+
<p>
57+
<img width="90%" src="images/6libU.png" />
58+
<p>
59+
<img width="90%" src="images/FfBuN.png" />
60+
</section>
61+
62+
<section class="slide">
63+
<h2>On representing a point in time</h2>
64+
<ul>
65+
<li>There are two major time standards which you should understand:
66+
<ul>
67+
<li><a target="_blank" href="http://en.wikipedia.org/wiki/UTC">UTC: Coordinated Universal Time (French: Temps Universel Coordonné)</a>
68+
<li><a target="_blank" href="http://en.wikipedia.org/wiki/Unix_time">UNIX time</a>
69+
</ul>
70+
</ul>
71+
</section>
72+
<section class="slide">
73+
<h2><a target="_blank" href="http://en.wikipedia.org/wiki/UTC">UTC: Coordinated Universal Time (French: Temps Universel Coordonné)</a></h2>
74+
<p>This is the primary time standard in the world
75+
<p>Provides a consistent reference all other time zones can relate to
76+
<p>No daylight savings time
77+
<p>Also known as Zulu Time, as the UTC time zone is sometimes denoted by the letter Z, e.g. 12:59Z
78+
<p>It is similar to, but not the same as, Greenwich Mean Time (GMT). UTC is more precisely defined
79+
<p>
80+
<!--
81+
-->
82+
<img width="30%" src="images/Greenwich_clock.jpg" />
83+
</section>
84+
85+
<section class="slide">
86+
<h2><a target="_blank" href="http://en.wikipedia.org/wiki/Unix_time">UNIX time</a></h2>
87+
<ul>
88+
<li>UNIX time is represented as the number of seconds from one point in time known as the Epoch, defined to be 00:00 UTC January 1, 1970, not counting leap seconds
89+
<li>Note that UNIX time is based on another time standard
90+
<li>On 32 bit OSes which store time as a signed 32-bit integer, the largest value that can be stored is 03:14:07 UTC on Tuesday, 19 January 2038. One second afterwards, time overflows back to zero. This is known as the Y2038 problem.
91+
<li>On 64 bit machines, the largest time which can be represented is in the year 292 billion, at which time our universe is predicted to not exist
92+
</ul>
93+
</section>
94+
95+
96+
<section class="slide">
97+
<h2>timezones and datetime calculations</h2>
98+
<p>
99+
<li>Calculating the time between two dates spanning timezones, daylight savings time transitions, and leap seconds is a task fraught with error
100+
<li>The <a target="_blank" href="http://en.wikipedia.org/wiki/Tz_database">Olson database</a> is a reference database of the world's timezones.
101+
<li>It can be obtained through the IANA <a target="_blank" href="http://www.iana.org/time-zones">here</a>
102+
<li>As in <a target="_blank" href="https://docs.python.org/2.7/library/datetime.html">datetime docs</a>, <blockquote>The rules for time adjustment across the world are more political than rational</blockquote>
103+
</p>
104+
</section>
105+
106+
<section class="slide">
107+
<h2>from datetime import time, date, datetime</h2>
108+
<p>The datetime object represents a specific moment in time
109+
<p>The date object represents a calendar date
110+
<p>The time object represents a time
111+
<pre><code>
112+
from datetime import datetime
113+
114+
t = datetime(2019, 11, 1)
115+
date = t.date()
116+
117+
now = datetime.now()
118+
</code></pre>
119+
</section>
120+
121+
<section class="slide">
122+
<h2>limitations of datetime</h2>
123+
<ul>
124+
<li>precision is limited to microseconds
125+
<li>time range is limited:
126+
<pre><code>
127+
In [3]: datetime.MINYEAR
128+
Out[3]: 1
129+
130+
In [4]: datetime.MAXYEAR
131+
Out[4]: 9999
132+
133+
In [5]: datetime.datetime(37337,1,1)
134+
---------------------------------------------------------------------------
135+
ValueError Traceback (most recent call last)
136+
<ipython-input-5-87a91e367d25> in <module>()
137+
138+
ValueError: year is out of range
139+
140+
In [6]: datetime.datetime(0,1,1)
141+
---------------------------------------------------------------------------
142+
ValueError Traceback (most recent call last)
143+
<ipython-input-6-7e3894d0bf49> in <module>()
144+
145+
ValueError: year is out of range
146+
147+
</code></pre>
148+
<li>If you are on a 32-bit OS and using Python pre-2.6, you will be limited to the year 2038.
149+
150+
</ul>
151+
</section>
152+
153+
<section class="slide">
154+
<h2>datetime -> string</h2>
155+
<p>
156+
<pre><code>from datetime import datetime
157+
t = datetime.now()
158+
t.isoformat()
159+
t.strftime("Date: %B %d, %Y. Time: %H:%M")
160+
</code></pre>
161+
<p>strftime passes format codes to the strftime of the platform's C library. This may not be standardized! A list of format directives is <a target="_blank" href="https://docs.python.org/2.7/library/datetime.html#strftime-strptime-behavior">here</a>
162+
<p>getting the current UNIX time :
163+
<pre><code>int(datetime.datetime.now().strftime('%s'))
164+
# in Python 3.3+:
165+
datetime.now().timestamp()
166+
</code></pre>
167+
</section>
168+
169+
<section class="slide">
170+
<h2>string -> datetime</h2>
171+
<p>datetime.strptime(string, format)
172+
<pre><code>
173+
In [88]: datetime.datetime.strptime?
174+
Type: builtin_function_or_method
175+
String form: <built-in method strptime of type object at 0x10f8536e0>
176+
Docstring: string, format -&gt; new datetime parsed from a string (like time.strptime()).
177+
178+
time_string = "2019/11/1 2300"
179+
format = "%Y/%m/%d %H%M"
180+
datetime.datetime.strptime(time_string, format)
181+
</code></pre>
182+
<p>strptime format strings use the same formatting tokens as strftime
183+
<p>If you need to parse arbitrary time strings, or don't want to maintain format strings, there is <a target="_blank" href="http://labix.org/python-dateutil">python-dateutil.parser</a>
184+
185+
</section>
186+
187+
<section class="slide">
188+
<h2>two types of datetimes - naive and aware</h2>
189+
<p>so far we haven't created any datetime objects with associated timezone information, these are known as 'naive' datetimes
190+
<p>in order to accurately represent a real time, timezone information is required
191+
<p>Some systems may expect naive times to represent UTC, others may decide on local time zone. It's usually safer to be explicit.
192+
<p>Timezone is specified with the tzinfo attribute, through the constructor: datetimes are immutable
193+
<p>Change the timezone or another attribute with the replace(*args, **kwargs) method to create a new object with all the same attributes except those specified
194+
<p>tzinfo is expected to be a subclass of datetime.tzinfo
195+
<p>However, datetime.tzinfo is an abstract base class, which means you'll need to define your own subclass (filled with peril) or install the pytz package
196+
<p>pytz is based on the <a target="_blank" href="http://en.wikipedia.org/wiki/Tz_database">Olson database</a>, a reference database of the world's timezones.
197+
</section>
198+
199+
<section class="slide">
200+
<h2>pytz</h2>
201+
<p>A list of all the timezones in pytz is available in pytz.all_timezones
202+
<p>Timezone is often specified as a UTC offset in hours, e.g. 2019-11-1T11:59-08:00. Don't use this offset directly to permanently record a user's timezone because it may change with Daylight Savings Time. Better to obtain the IANA code from the list in pytz and let datetime do the calculations.
203+
<p>
204+
<pre><code>
205+
from datetime import datetime
206+
207+
import pytz
208+
209+
t1 = datetime(2019,11,1, tzinfo=pytz.UTC)
210+
211+
us_pacific_tz = pytz.timezone('US/Pacific')
212+
t2 = datetime(2019,11,1, tzinfo=us_pacific_tz)
213+
214+
</code></pre>
215+
</section>
216+
217+
<section class="slide">
218+
<h2>time calculations</h2>
219+
<p>datetime.timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]]) represents a time difference
220+
<p>All the datetime objects overload the arithmetic operators, such that adding or subtracting dates will return a datetime.timedelta object
221+
<pre><code>In [17]: datetime.datetime.now() - datetime.datetime.now()
222+
Out[17]: datetime.timedelta(-1, 86399, 999987)
223+
</code></pre>
224+
<p>adding timedelta to a datetime will result in a new datetime
225+
<pre><code>
226+
In [19]: datetime.datetime(2019,11,1, tzinfo=pytz.UTC) + datetime.timedelta(days=1)
227+
Out[19]: datetime.datetime(2019, 11, 2, 0, 0)
228+
229+
# or create a shortcut for creating a UTC timezone aware datetime:
230+
import functools
231+
utc = functools.partial(datetime.datetime, tzinfo=pytz.UTC)
232+
utc(2019,11,1,12,0) + datetime.timedelta(days=1)
233+
</code></pre>
234+
235+
</section>
236+
<section class="slide">
237+
<h2>time calculations</h2>
238+
<p>timedelta has a few functions and properties to retrieve the results: timedelta.total_seconds(), timedelta.days, timedelta.seconds, timedelta.microseconds
239+
<p>datetimes in the calculations must be all naive or all aware
240+
<pre><code>
241+
In [35]: datetime.datetime(2019,11,1,tzinfo=pytz.UTC) - datetime.datetime(2019,10,1)
242+
---------------------------------------------------------------------------
243+
TypeError Traceback (most recent call last)
244+
<ipython-input-35-85c74b5e069b> in <module>()
245+
TypeError: can't subtract offset-naive and offset-aware datetimes
246+
</code><pre>
247+
248+
</section>
249+
250+
<section class="slide">
251+
<h2>Storing datetimes</h2>
252+
<p>Try to deal in UTC as much as possible. Do not depend on the machine's interpretation of local time.
253+
<p>For instance, datetime.now() on my Mac will return a naive datetime containing the local time. Alternatively:
254+
<pre><code>
255+
# return the current time as an aware datetime in UTC:
256+
datetime.datetime.now(pytz.UTC)
257+
# this will return a naive datetime with the current UTC time
258+
datetime.datetime.utcnow()
259+
</code></pre>
260+
<p>When storing a datetime in a database, it will need to be translated into the database's native format. Depending on the database driver, it may or may not accept datetimes. If it does, it may or may not respect the timezone information
261+
<p>Discovering the behavior is part of your database integration work
262+
</section>
263+
264+
<section class="slide">
265+
<h2>datetimes in sqlite3</h2>
266+
<p>From the <a target="_blank" href="http://www.sqlite.org/datatype3.html">sqlite3 docs</a>:
267+
<pre>
268+
Dates and times in sqlite3 are stored as TEXT, REAL, or INTEGER values
269+
270+
TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").
271+
REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic Gregorian calendar.
272+
INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.
273+
</pre>
274+
<p>So Python datetime objects must be translated to these types
275+
<p>sqlite3 has support for "adapters" and "converters" to translate types going in and out of the DB
276+
<p><a target="_blank" href="https://docs.python.org/2/library/sqlite3.html#default-adapters-and-converters">Default adapters and converters</a> are supplied for date and datetime objects
277+
<p>unfortunately, the default implementation does not handle timezone aware datetimes, but they are simply implementable
278+
<p>let's look at
279+
examples/datetime_naive_to_sqlite.py
280+
and
281+
examples/datetime_aware_to_sqlite.py
282+
</section>
283+
284+
285+
<section class="slide">
286+
<h2>The End</h2>
287+
<h2>Questions?</h2>
288+
</section>
289+
290+
291+
<!-- End slides. -->
292+
293+
294+
<!-- End slides. -->
295+
296+
<!-- Begin extension snippets. Add or remove as needed. -->
297+
298+
<!-- deck.navigation snippet -->
299+
<div aria-role="navigation">
300+
<a href="#" class="deck-prev-link" title="Previous">&#8592;</a>
301+
<a href="#" class="deck-next-link" title="Next">&#8594;</a>
302+
</div>
303+
304+
<!-- deck.status snippet -->
305+
<p class="deck-status" aria-role="status">
306+
<span class="deck-status-current"></span>
307+
/
308+
<span class="deck-status-total"></span>
309+
</p>
310+
311+
<!-- deck.goto snippet -->
312+
<!--
313+
<form action="." method="get" class="goto-form">
314+
<label for="goto-slide">Go to slide:</label>
315+
<input type="text" name="slidenum" id="goto-slide" list="goto-datalist">
316+
<datalist id="goto-datalist"></datalist>
317+
<input type="submit" value="Go">
318+
</form>
319+
-->
320+
<!-- End extension snippets. -->
321+
</div>
322+
323+
<!-- Required JS files. -->
324+
<script src="deckjs/jquery.min.js"></script>
325+
<script src="deckjs/core/deck.core.js"></script>
326+
327+
<!-- Extension JS files. Add or remove as needed. -->
328+
<script src="deckjs/extensions/menu/deck.menu.js"></script>
329+
<script src="deckjs/extensions/goto/deck.goto.js"></script>
330+
<script src="deckjs/extensions/status/deck.status.js"></script>
331+
<script src="deckjs/extensions/navigation/deck.navigation.js"></script>
332+
<script src="deckjs/extensions/scale/deck.scale.js"></script>
333+
334+
<!-- Initialize the deck. You can put this in an external file if desired. -->
335+
<script>
336+
$(function() {
337+
$.deck('.slide');
338+
});
339+
</script>
340+
</body>
341+
</html>
11.4 KB
Loading
10.8 KB
Loading
140 KB
Loading

slides_sources/source/index.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ Session 6
7575

7676
`Metaclasses <html_slides/06-metaclasses.html>`_
7777

78-
.. - datetime, time, pytz
78+
`datetime <html_slides/06-datetime.html>`_
79+
7980
.. - functools
8081
.. - itertools
8182
.. - Beautiful idiomatic code

0 commit comments

Comments
 (0)