Can't convert time.struct_time to json-compatible format - python

When I convert this
time.struct_time(tm_year=2014, tm_mon=11, tm_mday=30, tm_hour=4, tm_min=50, tm_sec=8, tm_wday=6, tm_yday=334, tm_isdst=0)
into a JSON object, it throws an error saying it can't serialize it. I didn't find an answer how to do this. How can I do it?

Convert it to a string using time.strftime() and then dump:
>>> import json
>>> import time
>>>
>>> struct = time.localtime()
>>> type(struct)
<type 'time.struct_time'>
>>> time_string = time.strftime('%Y-%m-%d %H:%M:%S', struct)
>>>
>>> print json.dumps({'time': time_string})
{"time": "2014-11-30 04:26:26"}

Related

Detecting date format and converting them to MM-DD-YYYY using Python3

I am trying to convert the date formats and make them uniform throughout the document using Python 3.6.
Here is the sample of the dates in my document:(There can be other formats as the document is large.)
9/21/1989
19640430
6/27/1980
5/11/1987
Mar 12 1951
2 aug 2015
I have checked the datetime lbrary. But could not understand hoow to detect and change the format of the dates automatically. Here is what I have checked till now:
>>> from datetime import datetime
>>> oldformat = '20140716'
>>> datetimeobject = datetime.strptime(oldformat,'%Y%m%d')
>>> newformat = datetimeobject.strftime('%m-%d-%Y')
>>> print (newformat)
07-16-2014
But I am not getting how I can make the program detect the date patterns automatically and convert them to one single uniform pattern of dates as mm/dd/yyyy
Kindly, suggest what I need to do, so as to achieve my goal using Python 3.6.
There is no universal Python way of doing this, but I'd recommend using regex to identify the type and then converting it correctly:
Example Python
import re
from datetime import datetime
with open("in.txt","r") as fi, open("out.txt","w") as fo:
for line in fi:
line = line.strip()
dateObj = None
if re.match(r"^\d{8}$", line):
dateObj = datetime.strptime(line,'%Y%m%d')
elif re.match(r"^\d{1,2}/", line):
dateObj = datetime.strptime(line,'%m/%d/%Y')
elif re.match(r"^[a-z]{3}", line, re.IGNORECASE):
dateObj = datetime.strptime(line,'%b %d %Y')
elif re.match(r"^\d{1,2} [a-z]{3}", line, re.IGNORECASE):
dateObj = datetime.strptime(line,'%d %b %Y')
fo.write(dateObj.strftime('%m-%d-%Y') + "\n")
Example Input
9/21/1989
19640430
6/27/1980
5/11/1987
Mar 12 1951
2 aug 2015
Example Output
09-21-1989
04-30-1964
06-27-1980
05-11-1987
03-12-1951
08-02-2015
I have tried using the dateutil library in my code to detect the date strings in any format. and then used the datetime library to convert it into the appropriate format.
Here is the code:
>>> import dateutil.parser
>>> yourdate = dateutil.parser.parse("May 24 2016")
>>>
>>> print(yourdate)
2016-05-24 00:00:00
>>> from datetime import datetime
>>> oldformat = yourdate
>>> datetimeobject = datetime.strptime(str(oldformat),'%Y-%m-%d %H:%M:%S')
>>> newformat = datetimeobject.strftime('%m-%d-%Y')
>>> print (newformat)
05-24-2016
This works.
See the image of the output:
(There can be other formats as the document is large.)
Unfortunately, Python does not provide "guess what I mean" functionality (although you might be able to repurpose GNU date for that, as it is quite flexible). You will have to make a list of all of the formats you want to support, and then try each in turn (using datetime.strptime() as you've shown) until one of them works.
Python does not try to guess because, in an international context, it is not generally possible to divine what the user wants. In the US, 2/3/1994 means "February 3rd, 1994," but in Europe the same string means "The 2nd of March, 1994." Python deliberately abstains from this confusion.

ValueError: Unknown string format in Python?

I'm trying to parse a basic iso formatted datetime string in Python, but I'm having a hard time doing that. Consider the following example:
>>> import json
>>> from datetime import datetime, date
>>> import dateutil.parser
>>> date_handler = lambda obj: obj.isoformat()
>>> the_date = json.dumps(datetime.now(), default=date_handler)
>>> print the_date
"2017-02-18T22:14:09.915727"
>>> print dateutil.parser.parse(the_date)
Traceback (most recent call last):
File "<input>", line 1, in <module>
print dateutil.parser.parse(the_date)
File "/usr/local/lib/python2.7/site-packages/dateutil/parser.py", line 1168, in parse
return DEFAULTPARSER.parse(timestr, **kwargs)
File "/usr/local/lib/python2.7/site-packages/dateutil/parser.py", line 559, in parse
raise ValueError("Unknown string format")
ValueError: Unknown string format
I've also tried parsing this using the regular strptime:
>>> print datetime.strptime(the_date, '%Y-%m-%dT%H:%M:%S')
# removed rest of the error output
ValueError: time data '"2017-02-18T22:11:58.125703"' does not match format '%Y-%m-%dT%H:%M:%S'
>>> print datetime.strptime(the_date, '%Y-%m-%dT%H:%M:%S.%f')
# removed rest of the error output
ValueError: time data '"2017-02-18T22:11:58.125703"' does not match format '%Y-%m-%dT%H:%M:%S.%f'
Does anybody know how on earth I can parse this fairly simple datetime format?
note the error message:
ValueError: time data '"2017-02-18T22:11:58.125703"'
There are single quotes + double quotes which means that the string actually contains double quotes. That's because json serialization adds double quotes to strings.
you may want to strip the quotes around your string:
datetime.strptime(the_date.strip('"'), '%Y-%m-%dT%H:%M:%S.%f')
or, maybe less "hacky", de-serialize using json.loads:
datetime.strptime(json.loads(the_date), '%Y-%m-%dT%H:%M:%S.%f')

How to join hex values

I am reading four bytes from file
I would like to join them
g = f.read(60)
f.seek (60)
k60 =f.read(1)
print('byte60',k60)
k61 =f.read(1)
print('byte61',k61)
k62 =f.read(1)
print('byte62',k62)
k63 =f.read(1)
print('byte63',k63)
print(k63,k62,k61,k60)
print (b''.join([k63,k62,k61,k60]))
Result is:
b'\x00\x00\x00\x80'
I would like to receive:
00000080
You to convert a byte string to its hex representation, you can use the hexlify() method from the binascii module:
>>> from binascii import hexlify
>>> ...
>>> raw = b''.join([k63,k62,k61,k60])
>>> print(hexlify(raw))
b'00000080'
>>> print(hexlify(raw).decode('ascii') # if you want to convert it to a string
00000080
The same could be accomplished by using codecs.encode(raw, 'hex').

Error concatenating string with Python datetime casted object

I've been searching a solution for this problem all over the web with no luck. I am trying to concatenate a string with a datetime object to form a .json format file however for some reason there is an error while doing so.
This is the code:
data = '{"gpio":"00000000","timestamp":'+str(int(time()))+',"formatted_time":"'+ **str(datetime.datetime.now().strftime("%A %b %d %X"))**+'""","time_zone":"'+str(read_tz_file())+'","firmware":"0.0"}
The even weirder scenario is that when adding any key after the method call it seems to be ok.
If you're writing/reading json, use the json library:
import json
print json.dumps(
dict(gpio='00000000',
timestamp=time(),
formatted_time=datetime.datetime.now().strftime("%A %b %d %X"),
time_zone=read_tz_file(),
firmware='0.0'))
for starters, it might help to put the code in a readable form,
preferrably multi-line (e.g. one json element per line).
this makes it easy to spot quoting errors.
data = ('{' +
'"gpio":"00000000",'+
'"timestamp":'+str(int(time()))+','+
'"formatted_time":"'+ str(datetime.datetime.now().strftime("%A %b %d %X")) +','+
'""",'+
'"time_zone":"'+str(read_tz_file())+'",'+
'"firmware":"0.0"'+
'}')
then try to debug the errors one by one.
e.g. str(int(time())) bails out at me, with a:
Traceback (most recent call last): File "", line 1, in
TypeError: 'module' object is not callable
that's because time is a module not a function, the proper function would be time.time():
data = ('' +
'{"gpio":"00000000",'+
'"timestamp":'+str(int(time.time()))+','+
'"formatted_time":"'+ str(datetime.datetime.now().strftime("%A %b %d %X")) +','+
'""",'+
'"time_zone":"'+str(read_tz_file())+'",'+
'"firmware":"0.0"'+
'}')
this gives me a valid string (after providing a dummy implementation of read_tz_file(), but it is invalid JSON (what's that """ supposed to do`)
a better way would be to construct a dictionary first, and convert that do json:
import json
d={
"gpio": 0,
"timestamp": int(time.time()),
"formatted_time": (datetime.datetime.now().strftime("%A %b %d %X"),
"time-zone": read_tz_file(),
"firmware": "0.0"
}
s=json.dumps()
print(s)
Use json module, to generate json text. Use the same Unix time for timestamp and formatted_time:
import json
import time
ts = int(time.time())
json_text = json.dumps(dict(
gpio="00000000",
timestamp=ts,
formatted_time=time.strftime("%A %b %d %X", time.localtime(ts)),
time_zone=read_tz_file(),
firmware="0.0"))
Note: in general, time.localtime(ts) may provide more info than datetime.now() e.g. in Python 2:
>>> import time
>>> from datetime import datetime
>>> ts = time.time()
>>> time.strftime('%Z%z')
'CEST+0200'
>>> time.strftime('%Z%z', time.localtime(ts))
'CEST+0000'
>>> datetime.now().strftime('%Z%z')
''
>>> datetime.fromtimestamp(ts).strftime('%Z%z')
''
Notice: only time.strftime('%Z%z') provides complete info for the local timezone on my machine, see python time.strftime %z is always zero instead of timezone offset.
On Python 3, datetime.now() too does not provide info about the local timezone:
>>> import time
>>> from datetime import datetime
>>> ts = time.time()
>>> time.strftime('%Z%z')
'CEST+0200'
>>> time.strftime('%Z%z', time.localtime(ts))
'CEST+0200'
>>> datetime.now().strftime('%Z%z')
''
>>> datetime.fromtimestamp(ts).strftime('%Z%z')
''
You could workaround it:
>>> from datetime import timezone
>>> datetime.now(timezone.utc).astimezone().strftime('%Z%z')
'CEST+0200'
>>> datetime.fromtimestamp(ts, timezone.utc).astimezone().strftime('%Z%z')
'CEST+0200'
If you want to work with datetime in Python 3; your code could look like:
#!/usr/bin/env python3
import json
from datetime import datetime, timedelta, timezone
epoch = datetime(1970, 1, 1, tzinfo=timezone.utc)
local_time = datetime.now(timezone.utc).astimezone()
json_text = json.dumps(dict(
gpio="00000000",
timestamp=(local_time - epoch) // timedelta(seconds=1),
formatted_time=local_time.strftime("%A %b %d %X"),
time_zone=read_tz_file(),
firmware="0.0"))

Formatting Time as %d-%m-%y

am trying to print orig_time as 6/9/2013 and running into following error..can anyone provide inputs on what is wrong here
Code:
orig_time="2013-06-09 00:00:00"
Time=(orig_time.strftime('%m-%d-%Y'))
print Time
Error:-
Traceback (most recent call last):
File "date.py", line 2, in <module>
Time=(orig_time.strftime('%m-%d-%Y'))
AttributeError: 'str' object has no attribute 'strftime'
You cannot use strftime on a string as it is not a method of string, one way to do this is by using the datetime module:
>>> from datetime import datetime
>>> orig_time="2013-06-09 00:00:00"
#d is a datetime object
>>> d = datetime.strptime(orig_time, '%Y-%m-%d %H:%M:%S')
Now you can use either string formatting:
>>> "{}/{}/{}".format(d.month,d.day,d.year)
'6/9/2013'
or datetime.datetime.strftime:
>>> d.strftime('%m-%d-%Y')
'06-09-2013'
>>> import time
>>> time.strftime("%m-%d-%y",time.strptime("2013-06-09 00:00:00","%Y-%m-%d %H:%M:%S"))
'06-09-13'
but its more of a pain to remove leading zeros ... If you need that use the other answer
also its unclear what you want, since your title says one thing (and your format string), but it does not match what you say is your expected output in the question
import time
now1 = time.strftime("%d-%m-%y", time.localtime())
print(now1)
If you'd prefer, you can change the "d-m-y" as you want and can use a static time.
import time
orig_time="2013-06-09 00:00:00"
Time= time.strftime(orig_time, '%m-%d-%Y')
print Time

Categories

Resources