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.
Related
I'm trying to wrap my head in understanding the implication of using .utcnow vs. .now on Python's DateTime.
Here's the reason for my confusion: I live in France. Right now, we have a +1 hour on the UTC timezone (CET timezone in winter (now) / CEST (+2) timezone in summer).
If I take the following value :
dt = datetime.datetime.utcnow()
dt.strftime('%c') # Thu Dec 9 16:17:38 2021
int(dt.timestamp()) # 1639063064
This is correct as it is, in France right now, 17h17.
So, from my understanding, that timestamp, 1639063064, is the UTC representation of the time since EPOCH.
But if I test this value in the website Epoch Converter, I get
GMT: Thursday 9 December 2021 15:17:44
Your time zone: jeudi 9 décembre 2021 16:17:44 GMT+01:00
It seems that the website ALSO subtracts my timezone to an already "substracted" value, ending in removing twice the timezone and causing an invalid value.
The actual confusion is when I tried to import that UTC timestamp to Luxon on my front app, doing the following doesn't work :
DateTime.fromMillis(parseInt(ts), { zone: 'utc' }).toLocal().setLocale('en')
I'm one hour behind.
How can I "tell" Luxon that the current TS is in the UTC timezone, and calling toLocal will apply the proper user's timezone ?
It seems that the website ALSO substract my timezone t
No, epochconverter.com isn't doing anything. The value 1639063064 really does represent 2021-12-09T15:17:44Z. That's not the value you want.
I'm no Python expert, but I believe the problem is the combination of this utcnow() behavior (emphasis mine):
Return the current UTC date and time, with tzinfo None.
This is like now(), but returns the current UTC date and time, as a naive datetime object.
And this timestamp() behavior:
Naive datetime instances are assumed to represent local time and this method relies on the platform C mktime() function to perform the conversion.
It sounds like you want to follow this advice:
An aware current UTC datetime can be obtained by calling datetime.now(timezone.utc).
So just change your first line to:
dt = datetime.now(timezone.utc)
... and it should be okay.
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!
Users of my app enter planned events providing
date
start time
end time
geographic location (on a map)
I'd like to convert the dates and times to UTC. My app is on GAE (Python), so tools like timezonefinder or pytzwhere are not working (modules have dependencies not supported on the GAE runtime).
Using an online API would be a solution. So far I checked the Google Timezone API. You provide it a geographic location and it will return the timezone information. To deal with DST however, you must provide it with a timestamp as well. Oddly enough, you must provide the UTC timestamp as input, and that's exactly what I want as output!
I can give it a timestamp based on my local datetime information (so without timezone correction) and it will return me the rawOffset and dstOffset that I need to convert my local datetime to UTC, but it may be incorrect for datetimes during some period around the DST transit ([-12h, +12 hours], I reckon, depending on the actual offset), because I didn't provide the correct UTC timestamp.
Is there an obvious (online) method for converting local datetime to UTC datetime based on geographic location?
One way to gain some accuracy that I thought of is to apply the rawOffset and dstOffset that I receive from the API, generate the UTC timestamp again and call the API once more with that timestamp. The period around DST transit where my results could be incorrect should now be limited to +/-1 hour. But that's over the top to my impression, also considering the quota on the API.
In order to convert local datetime info to UTC based on geographic location, you could just pass an arbitrary timestamp to the Google Time Zone API with the primary purpose of retrieving the timeZoneId for the location.
Example Request:
https://maps.googleapis.com/maps/api/timezone/json?location=39.6034810,-119.6822510×tamp=0&key=YOUR_API_KEY
Example Response:
{
"dstOffset" : 0,
"rawOffset" : -28800,
"status" : "OK",
"timeZoneId" : "America/Los_Angeles",
"timeZoneName" : "Pacific Standard Time"
}
Then you could use the timeZoneId and user entered date and time info along with pytz to create a python datetime object in the local time and also get the UTC timestamp I think you are looking for. This approach will handle daylight savings based on the user entered date. For example:
from datetime import datetime
from pytz import timezone, utc
pacific = timezone('America/Los_Angeles')
pdt = pacific.localize(datetime(2018, 5, 1, 8, 0, 0))
pst = pacific.localize(datetime(2018, 12, 1, 8, 0, 0))
pdt_utc = pdt.astimezone(utc)
pst_utc = pst.astimezone(utc)
# Pacific Daylight Time
print(pdt)
# 2018-05-01 08:00:00-07:00
# Pacific Standard Time
print(pst)
# 2018-12-01 08:00:00-08:00
# UTC
print(pdt_utc)
# 2018-05-01 15:00:00+00:00
print(pst_utc)
# 2018-12-01 16:00:00+00:00
Important: I haven't tested this with all the possible return values from the API for timeZoneId to ensure that what is returned from the API will be correctly interpreted by pytz (it works with the example time zone "America/Los_Angeles" but you would need to test to be sure it was a robust solution for the geographies you are dealing with).
In your web pages, you can use the JavaScript function getTimezoneOffset to calculate the time difference between the user local time and UTC time:
The getTimezoneOffset() method returns the time zone difference, in
minutes, from current locale (host system settings) to UTC.
Then, you can add a parameter to all URL which require the Time zone offset. Another solution is to put this in a cookie.
From the server side, you can retrieve the time zone offset to calculate UTC dates/times.
I'm grabbing a UTC timestamp from Javascript and passing it to my python code. I want to store that date as a datetime, so I construct it with dt = datetime.datetime.fromtimestamp(int(starttime) / 1000). I check the timestamp and it is for 12:00 am UTC on a specific date. However, when I print out this newly created datetime object, it prints as 19:00 from the day before.
There is clearly some timezone issues at work here, but I expect that the default should always be UTC (apparently I expect wrong). How do I get this to always operate under UTC, rather than have some weird timezone transformation at play?
The documentation for fromtimestamp states (emphasis mine):
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.
Thus fromtimestamp does indeed return a value for your local timezone (not UTC as you expected). What you want is utcfromtimestamp:
starttime = 1408060800000
dt = datetime.datetime.utcfromtimestamp(int(starttime) / 1000)
dt # returns the UTC time you expected:
# datetime.datetime(2014, 8, 15, 0, 0)
Just to be clear, this is python 2.6, I am using pytz.
This is for an application that only deals with US timezones, I need to be able to anchor a date (today), and get a unix timestamp (epoch time) for 8pm and 11pm in PST only.
This is driving me crazy.
> pacific = pytz.timezone("US/Pacific")
> datetime(2011,2,11,20,0,0,0,pacific)
datetime.datetime(2011, 2, 11, 20, 0, tzinfo=<DstTzInfo 'US/Pacific' PST-1 day, 16:00:0 STD>)
> datetime(2011,2,11,20,0,0,0,pacific).strftime("%s")
'1297454400'
zsh> date -d '#1297454400'
Fri Feb 11 12:00:00 PST 2011
So, even though I am setting up a timezone, and creating the datetime with that time zone, it is still creating it as UTC and then converting it. This is more of a problem since UTC will be a day ahead when I am trying to do the calculations.
Is there an easy (or at least sensical) way to generate a timestamp for 8pm PST today?
(to be clear, I do understand the value of using UTC in most situations, like database timestamps, or for general storage. This is not one of those situations, I specifically need a timestamp for evening in PST, and UTC should not have to enter into it.)
There are at least two issues:
you shouldn't pass a timezone with non-fixed UTC offset such as "US/Pacific" as tzinfo parameter directly. You should use pytz.timezone("US/Pacific").localize() method instead
.strftime('%s') is not portable, it ignores tzinfo, and it always uses the local timezone. Use datetime.timestamp() or its analogs on older Python versions instead.
To make a timezone-aware datetime in the given timezone:
#!/usr/bin/env python
from datetime import datetime
import pytz # $ pip install pytz
tz = pytz.timezone("US/Pacific")
aware = tz.localize(datetime(2011, 2, 11, 20), is_dst=None)
To get POSIX timestamp:
timestamp = (aware - datetime(1970, 1, 1, tzinfo=pytz.utc)).total_seconds()
(On Python 2.6, see totimestamp() function on how to emulate .total_seconds() method).
Create a tzinfo object utc for the UTC time zone, then try this:
#XXX: WRONG (for any timezone with a non-fixed utc offset), DON'T DO IT
datetime(2011,2,11,20,0,0,0,pacific).astimezone(utc).strftime("%s")
Edit: As pointed out in the comments, putting the timezone into the datetime constructor isn't always robust. The preferred method using the pytz documentation would be:
pacific.localize(datetime(2011,2,11,20,0,0,0)).astimezone(utc).strftime("%s")
Also note from the comments that strftime("%s") isn't reliable, it ignores the time zone information (even UTC) and assumes the time zone of the system it's running on. It relies on an underlying C library implementation and doesn't work at all on some systems (e.g. Windows).