Skip to content

Commit 0eece6c

Browse files
committed
[ExecuteTime] fix timezone handling using notebook funtions
1 parent 117b523 commit 0eece6c

File tree

2 files changed

+26
-9
lines changed

2 files changed

+26
-9
lines changed

src/jupyter_contrib_nbextensions/nbconvert_support/execute_time.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66

77
from nbconvert.preprocessors.execute import ExecutePreprocessor
88

9+
try:
10+
# notebook >= 5.0.0-rc1
11+
import notebook._tz as nbtz
12+
except ImportError:
13+
# notebook < 5.0.0-rc1
14+
import notebook.services.contents.tz as nbtz
15+
916

1017
class ExecuteTimePreprocessor(ExecutePreprocessor):
1118
"""
@@ -20,13 +27,13 @@ def run_cell(self, cell, cell_index, *args, **kwargs):
2027
if exec_reply.get('msg_type', '') == 'execute_reply':
2128
ets = cell.setdefault('metadata', {}).setdefault('ExecuteTime', {})
2229
if 'started' in exec_reply.get('metadata', {}):
23-
# started value should is already a string
30+
# started value should is already a string, so don't isoformat
2431
ets['start_time'] = exec_reply['metadata']['started']
2532
else:
2633
# attempt to fallback to datetime obj for execution request msg
27-
ets['start_time'] = exec_reply.get('parent_header', {}).get(
28-
'date', before).isoformat()
29-
ets['end_time'] = (exec_reply.get('header', {}).get(
30-
'date', None) or datetime.utcnow()).isoformat()
34+
ets['start_time'] = nbtz.isoformat(
35+
exec_reply.get('parent_header', {}).get('date', before))
36+
ets['end_time'] = nbtz.isoformat(
37+
exec_reply.get('header', {}).get('date') or nbtz.utcnow())
3138

3239
return exec_reply, outs

tests/test_preprocessors.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# -*- coding: utf-8 -*-
22

3-
import datetime
43
import json
54
import os
5+
import re
66

77
import nbformat.v4 as nbf
88
from nbconvert import LatexExporter, NotebookExporter, RSTExporter
@@ -113,6 +113,16 @@ def test_preprocessor_svg2pdf():
113113
'exported pdf should be referenced in exported notebook')
114114

115115

116+
def _normalize_iso8601_timezone(timestamp_str):
117+
# Zulu -> +00:00 offset
118+
timestamp_str = re.sub(r'Z$', r'+00:00', timestamp_str)
119+
# HH -> HH:00 offset
120+
timestamp_str = re.sub(r'([+-]\d\d)$', r'\1:00', timestamp_str)
121+
# HHMM -> HH:MM offset
122+
timestamp_str = re.sub(r'([+-]\d\d):?(\d\d)$', r'\1:\2', timestamp_str)
123+
return timestamp_str
124+
125+
116126
def test_preprocessor_execute_time():
117127
"""Test ExecuteTime preprocessor."""
118128
# check import shortcut
@@ -133,6 +143,6 @@ def test_preprocessor_execute_time():
133143
assert_in('start_time', etmd)
134144
assert_in('end_time', etmd)
135145
assert_greater_equal(
136-
datetime.datetime.utcfromtimestamp(etmd['end_time']),
137-
datetime.datetime.utcfromtimestamp(etmd['start_time']),
138-
'end_time should be after start time')
146+
_normalize_iso8601_timezone(etmd['end_time']),
147+
_normalize_iso8601_timezone(etmd['start_time']),
148+
'end_time should not be before start_time')

0 commit comments

Comments
 (0)