Python: Convert simplejson dumped unicode datetime back to datetime object - python

I have...
entity = simplejson.dumps({"a":unicode(datetime.datetime.utcnow())})
How do I convert the datetime (that was converted to unicode) back to datetime again?
So that I can do something like...
entity2 = simplejson.loads(entity)
#your answer here..
add5 = entity2["a"] + datetime.timedelta(minutes=5)
Thanks!

DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S'
Do the following before serializing:
time = datetime.strftime(time, DATETIME_FORMAT)
Do the following after unserializing:
time = datetime.strptime(time, DATETIME_FORMAT)
example:
>>> from datetime import datetime
>>> DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S'
>>> time = datetime.now()
>>> time
datetime.datetime(2011, 5, 5, 3, 1, 45, 646302)
>>> time = time.strftime(DATETIME_FORMAT)
>>> time
'2011-05-05 03:01:45'
>>> import json
>>> time = json.loads(json.dumps(time))
>>> time
'2011-05-05 03:01:45'
>>> time = datetime.strptime(time, DATETIME_FORMAT)
>>> time
datetime.datetime(2011, 5, 5, 3, 1, 45)
In case you find this somewhat inelegant, you might consider a custom json encoder/decoder. I personally have tried the ones in the default json package, but gave up pulling my hair out with cryptic error messages. If you go this path, I might recommend a third party json package.

Use datetime.datetime.strptime.
dt = datetime.datetime.strptime(entity2['a'], '%Y-%m-%d %H:%M:%S.%f')

Related

convert given time from a given timezone to UTC

I have two inputs time 00:00 and timezone 'Asia/Kolkata'
I want to convert this to UTC time like '18.30'
I don't want to add or subtract offsets because it may affect the day light saving
what i did is
local = pytz.timezone ("UTC")
nativetime = datetime.strptime (setTime,frmt)
local_dt = local.localize(nativetime, is_dst=None)
utc_dt = local_dt.astimezone(pytz.utc)
but this doesn't change anything, the time is not converted to UTC
Please help
Something like this, assuming you're on py3:
>>> import datetime
>>> import pytz
>>> tz = pytz.timezone('Asia/Kolkata')
>>> dt = datetime.datetime(2020, 8, 4, 0, 0, tzinfo=tz)
>>> dt.astimezone(pytz.utc)
datetime.datetime(2020, 8, 3, 18, 7, tzinfo=<UTC>)
>>>
Since you say you're new to Python, it might be good to skip pytz since it's going to be deprecated with Python 3.9. You can use dateutil instead, which can be replaced more easily with zoneinfo in Python 3.9.
from datetime import datetime, timezone
from dateutil.tz import gettz
# assuming you have something like
dt_naive = datetime.strptime('2020-08-05', '%Y-%m-%d')
# dt_naive has no time zone info, so set it:
dt_aware = dt_naive.replace(tzinfo=gettz('Asia/Kolkata'))
# now you can convert to another timezone using .astimezone:
dt_aware_utc = dt_aware.astimezone(timezone.utc)
# datetime.datetime(2020, 8, 4, 18, 30, tzinfo=datetime.timezone.utc)
# -> 5:30 hours behind, which matches dt_aware.utcoffset()
#thebjorn gave me the answer
here is what i did
def utc_to_local(utc_dt,local_tz):
local_dt = utc_dt.replace(tzinfo=pytz.utc).astimezone(local_tz)
return local_tz.normalize(local_dt)
setTime='00:00:00'
setZone='Asia/Kolkata'
datePart = str(datetime.utcnow()).split(' ')[0]
dateTimeUtcStr = datePart+' '+str(setTime)
tz = pytz.timezone('Asia/Kolkata')
tz_utc = pytz.timezone('UTC')
dateTimeRef = datetime.strptime(dateTimeUtcStr, '%Y-%m-%d %H:%M:%S')
#local to utc
tzUtc = pytz.timezone('UTC')
local_dt = tz.localize(dateTimeRef, is_dst=None)
utc_dt = local_dt.astimezone(pytz.utc)
print(utc_dt)
#utc to local
altTime = utc_to_local(utc_dt,tz)
print(altTime)

How to serialize time objects while preserving their timezone?

