I'm using python to create a datetime value with Europe/London timezone:
import datetime
from pytz import timezone, utc
now_utc = datetime.datetime.now()
now_uk = now_utc.astimezone(timezone('Europe/London')) # convert to local time
I then want to add this value to a SQL database using sqlite3 within python.
cursor = con.cursor()
sql_data = ("INSERT INTO TCADATA (datetime, gym1) VALUES (datetime(:datetime), :gym1;")
cursor.execute(sql_data, {"datetime":now_uk, "gym1":data["gym1"]})
The value that gets added to the SQL database is one hour different from my London timezone, so if it's 16:00 here, the value in the database is 15:00.
My guess is that SQLite3 is converting the datetime to UTC.
How do I specify to sqlite that the value is a London time zone? I would prefer to specify London like I have done with python, rather than GMT since this changes at daylight savings.
Or perhaps it would be simpler to keep it as UTC and convert it to London time when the data is read?
I think the best way to get round this issue is to either store the datetimes in UTC timezone on the server and convert to local time zones as needed when retrieving the data in python.
Related
I have the following timestamp 1550588656 which translates to 2019-02-19 15:04:16+00:00 in UTC time convention.
I want to convert it to my country's time convention (UTC or GMT -3 in this time of the year) so it should translate to 2019-02-19 12:04:16+00:00
I have read on other SO questions that first I have to convert the timestamp to an UTC aware Datetime object and then localize it, I'm doing it like this
# string format time
naive_datetime = datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S')
# string parse time
naive_datetime = datetime.strptime(naive_datetime, "%Y-%m-%d %H:%M:%S")
# make naive Datetime object UTC aware
utc_datetime = naive_datetime.replace(tzinfo=pytz.UTC)
So now it's not a naive Datetime object, from here I should be able to localize it to my country's timezone. In Python that is pytz.timezone('America/Santiago')
So it should go something like this
cltime = pytz.timezone('America/Santiago')
local_datetime = utc_datetime.astimezone(cltime)
But I'm getting 2019-02-19 09:04:16-03:00 (UTC or GTM -6 ) as a result and I don't know why.
Can someone explain? My intuition tells me it's probably a simple thing I'm not looking at, but I've spent some minutes in it and I haven't been able to tell yet.
If you look at the documentation for fromtimestamp:
Return the local date and time corresponding to the POSIX timestamp
So the problem is that it is already doing a conversion from UTC to the local time, and you're doing it a second time.
First of all you have epoc time (UTC timestamp). You need to convert it into datetime object (native) which is followed by converting native time to aware time and than finally convert it to your local time.
Convert your timestamp to native datetime object
native_datetime = datetime.fromtimestamp(1550588656)
convert native datetime object to aware time (add timezone info, will add timezone info to native timezone UTC for current)
import pytz
utc_time = native_datetime.replace(tzinfo=pytz.timezone("UTC"))
localising aware datetime to your local datetime
local_time = utc_time.astimezone(pytz.timezone("America/Santiago"))
You can replace "America/Santiago" with your local time zone
I think this would help you to solve your problem. Thanks!
I have the following code:
import datetime
dt = 1546955400
print(datetime.datetime.fromtimestamp(dt))
When I run this code on my local machine, I get the correct (expected) time which is
2019-01-08 15:50:00.
However I tried running this exact same code on a VM and the result was
2019-01-08 13:50:00 (two hours earlier). Why is this is happening and how can I fix it so that I always get the first one regardless of where the code is running?
datetime.datetime.fromtimestamp() returns local time. From the documentation:
Return the local date and time corresponding to the POSIX timestamp, such as is returned by time.time(). If optional argument tz is None or not specified, the timestamp is converted to the platform’s local date and time, and the returned datetime object is naive.
The timestamp value is an offset in seconds from the UNIX epoch value, midnight 1 January 1970, in the UTC timezone. The local time is a system-wide configured offset from UTC, the local timezone.
If your VM is producing unexpected results, you need to configure the timezone of the OS.
Alternatively, ignore timezones and only deal with time in the UTC timezone. For timestamps, that means using the datetime.datetime.utcfromtimestamp() function.
Your specific timestamp is 13:50 UTC:
>>> dt = 1546955400
>>> from datetime import datetime
>>> datetime.utcfromtimestamp(dt)
datetime.datetime(2019, 1, 8, 13, 50)
>>> print(_)
2019-01-08 13:50:00
so your VM is either set to the UTC or the GMT timezone (the latter is currently at UTC+0, until the switch to the UK daylight saving timezone BST). Your local system is in a UTC+2 timezone, given your stated location from your profile that'd be EEE, Easter European Time.
Another option is to create a timezone-aware timestamp by passing in a tz argument. If you have a specific UTC offset, just create a datetime.timezone() instance for that offset:
utcplus2 = datetime.timezone(datetime.timedelta(hours=2))
datetime.datetime.fromtimestamp(dt, utcplus2)
However, it is usually better to store and operate on UTC datetime instances everywhere, and only convert to specific timezones when displaying information to users. This simplifies datetime handling as it lets you avoid a number of timezone corner cases and problems, such as mixing datetime information from different timezones and timezones with a summer and winter time distinction.
Currently i have the following timestamp format as below :
2018-04-02T09:00:00+09:30
How can i convert the timestamp above to suit the postgres's timestamp column like below?
2018-04-02 09:00:00 +09.30
Also how can use python to convert the xml timestamp first before loading into postgres table?
This doesn't require any conversion whatsoever, it's a regular ISO 8601 time stamp. PostgreSQL supports multiple input formats for time stamps
select timestamp with time zone '2018-04-02T09:00:00+09:30';
timestamptz
------------------------
2018-04-01 18:30:00-05
(1 row)
You'll notice it's storing it in UTC. That's what you want. From the docs,
For timestamp with time zone, the internally stored value is always in UTC (Universal Coordinated Time, traditionally known as Greenwich Mean Time, GMT). An input value that has an explicit time zone specified is converted to UTC using the appropriate offset for that time zone. If no time zone is stated in the input string, then it is assumed to be in the time zone indicated by the system's TimeZone parameter, and is converted to UTC using the offset for the timezone zone.
When a timestamp with time zone value is output, it is always converted from UTC to the current timezone zone, and displayed as local time in that zone. To see the time in another time zone, either change timezone or use the AT TIME ZONE construct (see Section 9.9.3).
If you know you will always get your data in that format, you can do something like:
>>> a = "2018-04-02T09:00:00+09:30"
>>>
>>> b = a.replace('T', ' ').replace('+', ' +')
>>> b
'2018-04-02 09:00:00 +09:30'
It is ugly, but it works.
It is always safer to interpret your input as a date and then print it in the desired format.
I am working on a raspberry project which adds variables into a sqlite database
curs.execute("INSERT INTO EntryLog(EntryTime)VALUES(?)",(time)
to make this work how can I make put current datetime value into time? (EntryTime is DATETIME value in sql, I need date and time in the same column)
You need to format time as string in format Y-m-d like time.strftime('%Y-%m-%d')
from datetime import datetime
time=datetime.now()
curs.execute("INSERT INTO EntryLog(EntryTime)VALUES(?)",(time.strftime('%Y-%m-%d'))
There are datetimes that are uploaded to DB by Django in the format “2015-10-31 17:00:00+03” (aware form of time).
PostgreSQL keeps time in UTC
In pgAdmin I see my datetimes as “2015-10-31 17:00:00+03” instead of UTC.
Is it possible to get from DB “2015-10-31 17:00:00+03” instead of “2015-10-31 14:00:00+00”? As I understand, if datetime is aware, there is TZ info in the value in DB, but how to take this TZ?
For example, I want to upload a new datetimes, but before to write to DB, I want to compare these datetimes with the values that already exist in the database. So, a new part of datetimes have format:
“2015-10-31 17:00:00+03”, but the values are taken from the database is UTC, ie
“2015-10-31 14:00:00+00”, when it should be also 17:00:00+03!
How to get value from DB not in UTC, but in TZ +3 (for this example)?
test = Shows.objects.get(name = 'Test')
test.date_time # I get UTC, but I need to get it as TZ +3
PS: hardcoding like this
from pytz import timezone
right_time = utc_from_db.astimezone(timezone('Europe/Berlin'))
is impossible. It is necessary to get exactly the time zone from the database that was originally filled with a value, because all datetimes may have different time zone.
As I was informed, seems it is impossible. PostgreSQL uses TZ from awared type of time to convert time to UTC and can't be converted back natively.
If I want to get back UTC-ed time from DB to the time with TZ it was initially, I can make one more column in DB and put there the name of TZ, such as 'Europe/Berlin' and convert time from DB with UTC to initial time with proper TZ like this (the same code as in the question part):
from pytz import timezone
right_time = utc_from_db.astimezone(timezone('Europe/Berlin'))