Reputation: 1913
I have date and time in one-string format "2016-03-28T20:23:46+0800". How to convert it to date-time format Sqlite3 supports in "datetime" domain? I'm using python to read/write data in database.
I know that it's possible to achive using python:
>>> str = "2016-03-28T20:23:46+0800"
>>> temp = str.split('T')
>>> temp[1] = temp[1].rstrip('+')
>>> temp[1]
'20:23:46+0800'
>>> temp[1] = temp[1].split('+')[0]
>>> result = " ".join(temp)
>>> result
'2016-03-28 20:23:46'
but maybe the given string has a convertible format?
Upvotes: 1
Views: 3373
Reputation: 17404
I would recommend you take the approach of using the sqlite3 text
format for datetimes, because these are human readable.
My first instinct was also to reach for integer
, but I soon realized this was a terrible idea when I had no idea what the values were when inspecting the database with a DBMS. (PS: My favorite tool right now is DBeaver CE.)
I would suggest you take the slightly arduous approach of creating a string in ISO8601 format, and then stripping off the 3 floating point digits off the end which are a higher precision than sqlite3 specifies.
(For some reason the sqlite3 documentation doesn't exactly follow the ISO8601 standard, which should have 6 decimal digits of floating point precision for the sub-seconds component. Instead they appear to use 3.)
Here's a function which does that for you. You can strip out my debugging output if you wish. PS: It was late when I wrote this. If I messed something up please let me know. I haven't tested it for cases where the fractional subseconds part produces zeros for the final 3 digits. I don't know if these are present in the original string produced by strftime
or not. I would assume that they are? Who knows. This implementation should cope either way, unless I messed something up.
import datetime
now = datetime.datetime.now()
now = now_to_sqlite3_iso8601(now)
print(now)
# helpful conversion function
def now_to_sqlite3_iso8601(now):
iso8601 = now.strftime("%Y-%m-%d %H:%M:%S.%f")
index = iso8601.find('.')
if index > 0:
ss = iso8601[index:]
print(f'ss={ss}')
length = len(ss)
if length > 4: # include the '.' character
len_to_remove = length - 4
final_len = len(iso8601) - len_to_remove
iso8601 = iso8601[0:final_len]
else:
print('warning \'.\' not found in string')
iso8601 = iso8601
print(f'iso8601: {iso8601}')
return iso8601
Upvotes: -1
Reputation: 414855
sqlite3
won't produce an error until you try to select the value back as datetime
object if you try to insert a timestamp in the wrong format. To validate the input date/time string, convert it to datetime.datetime
first. sqlite3
module can convert datetime.datetime
automatically:
#!/usr/bin/env python3
import sqlite3
from datetime import datetime
db = sqlite3.connect(':memory:')
db.execute('CREATE TABLE dates (timestamp TIMESTAMP)')
db.executemany('INSERT INTO dates VALUES(?)',
[[datetime.utcnow()], ['2016-03-28 20:23:46.000000+0800']])
print(*db.execute('SELECT timestamp FROM dates'), sep='\n')
('2016-05-14 05:08:52.487113',)
('2016-03-28 20:23:46.000000+0800',)
TIMESTAMP
field accepts a string in ISO 8601 format 'YYYY-MM-DD HH:MM:SS.mmmmmm'
or datetime.datetime
object.
To return datetime.datetime()
back, you could use detect_types=sqlite3.PARSE_DECLTYPES
(if you need the timezone support; define your own converter that returns timezone-aware datetime objects).
Upvotes: 1
Reputation: 489
date time format does not exist in sqlite, one work around is to use number sequence as date time for example:
def Strtime2Num(result):
date_object = datetime.strptime(Strtime,"%Y-%m-%dT%H:%M%S+0800")
Strtime = date_object.strftime('%Y%m%d%H%M')
return int(result)
when select in sql command, you can use
con.execute(UPDATE YearUpdateCapa SET %s = %d WHERE DateTime >= %d AND DateTime <= %d' % (name, avail,start,end))
Upvotes: 1