I'm trying to serialize time-objects to ISO8601 format while preserving their timezone information with Python 3.8.
The documentation for time.isoformat states:
time.isoformat(timespec='auto')
Return a string representing the time in ISO 8601 format, one of:
HH:MM:SS.ffffff, if microsecond is not 0
HH:MM:SS, if microsecond is 0
HH:MM:SS.ffffff+HH:MM[:SS[.ffffff]], if utcoffset() does not return None
HH:MM:SS+HH:MM[:SS[.ffffff]], if microsecond is 0 and utcoffset() does not return None
As far as I understand from that documentation I just have to generate a time-object whose utcoffset() isn't None to get the timezone information as part of the ISO8601-formatted string. That works fine when using datetime.timezone.utc as timezone:
>>> from datetime import time, timezone
>>> t = time(1, 2, 3, tzinfo=timezone.utc)
>>> t
datetime.time(1, 2, 3, tzinfo=datetime.timezone.utc)
>>> t.utcoffset()
datetime.timedelta(0)
>>> t.isoformat()
'01:02:03+00:00'
However as soon as I want to use a timezone which isn't provided by the Python standard library, that doesn't seem to work anymore. I tried dateutil and pytz and in both cases got the same result:
>>> from datetime import time
>>> from dateutil.tz import gettz
>>> t = time(1, 2, 3, tzinfo=gettz("US/Eastern"))
>>> t
datetime.time(1, 2, 3, tzinfo=tzfile('/usr/share/zoneinfo/US/Eastern'))
>>> t.utcoffset()
>>> t.isoformat()
'01:02:03'
>>> from datetime import time
>>> from pytz import timezone
>>> t = time(1, 2, 3, tzinfo=timezone("US/Eastern"))
>>> t
datetime.time(1, 2, 3, tzinfo=<DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>)
>>> t.utcoffset()
>>> t.isoformat()
'01:02:03'
I also tried using time.strftime() instead, however that doesn't solve my problem either:
>>> from datetime import time
>>> from dateutil.tz import gettz
>>> t = time(1, 2, 3, tzinfo=gettz("US/Eastern"))
>>> t.strftime("%H:%M:%S%z")
'01:02:03'
Why is that the case and how can I solve this issue?
Without a date, time doesn't give an unambiguous UTC offset. For example in your case, time zone "US/Eastern" has daylight saving time partly over the year, with UTC offsets EST (UTC-5) and EDT (UTC-4). Python is kind of quiet there, not telling you about it e.g. in a warning.
If you add a date, strftime works:
import datetime as dt
from dateutil.tz import gettz
t_est = dt.datetime.combine(dt.date(2020,1,1), dt.time(1, 2, 3, tzinfo=gettz("US/Eastern")))
t_est.strftime("%H:%M:%S%z")
# '01:02:03-0500'
t_edt = dt.datetime.combine(dt.date(2020,6,6), dt.time(1, 2, 3, tzinfo=gettz("US/Eastern")))
t_edt.strftime("%H:%M:%S%z")
# '01:02:03-0400'
On the other hand, if you provide tzinfo as a pure UTC offset, your code would work. Quoting from the docs:
t = dt.time.fromisoformat('04:23:01+04:00')
# datetime.time(4, 23, 1, tzinfo=datetime.timezone(datetime.timedelta(seconds=14400)))
t.isoformat()
# '04:23:01+04:00'
If you know for example that all your time objects refer to EST, you could use the respective UTC offset:
t = dt.time(1, 2, 3, tzinfo=dt.timezone(dt.timedelta(seconds=3600*-5)))
t.isoformat()
# '01:02:03-05:00'

How to print my time zone like this format UTC+8?

I am trying to write code.
I could print like that Mongolian time 2019-09-27T15:09:34.915812+08:00
How to print local time zone? Like that "UTC+8"
You could use
pytz library
from datetime import datetime, timedelta
from pytz import timezone
import pytz
utc_8 = timezone("Singapore")
utc_8.zone
fmt = '%Y-%m-%d %H:%M:%S %Z%z'
loc_dt = utc_8.localize(datetime(2019, 9, 27, 15, 9, 34))
print(loc_dt.strftime(fmt)) #2019-09-27 15:09:34 +08+0800
>>> import datetime
>>> foo = '2019-09-27T15:09:34.915812+08:00'
>>> bar = datetime.datetime.strptime(foo, '%Y-%m-%dT%H:%M:%S.%f%z')
>>> bar.tzname()
'UTC+08:00'

