Skip to content

Commit 0711750

Browse files
committed
Improves timezone switching performances.
1 parent b735ead commit 0711750

File tree

12 files changed

+154
-122
lines changed

12 files changed

+154
-122
lines changed
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <Python.h>
44
#include <stdint.h>
5+
#include <datetime.h>
56

67
#ifndef PyVarObject_HEAD_INIT
78
#define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
@@ -213,7 +214,7 @@ static PyMethodDef localtime_methods[] = {
213214
#if PY_MAJOR_VERSION >= 3
214215
static struct PyModuleDef moduledef = {
215216
PyModuleDef_HEAD_INIT,
216-
"_local_time",
217+
"_helpers",
217218
NULL,
218219
-1,
219220
localtime_methods,
@@ -232,7 +233,7 @@ moduleinit(void)
232233
#if PY_MAJOR_VERSION >= 3
233234
module = PyModule_Create(&moduledef);
234235
#else
235-
module = Py_InitModule3("_local_time", localtime_methods, NULL);
236+
module = Py_InitModule3("_helpers", localtime_methods, NULL);
236237
#endif
237238

238239
if (module == NULL)
@@ -242,12 +243,12 @@ moduleinit(void)
242243
}
243244

244245
#if PY_MAJOR_VERSION < 3
245-
PyMODINIT_FUNC init_local_time(void)
246+
PyMODINIT_FUNC init_helpers(void)
246247
{
247248
moduleinit();
248249
}
249250
#else
250-
PyMODINIT_FUNC PyInit__local_time(void)
251+
PyMODINIT_FUNC PyInit__helpers(void)
251252
{
252253
return moduleinit();
253254
}

pendulum/_extensions/tz/__init__.py

Whitespace-only changes.

pendulum/helpers.py

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

3-
from .constants import SECONDS_PER_HOUR, SECONDS_PER_MINUTE
4-
5-
6-
def day_ordinal(y, m, d):
7-
"""
8-
Returns the number of days before/after 1970-01-01.
9-
10-
:rtype: integer
11-
"""
12-
if m <= 2:
13-
y -= 1
14-
15-
era = (y if y >= 0 else y - 399) // 400
16-
yoe = y - era * 400
17-
doy = (153 * (m + (-3 if m > 2 else 9)) + 2) // 5 + d - 1
18-
doe = yoe * 365 + yoe // 4 - yoe // 100 + doy
19-
20-
return era * 146097 + doe - 719468
21-
22-
23-
def timestamp(year, month, day, hour, minute, second, microsecond, tzinfo):
24-
days_in_seconds = day_ordinal(year, month, day) * 86400
25-
26-
return (
27-
days_in_seconds
28-
+ hour * SECONDS_PER_HOUR
29-
+ minute * SECONDS_PER_MINUTE
30-
+ second
31-
+ microsecond / 1e6
32-
- tzinfo.offset
33-
)
3+
try:
4+
from ._extensions._helpers import local_time
5+
except ImportError:
6+
from ._extensions.helpers import local_time

pendulum/pendulum.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
from .tz import Timezone, UTC, FixedTimezone, local_timezone
1818
from .tz.timezone_info import TimezoneInfo
1919
from .formatting import FORMATTERS
20-
from .helpers import timestamp
2120
from ._compat import basestring
2221
from .constants import (
2322
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
@@ -209,7 +208,7 @@ def instance(cls, dt, tz=UTC):
209208
tz = dt.tzinfo or tz
210209

211210
# Checking for pytz/tzinfo
212-
if isinstance(tz, datetime.tzinfo) and not isinstance(tz, TimezoneInfo):
211+
if isinstance(tz, datetime.tzinfo) and not isinstance(tz, (Timezone, TimezoneInfo)):
213212
# pytz
214213
if hasattr(tz, 'localize'):
215214
tz = tz.zone
@@ -279,7 +278,7 @@ def now(cls, tz=None):
279278
if tz is not None and tz != cls._test_now.timezone:
280279
test_instance = test_instance.in_timezone(tz)
281280

282-
return test_instance.copy()
281+
return test_instance
283282

284283
if tz is None or tz == 'local':
285284
dt = datetime.datetime.now()
@@ -574,11 +573,7 @@ def timestamp(self):
574573
@property
575574
def float_timestamp(self):
576575
if self._timestamp is None:
577-
self._timestamp = timestamp(
578-
self._year, self._month, self._day,
579-
self._hour, self._minute, self._second, self._microsecond,
580-
self._tzinfo
581-
)
576+
self._timestamp = (self._datetime - self._EPOCH).total_seconds()
582577

583578
return self._timestamp
584579

pendulum/tz/loader.py

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from struct import unpack, calcsize
99

1010
from .. import _compat
11-
from .local_time import local_time
11+
from ..helpers import local_time
1212
from .transition import Transition
1313
from .transition_type import TransitionType
1414

@@ -99,23 +99,27 @@ def _load(cls, fp):
9999
# calculate transition info
100100
transitions = tuple()
101101
for i in range(len(transition_times)):
102-
transition_type = transition_types[lindexes[i]]
102+
transition_type_index = lindexes[i]
103103

104104
if i == 0:
105-
pre_transition_type = transition_types[lindexes[i]]
105+
pre_transition_type_index = lindexes[i]
106106
else:
107-
pre_transition_type = transition_types[lindexes[i - 1]]
107+
pre_transition_type_index = lindexes[i - 1]
108108

109-
pre_time = datetime(*local_time(transition_times[i],
110-
pre_transition_type.utc_offset))
111-
time = datetime(*local_time(transition_times[i],
112-
transition_type.utc_offset))
109+
pre_time = datetime(
110+
*local_time(transition_times[i],
111+
transition_types[pre_transition_type_index].utc_offset)
112+
)
113+
time = datetime(
114+
*local_time(transition_times[i],
115+
transition_types[transition_type_index].utc_offset)
116+
)
113117
tr = Transition(
114118
transition_times[i],
115-
transition_type,
119+
transition_type_index,
116120
pre_time,
117121
time,
118-
pre_transition_type
122+
pre_transition_type_index
119123
)
120124

121125
transitions += (tr,)
@@ -129,7 +133,7 @@ def _load(cls, fp):
129133
while index != 0 and transition_types[index].is_dst:
130134
index -= 1
131135

132-
while index != len(transitions) and transition_types[index].is_dst:
136+
while index != len(transition_types) and transition_types[index].is_dst:
133137
index += 1
134138

135139
if index != len(transitions):
@@ -138,5 +142,6 @@ def _load(cls, fp):
138142
return (
139143
transitions,
140144
transition_types,
141-
transition_types[default_transition_type_index]
145+
default_transition_type_index,
146+
tuple(map(lambda tr: datetime.utcfromtimestamp(tr.unix_time), transitions))
142147
)

pendulum/tz/local_time.py

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)