sdispater / pendulum Goto Github PK
View Code? Open in Web Editor NEWPython datetimes made easy
Home Page: https://pendulum.eustace.io
License: MIT License
Python datetimes made easy
Home Page: https://pendulum.eustace.io
License: MIT License
Currently, intervals are broken down into microseconds, seconds and days in Pendulum.
However, this might be not precise enough if you calculate with months. Adding months to a Pendulum
instance is already supported by add(months=n)
(with precise calculations), so we should be able to store months in Interval
instances too (and calculate with them).
This would also allow a loss-free representation of the ISO8601 duration format in a Duration
instance, and conversions from and to it ;-)
Of course, there might be some corner cases that need to be considered - like what happens when 1 month is compared with 30 days.
I'd suggest to peek at the PostgreSQL interval
implementation (with added microseconds):
Internally interval values are stored as months, days, and seconds. This is done because the number of days in a month varies, and a day can have 23 or 25 hours if a daylight savings time adjustment is involved.
using the following code: ** Note this was tested on 11/5/2016, so result should be 15, instead it is returning 16
from pendulum import Pendulum as p
d1 = p(2000,11,20)
diff = d1.diff()
diff.in_years()
16
Trial and error shows that it reported 15 when I set the date to 2000,11,25 meaning that it was 10 days off.
add()/sub()
, start_of()/end_of()
methods and fluent setters should return a new instance of Pendulum
rather than modify it in-place.
Hi, need to writing python supporting version in README.md or Official Site.
python 2.7 and 3.5
Currently, when using the start_of()
/last_of()
methods, timezone transitions are not properly applied:
import pendulum
dt = pendulum.create(2013, 8, 1, 0, 0, 0, 0, 'Europe/Paris')
# <Pendulum [2013-08-01T00:00:00+02:00]>
dt.start_of('year')
# <Pendulum [2013-01-01T00:00:00+02:00]>
# Should be <Pendulum [2013-01-01T00:00:00+01:00]>
Does pendulum aim for full api compatibility with datetime.datetime? It looks like pendulum's timestamp
is a property, while datetime's timestamp
is a function:
from datetime import datetime, timezone
import pendulum
d = datetime.now(timezone.utc)
p = pendulum.now(timezone.utc)
d.timestamp
# <function datetime.timestamp>
d.timestamp()
# 1478671704.494979
p.timestamp
# 1478671596
I really wanted to use pendulum under the covers and expose the interface as datetime, but this is a property I expect users to depend on having the usual signature.
When a negative interval only has one (-1) unit the unit word is in the plural form. It should be in singular form.
Sample code to reproduce error:
$> python
import pendulum
tz = pendulum.timezone('Europe/Paris')
tz.utcoffset(pendulum.utcnow())
Exception:
Traceback (most recent call last):
File "", line 1, in
File "/Users/thomaswilgenbus/.pyenv/versions/tex-connector-acs/lib/python2.7/site-packages/pendulum/tz/timezone.py", line 283, in utcoffset
return dt.adjusted_offset
AttributeError: 'Pendulum' object has no attribute 'adjusted_offset'
I like the in_words()/str() behavior of Interval objects. However I sometimes have intervals that are sub-second and it would be nice if those resolved to something like '25ms' instead of just an empty string ''.
I could submit a pull request with such a change if you like.
Suppose I have some existing datetime.datetime
objects, is their way to convert them to Pendulum
?
pendulum unable to create any date time instances due to unix_time not being loaded correctly on windows, seems okay under unix.
Win7 x64 Ent
(.env) C:\projects\scripts\python\timescamp (develop)
λ pip freeze
pendulum==0.6.1
python-dateutil==2.5.3
pytz==2016.6.1
requests==2.11.1
six==1.10.0
tzlocal==1.2.2
(.env) C:\projects\scripts\python\timescamp (develop)
λ python
Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:54:25) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import pendulum
>>> pendulum.now()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\projects\scripts\python\timescamp\.env\lib\site-packages\pendulum\pendulum.py", line 287, in now
return cls.instance(dt, tz)
File "C:\projects\scripts\python\timescamp\.env\lib\site-packages\pendulum\pendulum.py", line 223, in instance
tzinfo=tz
File "C:\projects\scripts\python\timescamp\.env\lib\site-packages\pendulum\pendulum.py", line 173, in __init__
self._tz = self._safe_create_datetime_zone(tzinfo)
File "C:\projects\scripts\python\timescamp\.env\lib\site-packages\pendulum\pendulum.py", line 100, in _safe_create_datetime_zone
return cls._local_timezone()
File "C:\projects\scripts\python\timescamp\.env\lib\site-packages\pendulum\pendulum.py", line 119, in _local_timezone
return local_timezone()
File "C:\projects\scripts\python\timescamp\.env\lib\site-packages\pendulum\tz\__init__.py", line 25, in local_timezone
return LocalTimezone.get()
File "C:\projects\scripts\python\timescamp\.env\lib\site-packages\pendulum\tz\local_timezone.py", line 29, in get
cls._cache = Timezone.load(cls.get_local_tz_name())
File "C:\projects\scripts\python\timescamp\.env\lib\site-packages\pendulum\tz\timezone.py", line 67, in load
utc_transition_times) = Loader.load(name)
File "C:\projects\scripts\python\timescamp\.env\lib\site-packages\pendulum\tz\loader.py", line 37, in load
return cls._load(f)
File "C:\projects\scripts\python\timescamp\.env\lib\site-packages\pendulum\tz\loader.py", line 122, in _load
pre_transition_type_index
File "C:\projects\scripts\python\timescamp\.env\lib\site-packages\pendulum\tz\transition.py", line 44, in __init__
self._utc_time = datetime.utcfromtimestamp(unix_time)
OSError: [Errno 22] Invalid argument
Synology x86_64 (unix)
(test) scott@pandora:~/scripts/python/pendulum$ pip freeze
pendulum==0.6.1
python-dateutil==2.5.3
pytz==2016.6.1
six==1.10.0
tzlocal==1.2.2
(test) scott@pandora:~/scripts/python/pendulum$ python3
Python 3.5.1 (default, Feb 23 2016, 17:47:45)
[GCC 4.9.3 20150311 (prerelease)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pendulum
>>> pendulum.now()
<Pendulum [2016-09-21T09:33:08.239546+10:00]>
>>>
Using a lib I received a datetime
object I wanted to convert to pendulum, so I did the following and it failed because of the tzinfo
not being a string but an UTC
instance:
>>> pendulum.instance(repo.updated_at)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "…/pendulum/pendulum.py", line 205, in instance
tzinfo=tz
File "…/pendulum/pendulum.py", line 180, in __init__
self._tz = self._safe_create_datetime_zone(tzinfo)
File "…/pendulum/pendulum.py", line 118, in _safe_create_datetime_zone
tz = cls._timezone(obj)
File "…/pendulum/pendulum.py", line 148, in _timezone
return Timezone.load(zone)
File "…/pendulum/tz/timezone.py", line 44, in load
if name.upper() == 'UTC':
AttributeError: 'UTC' object has no attribute 'upper'
>>> repo.updated_at
datetime.datetime(2016, 10, 16, 10, 24, 5, tzinfo=UTC())
As a workaround I'm doing:
>>> pendulum.parse(repo.updated_at.isoformat())
<Pendulum [2016-10-16T10:24:05+00:00]>
>>>
but it sucks to be using a string as an intermediate format, when we could convert directly 😖
While investigating the possibility of porting an existing project from pytz
to pendulum
I noticed some of our tests failing when instantiating certain timezones, for example CET
, EET
.
I'm running the tests on macOS 10.12.1 with Python 3.5.2 (macports).
In [1]: import pytz, pendulum
In [2]: pytz.timezone('CET')
Out[2]: <DstTzInfo 'CET' CET+1:00:00 STD>
In [3]: pendulum.timezone('CET')
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-3-b4d458d3915f> in <module>()
----> 1 pendulum.timezone('CET')
.../lib/python3.5/site-packages/pendulum/tz/__init__.py in timezone(name)
14 :rtype: Timezone
15 """
---> 16 return Timezone.load(name)
17
18
.../lib/python3.5/site-packages/pendulum/tz/timezone.py in load(cls, name)
65 transition_types,
66 default_transition_type_index,
---> 67 utc_transition_times) = Loader.load(name)
68
69 zone = cls(name,
.../lib/python3.5/site-packages/pendulum/tz/loader.py in load(cls, name)
35 try:
36 with pytz.open_resource(name) as f:
---> 37 return cls._load(f)
38 except _compat.FileNotFoundError:
39 raise ValueError('Unknown timezone [{}]'.format(name))
.../lib/python3.5/site-packages/pendulum/tz/loader.py in _load(cls, fp)
133 index = 0
134 if transition_types[0].is_dst:
--> 135 index = transition_types.index(transitions[0].transition_type)
136 while index != 0 and transition_types[index].is_dst:
137 index -= 1
AttributeError: 'Transition' object has no attribute 'transition_type'
As Django need a datetime object to be stored into a DateTimeField, I'm using 'getattribute('datetime')' to get the datetime object now, any better solutions?
After having defined p1
(from now until tomorrow):
>>> now = pendulum.utcnow()
>>> p1 = pendulum.Period(utcnow, now.tomorrow())
I can ask whether a specific Pendulum
object is inside p1
:
>>> now.add(hours=1) in p1
True
>>> now.yesterday() in p1
False
But when a Pendulum
object is outside a given Period
, I can't ask whether its before or after the Period
:
>>> now.yesterday() < p1
TypeError: unorderable types: Pendulum() < Period()
Of course, I could compare p1.start
and p1.end
, but this would make it more convenient.
Affects v0.6.0. Pull request coming very shortly to fix.
Still on that Debian Wheezy (old-stable), I get a strange behaviour:
% python3
Python 3.2.3 (default, Feb 20 2013, 17:02:41)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pendulum
>>> pendulum.parse('2016-09-04T15:30:09+02:00')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.2/dist-packages/pendulum/pendulum.py", line 242, in parse
tzinfo=tz
File "/usr/local/lib/python3.2/dist-packages/pendulum/pendulum.py", line 184, in __init__
hour, minute, second, microsecond
File "/usr/local/lib/python3.2/dist-packages/pendulum/tz/timezone.py", line 80, in convert
return dt.__class__(*converted)
ValueError: day is out of range for month
>>>
% python
Python 2.7.3 (default, Jun 20 2016, 16:18:47)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pendulum
>>> pendulum.parse('2016-09-04T15:30:09+02:00')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/pendulum/pendulum.py", line 242, in parse
tzinfo=tz
File "/usr/local/lib/python2.7/dist-packages/pendulum/pendulum.py", line 184, in __init__
hour, minute, second, microsecond
File "/usr/local/lib/python2.7/dist-packages/pendulum/tz/timezone.py", line 80, in convert
return dt.__class__(*converted)
ValueError: day is out of range for month
>>>
This is a quite weird behaviour, on BOTH python versions. Obviously, exact same code works fine on another computer running python3.5 and debian jessie.
I found a curious behavior when parsing timestamps where the microsecond value is off by one depending on the timezone used.
As a minimal example I'm attempting to parse the string 2016-11-12T02:09:39.594000
.
Parsing with the default timezone works as excepted:
In [3]: Pendulum.parse('2016-11-12T02:09:39.594000').microsecond
Out[3]: 594000
Using a particular timezone shows the off-by-one difference.
In [4]: Pendulum.parse('2016-11-12T02:09:39.594000', 'America/Panama').microsecond
Out[4]: 593999
Several timezones (but not all by any means) have this behavior
In [5]: len(pytz.common_timezones)
Out[5]: 436
In [6]: len({name for name in pytz.common_timezones if Pendulum.parse('2016-11-12T02:09:39.594000', name).microsecond != 594000})
Out[6]: 182
I don't think anything in the particular choice of time or timezone should result in a difference of a single microsecond?
As you know,
A week can start either on a Monday or Sunday (maybe even other days).
Python has that feature already done with strftime
:
%U
Sunday as the first day of the week.%W
Monday as the first day of the week.dt = datetime.datetime(2016, 10, 30)
print(dt.strftime("%U"))
'44'
print(dt.strftime("%W"))
'43'
Pendulum's week_of_year
currently uses datetime's isocalandar
(docs "week starts on a Monday and ends on a Sunday").
There needs to be a way to have both Sunday and Monday as an option because its not consistent across software (e.g. MySQL which uses Sunday). and also, why not have it if python supports it.
I would submit a pull request myself, but this is a design problem because its a property and not a function, so no args possible.
What do you think?
I'm a bit confused about the implementation of Pendulum._timezone
. What I assume would happen if I change only the timezone is that the time and date remain the same but the timezone and offset would change. I'm not sure whether this is a bug or not, but changing the timezone using Pendulum.timezone_
does not change the datetime.tzinfo
and therefore not the offset. It makes Pendulum.timezone
and datetime.tzinfo
out of sync.
>>> now = pendulum.now()
>>> now
# <Pendulum [2016-11-02T00:30:16.246721+01:00]>
>>> utc_ = now.timezone_('UTC')
>>> utc_
# <Pendulum [2016-11-02T00:30:16.246721+01:00]>
>>> utc_.tzinfo
# <TimezoneInfo [Europe/Brussels, 3600, False]>
>>> utc_.timezone
# <Timezone [UTC]>
>>> utc = now.in_timezone('UTC')
>>> utc
# <Pendulum [2016-11-01T23:30:16.246721+00:00]>
>>> utc.tzinfo
# <TimezoneInfo [UTC, 0, False]>
>>> utc.timezone
# <Timezone [UTC]>
Expected behaviour:
>>> now = pendulum.now()
>>> now
# <Pendulum [2016-11-02T00:34:59.665176+01:00]>
>>> now.timezone_('UTC')
# <Pendulum [2016-11-02T00:34:59.665176+00:00]>
Is this a bug in Pendulum or intended behaviour? Could you perhaps explain to me what the use case would be if it is intended behaviour?
Hi,
I was just trying to localize a datetime to the correct timezone and I noticed it is not working as expected:
>>> import pendulum
>>> pendulum.create(2016, 4, 15, 0, 0 , 0, 0)
<Pendulum [2016-04-15T00:00:00+00:00]> # so far, so good
>>> pendulum.create(2016, 4, 15, 0, 0 , 0, 0).timezone_('America/Sao_Paulo')
<Pendulum [2016-04-15T00:00:00+00:00]> # oops, should've been <Pendulum [2016-04-15T00:00:00-03:00]>
I am missing something or this is really an undesired behavior?
How can I get the age in this format: 32 years 3 months 45 days ?
I try to use:
age = pendulum.from_date(self.birth.year, self.birth.month, self.birth.day)
Currently, Pendulum automatically normalizes the datetime on creation to apply any DST transition:
import pendulum
pendulum.create(2013, 3, 31, 2, 30, 0, 0, 'Europe/Paris')
# <Pendulum [2013-03-31T03:30:00+02:00]>
However, it might be confusing, so the introduction of an option to control this behavior could prove useful:
import pendulum
pendulum.set_transition_rule(pendulum.PRE_TRANSITION)
pendulum.create(2013, 3, 31, 2, 30, 0, 0, 'Europe/Paris')
# <Pendulum [2013-03-31T02:30:00+01:00]>
pendulum.set_transition_rule(pendulum.TRANSITION_ERROR)
pendulum.create(2013, 3, 31, 2, 30, 0, 0, 'Europe/Paris')
# NonExistingTime: The requested datetime does not exist.
pendulum.create(2013, 10, 27, 2, 30, 0, 0, 'Europe/Paris')
# AmbiguousTime: The requested datetime is ambiguous.
The default behavior would be the same as the existing one (POST_TRANSITION).
Note that when shifting time, the normalization will always occur regardless of the option.
It would be very useful if the .start_of()
, .end_of()
and Period.range()
methods could support arbitrary units (e.g. things like 15 minutes
, 5 seconds
etc.)
A possible API for this would be to allow the those methods to receive Interval
objects in addition to the predefined string names.
During my testing test_construct.ConstructTest.test_now
constantly failed. I assume it's because I have the same timezone that is being inputted and so the hour in Paris and my PC is gonna be the same. I haven't looked further in it during my work on #48.
I don't quite understand why singular & plural are seperated (year/years, month/months ...)
I think integration function is more useful.
# for example, add_year() -> add_years().
from pendulum import Pendulum, Interval
p = Pendulum.now()
p2 = p + Interval(minutes=15)
assert p == p2
The reason is that Pendulum.add_timedelta()
assumes a default python timedelta
object and can't cope with the non-normalizing behavior of Interval
.
TypeError Traceback (most recent call last)
/usr/local/lib/python2.7/dist-packages/django/core/management/commands/shell.pyc in <module>()
----> 1 pendulum.parse('2015-03-08T01:00:00-06:00').add(weeks=1)
/usr/local/lib/python2.7/dist-packages/pendulum/pendulum.pyc in add(self, years, months, weeks, days, hours, minutes, seconds, microseconds)
1414
1415 dt = self._datetime + delta
-> 1416 dt = self._tz.convert(dt)
1417
1418 return self.instance(dt)
/usr/local/lib/python2.7/dist-packages/pendulum/tz/timezone.pyc in convert(self, dt, dst_rule)
91
92 else:
---> 93 converted = self._convert(dt)
94
95 if not isinstance(converted, tuple):
/usr/local/lib/python2.7/dist-packages/pendulum/tz/timezone.pyc in _convert(self, dt)
216 )
217
--> 218 return dt.astimezone(self)
219
220 def _to_local_time(self, unix_time, transition_type_index):
/usr/local/lib/python2.7/dist-packages/pendulum/tz/timezone.pyc in fromutc(self, dt)
298 dt = dt.replace(tzinfo=None)
299
--> 300 idx = self._find_utc_index(dt)
301 tr = self._transitions[idx]
302 tzinfo = self._tzinfos[tr._transition_type_index]
/usr/local/lib/python2.7/dist-packages/pendulum/tz/timezone.pyc in _find_utc_index(self, dt)
315 lo = hint[1]
316
--> 317 idx = max(0, bisect_right(self._utc_transition_times, dt, lo, hi) - 1)
318
319 self._local_hint['_utc'] = (dt, idx)
TypeError: can't compare datetime.datetime to int
add_xxx()
, sub_xxx()
)diff_for_humans()
for instance)import pendulum
pendulum.now()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.5/site-packages/pendulum/pendulum.py", line 274, in now
return cls.instance(dt, tz)
File "/usr/lib/python3.5/site-packages/pendulum/pendulum.py", line 205, in instance
tzinfo=tz
File "/usr/lib/python3.5/site-packages/pendulum/pendulum.py", line 180, in __init__
self._tz = self._safe_create_datetime_zone(tzinfo)
File "/usr/lib/python3.5/site-packages/pendulum/pendulum.py", line 111, in _safe_create_datetime_zone
return cls._local_timezone()
File "/usr/lib/python3.5/site-packages/pendulum/pendulum.py", line 130, in _local_timezone
return local_timezone()
File "/usr/lib/python3.5/site-packages/pendulum/tz/__init__.py", line 25, in local_timezone
return LocalTimezone.get()
File "/usr/lib/python3.5/site-packages/pendulum/tz/local_timezone.py", line 25, in get
name = cls.get_local_tz_name()
File "/usr/lib/python3.5/site-packages/pendulum/tz/local_timezone.py", line 60, in get_local_tz_name
return getattr(cls, 'get_tz_name_for_{}'.format(os))()
File "/usr/lib/python3.5/site-packages/pendulum/tz/local_timezone.py", line 157, in get_tz_name_for_unix
return Timezone.load(tzpath)
File "/usr/lib/python3.5/site-packages/pendulum/tz/timezone.py", line 50, in load
default_transition_type) = Loader.load(name)
File "/usr/lib/python3.5/site-packages/pendulum/tz/loader.py", line 36, in load
with pytz.open_resource(name) as f:
File "/usr/lib/python3.5/site-packages/pytz-2016.6.1-py3.5.egg/pytz/__init__.py", line 96, in open_resource
File "/usr/lib/python3.5/site-packages/pkg_resources/__init__.py", line 1208, in resource_stream
self, resource_name
File "/usr/lib/python3.5/site-packages/pkg_resources/__init__.py", line 1486, in get_resource_stream
return io.BytesIO(self.get_resource_string(manager, resource_name))
File "/usr/lib/python3.5/site-packages/pkg_resources/__init__.py", line 1489, in get_resource_string
return self._get(self._fn(self.module_path, resource_name))
File "/usr/lib/python3.5/site-packages/pkg_resources/__init__.py", line 1562, in _get
return self.loader.get_data(path)
OSError: [Errno 0] Error: 'pytz/zoneinfo/usr/share/zoneinfo/Europe/Bratislava'
After reverting back to 0.5.2 it works as expected:
import pendulum
pendulum.now()
<Pendulum [2016-08-31T06:17:32.144487+02:00]>
I propose to add some very simple default intervals to the library.
I propose to add an interval called day
, hour
, minute
and so on to the lib. That way you can do stuff like this:
import pendulum as pm
now_in_paris = pm.now('Europe/Paris')
tomorrow_in_paris = now_in_paris + pm.day
next_week_in_paris = now_in_paris + 7*pm.day
It's inspired by the Ruby way of adding dates according to this comment, but modified to be Pythonic: https://news.ycombinator.com/item?id=12301965
I wouldn't mind creating a pull request for this if you agree that this would be nice to have.
Today, Pendulum objects have the weekday
and the isoweekday
methods that shows the first 2 lines of this Wikipedia table:
Line M T W T F S S
1 1 2 3 4 5 6 7
2 0 1 2 3 4 5 6
3 2 3 4 5 6 7 1
4 1 2 3 4 5 6 0
About each line, Wikipedia tells us:
%_ISODOWI%
, %@ISODOWI[]%
(4DOS); DAYOFWEEK()
(HP Prime)%NDAY OF WEEK%
(NetWare, DR-DOS); %_DOWI%
, %@DOWI[]%
(4DOS)I think it would be useful more 2 methods, namely dosweekday
and hpweekday
, including that 3rd and 4th lines. Usually Brazilian people think on the weekday as the dosweekday
(3rd line), since the day names follows our numbering system (e.g. "second day" = "segundo dia", and "monday" = "segunda").
I know that it's actually possible with things like dt.isoweekday() % 7 + 1
(3rd line), but maybe that could be part of the library. =)
>>> Pendulum.now() == ''
...
ValueError: String does not contain a date.
>>> Pendulum.now() == 'aa'
...
ValueError: Unknown string format
This is also the case when checking if a Pendulum
object is in a list:
>>> Pendulum.now() in ['']
...
ValueError: String does not contain a date.
>>> '' in [Pendulum.now()]
...
ValueError: String does not contain a date.
>>> Pendulum.now() in ['aa']
...
ValueError: Unknown string format
>>> 'aa' in [Pendulum.now()]
...
ValueError: Unknown string format
This prohibits the use of Pendulum
objects in collections. A possible solution is to catch ValueErrors in _get_datetime
when the instance is a string. You have a better understanding of the internals of Pendulum than I do, perhaps you think it's a better idea to catch exceptions in the comparison methods and return False
in case of an exception.
Hi, care to add a comparison / differentiation to https://github.com/crsmithdev/arrow to the readme?
I have a small library written in Kotlin similar to Pendulum's Period functionality and added an exclusion function. It would 'remove' and edit periods from a list of periods based on the period that needs to be excluded. I would love to submit a PR and add the feature to Pendulum. Here's an example:
periods = [
Period(
start=yesterday,
end=tomorrow
)
]
excluded_periods = Period.exclude(
periods=periods,
exclusion=Period(
start=today,
end=tomorrow
)
)
[
Period(
start=yesterday,
end=today
)
]
Could we perhaps talk on the Slack you mentioned in #42? Send me a message on Twitter for my email address.
Pendulum package is missing when installed with pip install -t
~/tmp> pip install -t lib pendulum
Collecting pendulum
Collecting pytz (from pendulum)
Using cached pytz-2016.6.1-py2.py3-none-any.whl
Collecting tzlocal (from pendulum)
Collecting python-dateutil (from pendulum)
Using cached python_dateutil-2.5.3-py2.py3-none-any.whl
Collecting six>=1.5 (from python-dateutil->pendulum)
Using cached six-1.10.0-py2.py3-none-any.whl
Installing collected packages: pytz, tzlocal, six, python-dateutil, pendulum
Successfully installed pendulum python-dateutil-2.5.3 pytz-2016.6.1 six-1.10.0 tzlocal-1.2.2
~/tmp> ls -l lib/
total 64
drwxrwxr-x 1 lauris lauris 276 Aug 17 17:41 dateutil
drwxrwxr-x 1 lauris lauris 154 Aug 17 17:41 python_dateutil-2.5.3.dist-info
drwxrwxr-x 1 lauris lauris 272 Aug 17 17:41 pytz
drwxrwxr-x 1 lauris lauris 154 Aug 17 17:41 pytz-2016.6.1.dist-info
drwxrwxr-x 1 lauris lauris 138 Aug 17 17:41 six-1.10.0.dist-info
-rw-rw-r-- 1 lauris lauris 30098 Aug 17 17:41 six.py
-rw-rw-r-- 1 lauris lauris 29545 Aug 17 17:41 six.pyc
drwxrwxr-x 1 lauris lauris 254 Aug 17 17:41 tzlocal
drwxrwxr-x 1 lauris lauris 154 Aug 17 17:41 tzlocal-1.2.2.dist-info
~/tmp> pip --version
pip 8.1.2 from /usr/lib/python2.7/site-packages (python 2.7)
I get this error on a fairly stock fedora box.
>>> pendulum.now()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python3.5/site-packages/pendulum/pendulum.py", line 270, in now
return cls.instance(dt, tz)
File "/usr/lib64/python3.5/site-packages/pendulum/pendulum.py", line 205, in instance
tzinfo=tz
File "/usr/lib64/python3.5/site-packages/pendulum/pendulum.py", line 180, in __init__
self._tz = self._safe_create_datetime_zone(tzinfo)
File "/usr/lib64/python3.5/site-packages/pendulum/pendulum.py", line 111, in _safe_create_datetime_zone
return cls._local_timezone()
File "/usr/lib64/python3.5/site-packages/pendulum/pendulum.py", line 130, in _local_timezone
return local_timezone()
File "/usr/lib64/python3.5/site-packages/pendulum/tz/__init__.py", line 25, in local_timezone
return LocalTimezone.get()
File "/usr/lib64/python3.5/site-packages/pendulum/tz/local_timezone.py", line 19, in get
name = cls.get_local_tz_name()
File "/usr/lib64/python3.5/site-packages/pendulum/tz/local_timezone.py", line 36, in get_local_tz_name
return getattr(cls, 'get_tz_name_for_{}'.format(os))()
File "/usr/lib64/python3.5/site-packages/pendulum/tz/local_timezone.py", line 145, in get_tz_name_for_unix
return Timezone('', *Parser.parse(tzfile))
File "/usr/lib64/python3.5/site-packages/pendulum/tz/parser.py", line 27, in parse
with open(filepath, 'rb') as fp:
TypeError: invalid file: <_io.BufferedReader name='/etc/localtime'>
I don't know the full details that make my platform not work with Loader.load
but I'm using a Fedora Core 24 box with its stock python3.5 interpretor. I believe that the pytz
install I have was installed by pip3 but I'm not 100% sure.
When I run tests most of them fail because Loader.load
is trying to open zoneinfo files in a location that they don't exist. Looking at the code it looks like this is a possibly a non portable way of getting zoneinfo since it makes assumptions about where the zoneinfo files should live.
I tweaked the exception to print the file location to illustrate..
======================================================================
ERROR: wrap_with_test_now (tests.tz_tests.test_timezone.TimezoneTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/mayfield/project/pendulum/tests/__init__.py", line 13, in setUp
LocalTimezone.set_local_timezone(timezone('America/Toronto'))
File "/home/mayfield/project/pendulum/pendulum/tz/__init__.py", line 16, in timezone
return Timezone.load(name)
File "/home/mayfield/project/pendulum/pendulum/tz/timezone.py", line 50, in load
default_transition_type) = Loader.load(name)
File "/home/mayfield/project/pendulum/pendulum/tz/loader.py", line 28, in load
raise TypeError(filepath)
TypeError: /usr/lib/python3.5/site-packages/pytz/zoneinfo/America/Toronto
In that case there is not a zoneinfo
sub dir in /usr/lib/python3.5/site-packages/pytz
. But on the same machine this works fine..
>>> pytz.timezone('America/Toronto')
<DstTzInfo 'America/Toronto' LMT-1 day, 18:42:00 STD>
Doing various math operator actions on timedelta subclasses produces timedelta instances instances. This is partially because of the frailty of datetime.timedelta code but it would be highly preferable to support operations like avg_perdio = total_period / some_count
and get a Period/Interval object back instead of a timedelta object. It's also quite confusing since the APIs are very different between all 3 of these subclasses.
Example..
>>> import pendulum
>>> iobj = pendulum.Interval(seconds=10)
>>> x = iobj / 3
>>> x
datetime.timedelta(0, 3, 333333)
>>> type(x)
<class 'datetime.timedelta'>
>>> type(iobj)
<class 'pendulum.interval.Interval'>
>>>
I took a look at the code and unfortunately it looks like you'd have to subclass all the relevant operator calls (__div__
, etc) and patch them to produce new Interval or Period objects. Because Interval and Period have very different instantiation patterns it might not even be possible to implement in the base Interval class. However I'll leave it to you to review.
I'm trying to do some maths with dates that results in objects with different DST timezone offsets, e.g.:
>>> pendulum.parse("2016-01-12", tz="America/Sao_Paulo").add(months=1)
<Pendulum [2016-02-12T00:00:00-02:00]>
>>>pendulum.parse("2016-01-12", tz="America/Sao_Paulo").add(months=4)
<Pendulum [2016-05-11T23:00:00-03:00]>
>>> pendulum.parse("2016-01-30", tz="America/Sao_Paulo").add(months=4)
<Pendulum [2016-05-29T23:00:00-03:00]>
That's a behavior that seems undesired. I was expecting that every result had a 00:00:00
as I'm adding months, not hours, and I think the day numbers (12
and 30
in the example above) shouldn't be lost (unless I'm trying to move from january to february, but that wasn't the case).
There are several timezones that don't have a integer offset from UTC: for instance Australia/Adelaide is +0930 (+1030 DST). This means that the following is incorrect:
>>> import pendulum
>>> pendulum.now('Australia/Adelaide).offset_hours
9
Is this intentional? The documentation say "integer offset".
Trying to convert a datetime instance which have a tzinfo property, to a pendulum instance returns an error.
import pendulum
import pytz
from datetime import datetime
date = datetime.now()
date = date.replace(tzinfo=pytz.utc)
pendulum_date = pendulum.instance(date)
returns:
AttributeError: 'UTC' object has no attribute 'upper'
I installed pendulum on Python 3.2 install, and when I run it, here's what I get:
% python3
Python 3.2.3 (default, Feb 20 2013, 17:02:41)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pendulum
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.2/dist-packages/pendulum/__init__.py", line 3, in <module>
from .pendulum import Pendulum
File "/usr/local/lib/python3.2/dist-packages/pendulum/pendulum.py", line 19, in <module>
from .tz import Timezone, UTC, FixedTimezone, local_timezone
File "/usr/local/lib/python3.2/dist-packages/pendulum/tz/__init__.py", line 3, in <module>
from .timezone import Timezone, FixedTimezone, UTC
File "/usr/local/lib/python3.2/dist-packages/pendulum/tz/timezone.py", line 6, in <module>
from .loader import Loader
File "/usr/local/lib/python3.2/dist-packages/pendulum/tz/loader.py", line 10, in <module>
from .. import _compat
File "/usr/local/lib/python3.2/dist-packages/pendulum/_compat.py", line 19, in <module>
FileNotFoundError = FileNotFoundError
NameError: name 'FileNotFoundError' is not defined
It looks like the FileNotFoundError
exception, along with the rework of the OS/IO exceptions has been introduced in Python 3.3.
cf
I do not understand why FileNotFoundError
could not defined in Python 3.2. cf PEP-3151
Instead of relying on major python versions to check for features, I'd suggest to check for the feature and fallback to the alternative. Such as:
try:
FileNotFoundError = FileNotFoundError
except NameError:
FileNotFoundError = IOError
The Python3.2.3 I'm using, is the one from Debian Wheezy (old-stable) and I installed pendulum v0.5.5 from Pypi. I tried with the suggested fix above, and it works.
I am using py3 and I tested the module in my locale (pt-br) but on formatting it returns a error:
ValueError: Invalid format string
OS X 10.11.6, Python 3.5.1, Pendulum 0.6.4
sudo ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime
python -c 'import pendulum; pendulum.now().add(seconds=3)'
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/Users/gavin/Development/MarksAndSpencer/cfto-browse/venv/lib/python3.5/site-packages/pendulum/pendulum.py", line 1446, in add
dt = self._tz.convert(dt)
File "/Users/gavin/Development/MarksAndSpencer/cfto-browse/venv/lib/python3.5/site-packages/pendulum/tz/timezone.py", line 93, in convert
converted = self._convert(dt)
File "/Users/gavin/Development/MarksAndSpencer/cfto-browse/venv/lib/python3.5/site-packages/pendulum/tz/timezone.py", line 218, in _convert
return dt.astimezone(self)
File "/Users/gavin/Development/MarksAndSpencer/cfto-browse/venv/lib/python3.5/site-packages/pendulum/tz/timezone.py", line 301, in fromutc
tr = self._transitions[idx]
IndexError: tuple index out of range
Importing pendulum inside a test file and running pytest returns an error about importing language files.
Running the following code:
import pytest
import pendulum
def test_import_pendulum():
date = pendulum.now(tz='America/Sao_Paulo')
assert data.is_today() == True
returns the following message:
ImportError while importing test module '/home/decko/dev/temp/test_pendulum.py'.
Original error message:
'No module named no'
Make sure your test modules/packages have valid Python names.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.