Python convert date string to python date and subtract

I have a situation where I need to find the previous date from the date_entry where the date_entry is string, I managed to do this:
>>> from datetime import timedelta, datetime
>>> from time import strptime, mktime
>>> date_str = '20130723'
>>> date_ = strptime(date_str, '%Y%m%d')
>>> date_
time.struct_time(tm_year=2013, tm_mon=7, tm_mday=23, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=1, tm_yday=204,tm_isdst=-1)
>>> datetime.fromtimestamp(mktime(date_))-timedelta(days=1)
datetime.datetime(2013, 7, 22, 0, 0)
>>>
But, for this I have to import the modules timedelta, datetime, strptime and mktime. I think this really an overkill to solve this simple problem.
Is there any more elegant way to solve this (using Python 2.7) ?
Just use datetime.datetime.strptime class method:
>>> import datetime
>>> date_str = '20130723'
>>> datetime.datetime.strptime(date_str, '%Y%m%d') - datetime.timedelta(days=1)
datetime.datetime(2013, 7, 22, 0, 0)
Chosen answer is old and works on python 2, returns bellow error for python 3.
Error:
AttributeError: type object 'datetime.datetime' has no attribute 'datetime'
Fix + Doing it with PYTHON 3 :
from datetime import datetime,timedelta
date_str = '20130723'
datetime.strptime(date_str, '%Y%m%d') - timedelta(days=1)
Also, use up to date document on Python 3 here: https://docs.python.org/3/library/datetime.html#datetime.datetime.strptime

How to get the difference in Localtime and GMT time python?

I get the server date and I need to get the difference of this date from GMT
I get
Datetime = "2011-04-27 2:17:45"
I would like to get the result like
Datetime = "2011-04-27 2:17:45 +0500"
Try this:
import datetime, pytz
now = datetime.datetime.now(pytz.timezone('Asia/Kolkata'))
print now.strftime('%Y-%m-%d %H:%M:%S %z')
# prints: '2011-04-27 13:56:09 +0530'
From the example you have given, it looks to me that what you are looking for is datetime.isoformat. The example in the page shows how to convert the datetime values to the ISO format with the time zone information.
To do this, you have to know the timezone (or the UTC offset) of the server date. What you have here is a "naive" date, without timezone info, you can't guess the UTC difference.
I think the datetime module is what you need here:
>>> from datetime import datetime
>>> datetime.now()
datetime.datetime(2011, 4, 27, 11, 8, 26, 149000)
>>> datetime.utcnow()
datetime.datetime(2011, 4, 27, 8, 8, 47, 712000)
For a difference between two dates:
>>> dtnow = datetime.now()
>>> dtutc = datetime.utcnow()
>>> dtnow - dtutc
datetime.timedelta(0, 10792, 847000)
Look up the datetime module and the relevant classes in Python's docs.
A very powerful extension of the datetime standard python library is the dateutil one, that allows you to easily:
set the delta of your time zone:
parse dates with various convenient options (in our case we will use the default option, which will allow us to set our time zone)
So 1st set time zone, and default date with this zone:
>>> from datetime import datetime
>>> from dateutil import parser
>>> from dateutil.tz import tzoffset
>>> tz_plus_5 = tzoffset(None, 5 * 60 * 60) # offset is in seconds !
>>> default = datetime.now(tz_plus_5)
Now use this default date in the parsing:
>>> Datetime = "2011-04-27 2:17:45"
>>> my_date = parser.parse(Datetime, default=default)
>>> my_date
datetime.datetime(2011, 4, 27, 2, 17, 45, tzinfo=tzoffset(None, 18000))
>>> my_date.strftime("%Y-%m-%d %H:%M:%S %z")
'2011-04-27 02:17:45 +0500'
For those that simply need to get the offset between local time and UTC, the time module has an attribute time.altzone that specifies the difference between UTC and local time in seconds:
The offset of the local DST timezone, in seconds west of UTC, if one is defined. This is negative if the local DST timezone is east of UTC (as in Western Europe, including the UK). Only use this if daylight is nonzero.
Here's an example of how it works:
>>> datetime.now().isoformat()
'2011-09-01T17:26:46.971000'
>>> datetime.utcnow().isoformat()
'2011-09-01T15:27:32.699000'
>>> time.altzone / (60*60)
-2
Doesn't get much cleaner than that.

Categories

Resources