i've got a silly problem. I'm parsing Facebook user data, and I get the timezone as a number:
timezone: The user's timezone offset from UTC
For me ('America/Argentina/Buenos_Aires') it's -3.
Now, how can I convert that number to a pytz.timezone?
Thank you!
There's not a 1:1 correspondence, so there's no way to do it without making some assumptions that are bound to be invalid.
You can create your own tzinfo class that encodes the offset directly without trying to tie it back to a zone.
As #Mark Ransom said, multiple pytz.timezone may have the same UTC offset at a given date. You could print the mapping for a particular date:
#!/usr/bin/env python
from collections import defaultdict
from datetime import datetime
import pytz # $ pip install pytz
dt = datetime.now(pytz.utc) # current time in UTC
zone_names = defaultdict(list)
for tz in pytz.common_timezones:
zone_names[dt.astimezone(pytz.timezone(tz)).utcoffset()].append(tz)
for offset, zone in sorted(zone_names.items()):
print("%.1f %s" % (offset.total_seconds() / 3600, zone))
# -> -11.0 ['Pacific/Midway', 'Pacific/Niue', 'Pacific/Pago_Pago']
# ...
You can use tzinfo.tzname to get the zone name.
Related
I need to get a now() timestamp like this following: 2018-11-13T20:20:39+00:00 What is the correct format string for this?
To get an isoformat() string with time zone offset (the +00:00 at the end of the string) you need to supply a tzinfo object when constructing the datetime. the easiest way to do this is with the pytz library - pytz.timezone("UTC") returns the tzinfo for UTC.
There's another issue though, which is that technically that string doesn't quite match default isoformat() output because it has no microseconds. So a full example for the output requested would be:
import datetime
import pytz
datetime.datetime.now(tz=pytz.timezone("UTC")).replace(microsecond=0).isoformat()
This appears to be the isoformat.
You could use
import datetime as dt
# Get current time in utc
# Because the datetime object is timezone aware the +00:00 will be printed
current_time = dt.datetime.now(dt.timezone.utc)
# timespec will round the solution upto seconds
iso_string = current_time.isoformat(timespec="seconds")
print(iso_string)
will print 2019-11-19T19:51:46+00:00.
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'd like to use the timestamp from a database result and convert it to my locale time format. The timestamp itself is saved in UTC format: 2015-03-30 07:19:06.746037+02. After calling print value.strftime(format) with the format %d.%m.%Y %H:%M %z the output will be 30.03.2015 07:19 +0200. This might be the correct way to display timestamps with timezone information but unfortunately users here are not accustomed to that. What I want to achieve is the following for the given timestamp: 30.03.2015 09:19. Right now I'm adding two hours via
is_dst = time.daylight and time.localtime().tm_isdst > 0
utc_offset = - (tine.altzone if is_dst else time.timezone)
value = value + timedelta(seconds=utc_offset)
I was wondering if there is a more intelligent solution to my problem. (timestamp.tzinfo has a offset value, can/should this be used instead? The solution needs to be DST aware too.)
In your question the timestamp is already in desired timezone, so you don't need to do anything.
If you want to convert it to some other timezone you should be able to use;
YourModel.datetime_column.op('AT TIME ZONE')('your timezone name')
or,
func.timezone('your timezone name', YourModel.datetime_column)
in SQLAlchemy level.
On python level, consider using pytz
You don't need to do conversions manually when you use time zone aware database timestamps unless the timezone you want to display is different from the system timezone.
When you read and write datetime objects to the database the timezone info of the datetime object is taken into account, this means what you get back is the time in the local time zone, in your case +0200.
This SO post answers how to get local time from a timezoned timestamp.
Basically, use tzlocal.
import time
from datetime import datetime
import pytz # $ pip install pytz
from tzlocal import get_localzone # $ pip install tzlocal
# get local timezone
local_tz = get_localzone()
# test it
# utc_now, now = datetime.utcnow(), datetime.now()
ts = time.time()
utc_now, now = datetime.utcfromtimestamp(ts), datetime.fromtimestamp(ts)
local_now = utc_now.replace(tzinfo=pytz.utc).astimezone(local_tz) # utc -> local
assert local_now.replace(tzinfo=None) == now
I am am given the following:
The offset of the user's time from GMT in minutes. For example, GMT+10 is
timezone_offset = 600.
I use pytz to get the current time in UTC:
from datetime import datetime
from pytz import timezone
now_utc = datetime.now(timezone('UTC'))
How do I the get the users time?
Thanks
You can add timedelta(hours=10) or timedelta(minutes=600) to the datetime object containing the UTC time.
However, it would be a better idea to store the timezone instead of the offset and then use Python's timezone functions to convert the time.
Please help me to change datetime object (for example: 2011-12-17 11:31:00-05:00) (including timezone) to Unix timestamp (like function time.time() in Python).
Another way is:
import calendar
from datetime import datetime
d = datetime.utcnow()
timestamp=calendar.timegm(d.utctimetuple())
Timestamp is the unix timestamp which shows the same date with datetime object d.
import time
import datetime
dtime = datetime.datetime.now()
ans_time = time.mktime(dtime.timetuple())
Incomplete answer (doesn't deal with timezones), but hopefully useful:
time.mktime(datetime_object.timetuple())
** Edited based on the following comment **
In my program, user enter datetime, select timezone. ... I created a timezone list (use pytz.all_timezones) and allow user to chose one timezone from that list.
Pytz module provides the necessary conversions. E.g. if dt is your datetime object, and user selected 'US/Eastern'
import pytz, calendar
tz = pytz.timezone('US/Eastern')
utc_dt = tz.localize(dt, is_dst=True).astimezone(pytz.utc)
print calendar.timegm(utc_dt.timetuple())
The argument is_dst=True is to resolve ambiguous times during the 1-hour intervals at the end of daylight savings (see here http://pytz.sourceforge.net/#problems-with-localtime).