16

In current part of system pendulum v1.4 is used, but with croniter it causing error described in https://github.com/sdispater/pendulum/issues/214

This works fine with datetime.datetime type and i still have to stay with pendulum v1.4.

So i am looking for solution how to efficiently to convert pendulum to datetime.datetime type ?

Already tried formatting pendulum as string and parsing using dateutil.parser.

esugei
  • 181
  • 1
  • 1
  • 8

5 Answers5

19

Another take on this:

>>> from datetime import datetime
>>> import pendulum
>>> datetime.fromtimestamp(pendulum.now().timestamp(), pendulum.tz.UTC)
datetime.datetime(2021, 1, 12, 11, 41, 32, 387753, tzinfo=Timezone('UTC'))

Usually there should be no need to do this since pendulum's DateTime inherits from datetime.datetime. Any code working with stdlib's datetime's should work with pendulum's as well.

Arne
  • 17,706
  • 5
  • 83
  • 99
Anthony
  • 1,877
  • 17
  • 21
  • Don't sure about pandas – Anthony May 10 '19 at 14:13
  • 4
    @MisterMonk For Pandas, the Pendulum nanoseconds must be stripped off, Pandas does not support nanoseconds. pandas_friendly = pendulum_datetime.strftime("%Y-%m-%d %H:%M:%S %z") See here: https://gist.github.com/liquidgenius/195fd7ca99fb761fd0fd2c2f2c78608d and here: https://github.com/sdispater/pendulum/issues/246 – Liquidgenius May 27 '19 at 21:46
  • 1
    Just to add to the counter examples of pendulum's DateTime working everywhere datetime does - SQLAlchemy doesn't like to use pendulum's DateTime and can cause weird issues. – robertlayton Jul 17 '20 at 04:48
  • @robertlayton If you're trying to use pendulum's `DateTime` as a column type, like this: `Column('foo', pendulum.DateTime)` - it isn't intended to work. – Anthony Aug 02 '20 at 11:17
  • Thanks for the reply. I'm using a normal SQLAlchemy datetime column, but when you pass a pendulum DateTime to it, it fails at database commit time. I now just wrap it in a pendulum_to_datetime function before passing in. – robertlayton Aug 02 '20 at 23:38
  • @robertlayton Here is gist that demonstrates usage of pendulum's `DateTime` instances as values for SQLA `DateTime` columns: https://gist.github.com/tribals/49668c4c332f03462eb15d172cc06f4a#file-test_models-py. As you can see, it works well. – Anthony Aug 13 '20 at 11:33
  • @tosh. Awesome. Thanks for following up. I see the SQLAlchemy version is greater than my project's so I will try update that and see how that goes. – robertlayton Aug 17 '20 at 00:51
  • Also like to add that pendulum Datetime does not support microseconds. Ran into a `'datetime.timedelta' object has no attribute '_to_microseconds'` issue when computing timedelta from a pendulum datetime – DFeng Jan 28 '22 at 20:51
4

I couldn't find a Pendulum helper for this either. So, back to basics:

import datetime as dt

tz_info = dateutil.tz.gettz(zone_name)
pend_time = pendulum.datetime(...)

dt_time = dt.datetime(
    pend_time.year,
    pend_time.month,
    pend_time.day,
    pend_time.hour,
    pend_time.minute,
    pend_time.second,
    pend_time.microsecond,
).astimezone(tz_info)

Note the use of dateutil. As of Python 3.6, the tzinfo documentation recommends dateutil.tz rather than pytz as an IANA time zone provider.

Gavin
  • 131
  • 5
3

pendulum==1.4.0 objects have the protected _datetime member:

import pendulum

p = pendulum.now()
p._datetime

This will give you something like

datetime.datetime(2021, 5, 24, 12, 44, 11, 812937, tzinfo=<TimezoneInfo [America/New_York, EDT, -4:00:00, DST]>)

Another way is as follows: and works for pendulum==1.4.0 and more recent pendulum==2.1.2

import pendulum
from datetime import datetime

p = pendulum.now()
datetime_string = p.to_datetime_string()
datetime.fromisoformat(datetime_string)

which will give

datetime.datetime(2021, 5, 24, 12, 44, 11)
Ali Cirik
  • 1,475
  • 13
  • 21
1

The following code works for me:

In [1]: import pendulum

In [2]: import datetime

In [3]: pdt = pendulum.now()

In [4]: datetime.datetime.fromisoformat(pdt.to_iso8601_string())
Out[4]: datetime.datetime(2022, 2, 22, 14, 29, 36, 812772,tzinfo=datetime.timezone(datetime.timedelta(seconds=28800)))
dindom
  • 583
  • 2
  • 4
  • 17
-6

use arrow module to convert pendulum to datetime

>>> arrow.get(datetime(2013, 5, 5), 'US/Pacific')
<Arrow [2013-05-05T00:00:00-07:00]>

example:

In [90]: import numpy as np
    ...: import pandas as pd
    ...: import pendulum
    ...: import arrow
    ...: 
    ...: def pendulum_to_datetime(x):
    ...:     return arrow.get(x, x.tz.name).datetime

In [91]: dates = [pendulum.datetime(2011, 1, 2, tz='Asia/Seoul'),
    ...:             pendulum.datetime(2011, 1, 5, tz='Asia/Seoul'),
    ...:             pendulum.datetime(2011, 1, 7, tz='Asia/Seoul')]
In [92]: dates
Out[92]: 
[DateTime(2011, 1, 2, 0, 0, 0, tzinfo=Timezone('Asia/Seoul')),
 DateTime(2011, 1, 5, 0, 0, 0, tzinfo=Timezone('Asia/Seoul')),
 DateTime(2011, 1, 7, 0, 0, 0, tzinfo=Timezone('Asia/Seoul'))]

In [93]: dates2 = [pendulum_to_datetime(x) for x in dates]
In [94]: dates2
Out[94]: 
[datetime.datetime(2011, 1, 2, 0, 0, tzinfo=tzfile('ROK')),
 datetime.datetime(2011, 1, 5, 0, 0, tzinfo=tzfile('ROK')),
 datetime.datetime(2011, 1, 7, 0, 0, tzinfo=tzfile('ROK'))]

In [95]: s1 = pd.Series(np.random.randn(3), index=dates2)
In [96]: s1
Out[96]: 
2011-01-02 00:00:00+09:00   -0.359771
2011-01-05 00:00:00+09:00   -0.208608
2011-01-07 00:00:00+09:00   -0.051233
dtype: float64

In [97]: s1.index
Out[97]: 
DatetimeIndex(['2011-01-02 00:00:00+09:00', '2011-01-05 00:00:00+09:00',
               '2011-01-07 00:00:00+09:00'],
              dtype='datetime64[ns, tzfile('ROK')]', freq=None)

In [98]: s2 = pd.Series(dates2)
In [99]: s2
Out[99]: 
0   2011-01-02 00:00:00+09:00
1   2011-01-05 00:00:00+09:00
2   2011-01-07 00:00:00+09:00
dtype: datetime64[ns, tzfile('ROK')]