A Elo
A Elo

Reputation: 87

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.

Upvotes: 1

Views: 4637

Answers (3)

jfs
jfs

Reputation: 414129

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"))

Upvotes: 1

umläute
umläute

Reputation: 31274

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)

Upvotes: 1

Open AI - Opting Out
Open AI - Opting Out

Reputation: 24133

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'))

Upvotes: 3

Related Questions