diff --git a/pytoml/parser.py b/pytoml/parser.py
index 4dce4b336ad552e8f71bcbd0cbe431cf15bedf39..189589e0c1585fbc377978114a13918f61c8be95 100644
--- a/pytoml/parser.py
+++ b/pytoml/parser.py
@@ -1,4 +1,4 @@
-import string, re, sys
+import string, re, sys, datetime
 from .core import TomlError
 
 class _CharSource:
@@ -63,6 +63,8 @@ if sys.version_info[0] == 2:
 else:
     _chr = chr
 
+_datetime_re = re.compile(r'(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d+)?(?:Z|([+-]\d{2}):(\d{2}))')
+
 def _lex(s, filename):
     src = _CharSource(s.replace('\r\n', '\n'), filename)
     def is_id(ch):
@@ -94,9 +96,8 @@ def _lex(s, filename):
             src.error('invalid_escape_sequence')
         return res
 
-    datetime_re = re.compile(r'\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})')
     def consume_datetime():
-        m = datetime_re.match(src.tail)
+        m = _datetime_re.match(src.tail)
         if not m:
             return False
         src.next(len(m.group(0)))
@@ -251,6 +252,36 @@ class _TokSource:
     def error(self, message):
         raise TomlError(message, self.pos[0][0], self.pos[0][1], self._filename)
 
+def _translate_datetime(s):
+    match = _datetime_re.match(s)
+    re.compile(r'(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d+)?(?:Z|([+-]\d{2}):(\d{2}))')
+
+    y = int(match.group(1))
+    m = int(match.group(2))
+    d = int(match.group(3))
+    H = int(match.group(4))
+    M = int(match.group(5))
+    S = int(match.group(6))
+
+    if match.group(7) is not None:
+        micro = float(match.group(7))
+    else:
+        micro = 0
+
+    if match.group(8) is not None:
+        tzh = int(match.group(8))
+        tzm = int(match.group(9))
+        if tzh < 0:
+            tzm = -tzm
+        offs = tzh * 60 + tzm
+    else:
+        offs = 0
+
+    dt = datetime.datetime(y, m, d, H, M, S, int(micro * 1000000),
+        _TimeZone(datetime.timedelta(0, offs*60)))
+
+    return dt
+
 def _translate_literal(type, text):
     if type == 'bool':
         return text == 'true'
@@ -261,7 +292,7 @@ def _translate_literal(type, text):
     elif type == 'str':
         return text
     elif type == 'datetime':
-        return text
+        return _translate_datetime(text)
 
 def _translate_array(a):
     return a
@@ -403,3 +434,24 @@ def loads(s, translate_literal=_translate_literal, translate_array=_translate_ar
         return scope
 
     return merge_tables(root, tables)
+
+class _TimeZone(datetime.tzinfo):
+    def __init__(self, offset):
+        self._offset = offset
+
+    def utcoffset(self, dt):
+        return self._offset
+
+    def dst(self, dt):
+        return None
+
+    def tzname(self, dt):
+        m = self._offset.total_seconds() // 60
+        if m < 0:
+            res = '-'
+            m = -m
+        else:
+            res = '+'
+        h = m // 60
+        m = m - h * 60
+        return '{}{:.02}{:.02}'.format(res, h, m)