user51819
user51819

Reputation: 323

Convert numeric offset to a timezone?

There is a website that provides timezone information in the form of e.g. -07:00. Is there a way I can use this to localize a timestamp in pytz?

Normally I am doing this:

EASTERN_TIMEZONE = pytz.timezone("US/Eastern")
date_in_pacific_time = EASTERN_TIMEZONE.localize(my_date)

where my_date is some datetime date. But I don't know how to take a number and get the timezone from it so I can apply it to the date and get a timestamp from it.

This may be an XY question though because what I want to do is take a date string like "2021-04-02T18:30:04-07:00" and convert it to a Unix UTC timestamp.

Edit:

Like this?

listing_date_string = "2021-04-02T18:30:04-07:00"
listing_date_string_datepart = listing_date_string[:19]
listing_date_string_timezone = int(listing_date_string[19:].replace(":00", ""))
d = datetime.datetime.strptime(listing_date_string_datepart, '%Y-%m-%dT%H:%M:%S')
d -= datetime.timedelta(hours=listing_date_string_timezone)

print(int(d.timestamp()))  # outputs 1617427804

Upvotes: 1

Views: 925

Answers (3)

FObersteiner
FObersteiner

Reputation: 25554

Python < 3.7 - from the docs:

Changed in version 3.7: When the %z directive is provided to the strptime() method, the UTC offsets can have a colon as a separator between hours, minutes and seconds.

Vice versa that means that with older Python versions, %z won't parse a UTC offset with a colon as hours/minutes separator. You can work around like

from datetime import datetime
# your input
s = "2021-04-02T18:30:04-07:00"
# parse separately, colon removed from UTC offset
tz = datetime.strptime(s[19:].replace(':', ''), '%z').tzinfo
dtobj = datetime.strptime(s[:19], "%Y-%m-%dT%H:%M:%S").replace(tzinfo=tz)
print(repr(dtobj))
datetime.datetime(2021, 4, 2, 18, 30, 4, tzinfo=datetime.timezone(datetime.timedelta(-1, 61200)))

If you know the time zone, you can skip parsing the UTC offset:

import pytz
tz = pytz.timezone('US/Pacific')
dtobj = tz.localize(datetime.strptime(s[:19], "%Y-%m-%dT%H:%M:%S"))
print(repr(dtobj))
datetime.datetime(2021, 4, 2, 18, 30, 4, tzinfo=<DstTzInfo 'US/Pacific' PDT-1 day, 17:00:00 DST>)

Note: pytz is deprecated with the release of Python 3.9 - you now have zoneinfo in the standard lib.


On Python 3.7+ you can just use fromisoformat;

dtobj = datetime.fromisoformat(s)

and change from UTC offset to an actual time zone like

dtobj.astimezone(tz) # tz is a timezone object from pytz, dateutil, zoneinfo...
Out[9]: datetime.datetime(2021, 4, 2, 18, 30, 4, tzinfo=<DstTzInfo 'US/Pacific' PDT-1 day, 17:00:00 DST>)

Upvotes: 1

Simon
Simon

Reputation: 421

does this work on your side?

import datetime

dt = datetime.datetime.strptime(
    "2021-04-02T18:30:04-07:00", 
    "%Y-%m-%dT%H:%M:%S%z"
    )
print(
    dt.year,
    dt.month,
    dt.day,
    dt.hour,
    dt.minute,
    dt.second,
    dt.tzinfo,
    )
2021 4 2 18 30 4 UTC-07:00

Upvotes: 0

J_H
J_H

Reputation: 20450

For question X, it is not in general feasible. But you have some candidate timezones in mind, like

  • US/Pacific
  • America/Phoenix
  • US/Mountain (same as America/Denver)

so you could try each one to see if it matches -7 hours.

Some days Denver is at -7 hours, on other days Los Angeles is at -7 hours. And Phoenix is at -7 hours all the time.

Note that a timezone, like US/Mountain, is quite different from a zone offset, like -7 hours.

For question Y, well, that's easy! Just treat the first part as UTC, then apply the remaining -7 hour correction.

Upvotes: 1

Related Questions