I have JSON response object with string representing date and time:
"event":{
"type":"Type",
"date-time":"\/Date(928142400000+0200)\/",
},
I am not sure:
what format is that
how can I parse it in python app
how can I convert python date into this format
Any suggestions?
928142400000 is the time in milliseconds since the UNIX epoch, +0200 is the timezone.
With the dateutil library or datetime.timezone() objects you can model the timezone offset, the timestamp itself is parsable with datetime.datetime.fromtimestamp(), provided you divide the value by 1000.0:
import datetime
import re
timestamp_parse = re.compile(r'Date\((\d+)([+-]\d{4})\)')
timestamp, offset = timestamp_parse.search(datetime_value).groups()
tzoffset = datetime.timedelta(hours=int(offset[1:3]), minutes=int(offset[3:]))
if offset[0] == '-':
tzoffset *= -1
tzoffset = datetime.timezone(tzoffset)
dt = datetime.datetime.fromtimestamp(int(timestamp) / 1000.0).replace(tzinfo=tzoffset)
The dateutil.tz.tzoffset() object version is similar:
import datetime
import re
import dateutil.tz
timestamp_parse = re.compile(r'Date\((\d+)([+-]\d{4})\)')
timestamp, offset = timestamp_parse.search(datetime_value).groups()
tzoffset = int(offset[1:3]) * 3600 + int(offset[3:]) * 60
if offset[0] == '-':
tzoffset *= -1
tzoffset = dateutil.tz.tzoffset(None, tzoffset)
dt = datetime.datetime.fromtimestamp(int(timestamp) / 1000.0).replace(tzinfo=tzoffset)
Demo:
>>> import datetime
>>> import re
>>> datetime_value = "/Date(928142400000+0200)/"
>>> timestamp_parse = re.compile(r'Date\((\d+)([+-]\d{4})\)')
>>> timestamp, offset = timestamp_parse.search(datetime_value).groups()
>>> tzoffset = datetime.timedelta(hours=int(offset[1:3]), minutes=int(offset[3:]))
>>> if offset[0] == '-':
... tzoffset *= -1
...
>>> tzoffset = datetime.timezone(tzoffset)
>>> datetime.datetime.fromtimestamp(int(timestamp) / 1000.0).replace(tzinfo=tzoffset)
datetime.datetime(1999, 5, 31, 10, 20, tzinfo=datetime.timezone(datetime.timedelta(0, 7200)))
Related
i create this loop to give all timezones :
import datetime
import pytz
today=datetime.datetime.now(tz=pytz.UTC)
for i in pytz.all_timezones:
print(today.astimezone(pytz.timezone(i)))
but i want to get them in order from -9 to +14
now = datetime.datetime.now()
tzs = sorted(pytz.all_timezones, key=lambda tz: pytz.timezone(tz).utcoffset(now))
This gives you a list like:
['Etc/GMT+12',
'Etc/GMT+11',
'Pacific/Midway',
'Pacific/Niue',
'Pacific/Pago_Pago',
'Pacific/Samoa',
'US/Samoa',
'Etc/GMT+10',
'HST',
'Pacific/Honolulu',
...]
Supposing you are just interested in GMT timezones...
from datetime import datetime
from pytz import UTC, all_timezones, timezone, UnknownTimeZoneError
now = datetime.now(tz=UTC)
print('Timezones should be similar to these...')
timezones_candidates = [tz for tz in all_timezones if 'GMT' in tz]
print(timezones_candidates)
first = -14
last = +9
desired_timezones = ['Etc/GMT{0:+}'.format(shift) for shift in range(first, last+1)]
print('\nNow as timezone:')
for tz in desired_timezones:
try:
print(now.astimezone(timezone(tz)))
except UnknownTimeZoneError:
print('The timezone {0} doesnt exist'.format(tz))
import datetime
import pytz
today=datetime.datetime.now(tz=pytz.UTC)
ordered = {}
for i in pytz.all_timezones:
timezone = today.astimezone(pytz.timezone(i))
gmt = str(timezone)[-6:-3]
gmt = (-1 if gmt[0] == '-' else 1) * int(gmt[1:])
ordered[pytz.timezone(i)] = gmt
for timezone, _ in sorted(ordered.items(), key=lambda item: item[1]):
print(today.astimezone(timezone))
I have a time string, say
str = "2018-09-23 14:46:55"
and an offset
offset = "0530"
I want to get str2 with offset added, ie
str2 = "2018-09-23 20:16:55"
Please guide.
You can use the datetime module:
from datetime import datetime, timedelta
x = "2018-09-23 14:46:55"
offset = "0530"
res = datetime.strptime(x, '%Y-%m-%d %H:%M:%S') + \
timedelta(hours=int(offset[:2]), minutes=int(offset[2:]))
print(res)
datetime.datetime(2018, 9, 23, 20, 16, 55)
Use timedelta to add offset to a datetime object.
from datetime import datetime, timedelta
str = "2018-09-23 14:46:55"
str = datetime.strptime(str, "%Y-%m-%d %H:%M:%S")
str2 = str + timedelta(hours=5, minutes=30)
print(str2)
I have no idea how to implement this. Please describe how to do it correctly.
datetest = "2016.05.09" + " "+ "15:45:45"
from datetime import datetime
d = datetime.strptime(datetest, "%Y.%m.%d %H:%M")
epocht = d.strftime("%Y.%m.%d %H:%M:%S")
Check this out:
from datetime import time
timestamp = int(time.mktime(d.timetuple())) * 1000
You can try this -
import time
import datetime
t = datetime.datetime(2016, 5, 9, 15, 45, 45)
print(time.mktime(t.timetuple() * 1000))
from datetime import datetime
import time
datetest = "2016.05.09" + " "+ "15:45:45"
d = datetime.strptime(datetest, "%Y.%m.%d %H:%M:%S")
t = d.timetuple()
res = int(time.mktime(t)) * 1000
print(res) # -> 1462833945000
I use the dateutil parser as it offers some flexibility, but others may disagree
In [1]:
from dateutil.parser import parse as dateparse
datetest = "2016.05.09" + " "+ "15:45:45"
dateparse(datetest).timestamp() * 1000
Out [1]:
1462830345000.0
'dateparse' returns a datetime.datetime object:
In [2]:
dateparse(datetest)
Out[2]:
datetime.datetime(2016, 5, 9, 15, 45, 45)
I have a date which is in local time:
date: "2013-12-02 22:00:00"
and another value the tz:
timezone_offset: "GMT-0800"
If I : dateutil.parser.parse(date).isoformat() I will get:
"2013-12-02T22:00:00+0000"
I want to implement the date in ISO format with the tz info and get a result of:
"2013-12-02T22:00:00-0800"
Something close to: parse(date,tzinfos=??).isoformat() ? How can I get the tzinfo from the string timezone_offset ?
>>> from dateutil.parser import parse
>>> dt = parse("2013-12-02 22:00:00" + "GMT+0800")
>>> dt.isoformat()
'2013-12-02T22:00:00-08:00'
Note: the sign is reversed.
You could also do it using only stdlib:
>>> from datetime import datetime
>>> dt = datetime.strptime("2013-12-02 22:00:00", "%Y-%m-%d %H:%M:%S")
>>> dt = dt.replace(tzinfo=FixedOffset(-8*60, "GMT+0800"))
>>> dt.isoformat()
'2013-12-02T22:00:00-08:00'
where FixedOffset is taken from datetime docs:
from datetime import tzinfo, timedelta
class FixedOffset(tzinfo):
"""Fixed offset in minutes east from UTC."""
def __init__(self, offset, name):
self.__offset = timedelta(minutes = offset)
self.__name = name
def utcoffset(self, dt):
return self.__offset
def tzname(self, dt):
return self.__name
def dst(self, dt):
return timedelta(0)
Here's the same using pytz module:
>>> from datetime import datetime
>>> import pytz
>>> dt = datetime.strptime("2013-12-02 22:00:00", "%Y-%m-%d %H:%M:%S")
>>> dt = pytz.timezone('Etc/GMT+8').localize(dt)
>>> dt.isoformat()
'2013-12-02T22:00:00-08:00'
Here are two approaches you could use:
>>> import datetime
>>> dtnow = datetime.datetime.now();dtutcnow = datetime.datetime.utcnow()
>>> dtnow
datetime.datetime(2013, 11, 12, 9, 10, 48, 404000)
>>> dtutcnow
datetime.datetime(2013, 11, 12, 15, 10, 48, 404000)
>>> delta = dtnow - dtutcnow
>>> delta
datetime.timedelta(-1, 64800)
>>> hh,mm = divmod((delta.days * 24*60*60 + delta.seconds + 30) // 60, 60)
>>> hh,mm
(-6, 0)
>>> "%s%+02d:%02d" % (dtnow.isoformat(), hh, mm)
'2013-11-12T09:10:48.404000-6:00'
Or this:
>>> import datetime, pytz # 3rd Party
>>> datetime.datetime.now(pytz.timezone('US/Central')).strftime('%Y-%m-%dT%H:%M:%S.%f%z')
'2013-11-12T09:15:20.688000-0600'
>>>
The main advantage of the second method is it makes your time string 'timezone aware'. From the docs:
There are two kinds of date and time objects: “naive” and “aware”.
This distinction refers to whether the object has any notion of time
zone, daylight saving time, or other kind of algorithmic or political
time adjustment. Whether a naive datetime object represents
Coordinated Universal Time (UTC), local time, or time in some other
timezone is purely up to the program, just like it’s up to the program
whether a particular number represents metres, miles, or mass. Naive
datetime objects are easy to understand and to work with, at the cost
of ignoring some aspects of reality.
Hope this helps!
I'm working on PDF with Python and I'm accessing the file's meta data by using PDFMiner. I extract the info using this:
from pdfminer.pdfparser import PDFParser, PDFDocument
fp = open('diveintopython.pdf', 'rb')
parser = PDFParser(fp)
doc = PDFDocument()
parser.set_document(doc)
doc.set_parser(parser)
doc.initialize()
print doc.info[0]['CreationDate']
# And return this value "D:20130501200439+01'00'"
How can I convert D:20130501200439+01'00' into a readable format in Python?
I found the format documented here. I needed to cope with the timezones too because I have 160k documents from all over to deal with. Here is my full solution:
import datetime
import re
from dateutil.tz import tzutc, tzoffset
pdf_date_pattern = re.compile(''.join([
r"(D:)?",
r"(?P<year>\d\d\d\d)",
r"(?P<month>\d\d)",
r"(?P<day>\d\d)",
r"(?P<hour>\d\d)",
r"(?P<minute>\d\d)",
r"(?P<second>\d\d)",
r"(?P<tz_offset>[+-zZ])?",
r"(?P<tz_hour>\d\d)?",
r"'?(?P<tz_minute>\d\d)?'?"]))
def transform_date(date_str):
"""
Convert a pdf date such as "D:20120321183444+07'00'" into a usable datetime
http://www.verypdf.com/pdfinfoeditor/pdf-date-format.htm
(D:YYYYMMDDHHmmSSOHH'mm')
:param date_str: pdf date string
:return: datetime object
"""
global pdf_date_pattern
match = re.match(pdf_date_pattern, date_str)
if match:
date_info = match.groupdict()
for k, v in date_info.iteritems(): # transform values
if v is None:
pass
elif k == 'tz_offset':
date_info[k] = v.lower() # so we can treat Z as z
else:
date_info[k] = int(v)
if date_info['tz_offset'] in ('z', None): # UTC
date_info['tzinfo'] = tzutc()
else:
multiplier = 1 if date_info['tz_offset'] == '+' else -1
date_info['tzinfo'] = tzoffset(None, multiplier*(3600 * date_info['tz_hour'] + 60 * date_info['tz_minute']))
for k in ('tz_offset', 'tz_hour', 'tz_minute'): # no longer needed
del date_info[k]
return datetime.datetime(**date_info)
Is "+01'00'" the timezone information? Not taking that into account, you can create a datetime object as follows...
>>>from time import mktime, strptime
>>>from datetime import datetime
...
>>>datestring = doc.info[0]['CreationDate'][2:-7]
>>>ts = strptime(datestring, "%Y%m%d%H%M%S")
>>>dt = datetime.fromtimestamp(mktime(ts))
datetime(2013, 5, 1, 20, 4, 30)
use Python 3's datetime.strptime; just remove the apostrophes first:
from datetime import datetime
creation_date = "D:20130501200439+01'00'"
dt = datetime.strptime(creation_date.replace("'", ""), "D:%Y%m%d%H%M%S%z")
print(repr(dt))
# datetime.datetime(2013, 5, 1, 20, 4, 39, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600)))
print(dt.isoformat())
# 2013-05-01T20:04:39+01:00
once you have a datetime object, you can format back to string however you like for a "readable" output, see strptime/strftime directives.
Guess I don't have the rep to comment on Paul Whipp's illustrative answer, but I've amended it to handle a form of the Y2K bug present in some of my old files. The year 2000 was written 19100, so the relevant line of pdf_date_pattern became
r"(?P<year>191\d\d|\d\d\d\d)",
and I added an elif to the transform values loop:
elif k == 'year' and len(v) == 5:
date_info[k] = int('20' + v[3:])