0

I am trying to convert a datetime from an API that stores datetime values as UTC. I need to convert the datetime to my local time 'Pacific/Auckland'

The API I am using is Sunrise-Sunset https://sunrise-sunset.org/api

The specific location I am requesting is Christchurch, New Zealand https://sunrise-sunset.org/search?location=christchurch

import requests

api_url = 'https://api.sunrise-sunset.org/json?lat=-43.525650&lng=172.639847&formatted=0'
response = requests.get(api_url)

if response.status_code == 200:
    sunset_today = response.json()['results']['sunset']
    print(sunset_today) # outputs '2021-09-26T06:31:41+00:00'

I have searched StackOverflow and Google extensively, but cannot seem to find a solution that fits my needs.

The question I am asking is

  1. How can I convert the UTC value to my local datetime ('Pacific/Auckland')?

FYI, I don't want to add bloat to the application, but from previous (unsuccessful) attempts at solving this problem I have already installed the tzlocal and pytz packages.

I am writing my application in Django 3.2.7 and have adjusted my settings.py TIME_ZONE = 'Pacific/Auckland'

Edit When trying to convert the string to a datetime I get the following error. time data '2021-09-26T06:31:41+00:00' does not match format '%Y-%m-%dT%H:%M:%S %Z'

sunset_today = response.json()['results']['sunset']
format = '%Y-%m-%dT%H:%M:%S %Z'
parsed_date = datetime.strptime(sunset_today, format)
print(parsed_date) 

# ERROR: time data '2021-09-26T06:31:41+00:00' does not match format '%Y-%m-%dT%H:%M:%S %Z'*
  • So why don't use correct lat/lng for Christchurch? `https://api.sunrise-sunset.org/json?lat=-43.530955&lng=172.6366455&formatted=0` should give you `2021-09-26T06:31:42+00:00` – Andrej Kesely Sep 26 '21 at 11:16
  • Whoops, I originally had it correct, but changed it to another zone for testing purposes and forgot to put it back. I have updated `api_url = 'https://api.sunrise-sunset.org/json?lat=-43.525650&lng=172.639847&formatted=0'` –  Sep 26 '21 at 11:19
  • @AndrejKesely thanks for pointing out my mistake, I have updated my post (the correct UTC time is displayed), but sill not sure how to convert it to my local time –  Sep 26 '21 at 11:23
  • 1
    Parse the string to datetime and set the timezone? e.g. https://stackoverflow.com/a/63628816/10197418 – FObersteiner Sep 26 '21 at 11:26
  • @MrFuppes, thanks for sending that link. I have tried to convert the string to a datetime but keep getting an error `time data '2021-09-26T06:31:41+00:00' does not match format '%Y-%m-%dT%H:%M:%S %Z'` I'm not sure how to convert it? –  Sep 26 '21 at 11:37
  • 1
    I think @Gasanov has a good answer to this. You don't need third party libs like pytz or dateutil. strptime directive by the way should be `'%Y-%m-%dT%H:%M:%S%z'` – FObersteiner Sep 26 '21 at 12:10
  • @MrFuppes yeah it displayed the (+13:00) value when displayed in my browser but when I printed the value to the terminal, it displayed the (+00:00) time? Is this behavior normal? It makes me think that my browser is doing the conversion? Which could impose problems if overseas users are visiting the site wanting to get the sunset time for Christchurch? . . . but I could be wrong? –  Sep 26 '21 at 12:17
  • Not sure but *I'd expect* that internally it's all handled in UTC (+00:00), and only converted to local tz in the browser to give users a better experience. – FObersteiner Sep 26 '21 at 12:22

2 Answers2

0

To convert timezone aware string to python datetime easier to use fromisoformat, since you are getting ISO formatted string from API anyway:

import datetime

sunset_today = response.json()['results']['sunset']
parsed_date = datetime.datetime.fromisoformat(sunset_today)
# 2021-09-26 06:31:41+00:00
Gasanov
  • 2,839
  • 1
  • 9
  • 21
  • Thanks this worked when viewing the result in the browser, but not when I print the to the terminal. The terminal still displays the UTC time, but the browser showed the converted time. Why is this happening? and how does `fromisoformat` know my time offset (+13:00)? –  Sep 26 '21 at 12:13
  • Although this does not print the correct output in the terminal (maybe it's just me?), this does display the correct time in the browser. I will accept this as the answer. –  Sep 26 '21 at 12:28
0

I solved the problem using the dateutil and pytz library

import requests
import pytz
from dateutil import parser

api_url = 'https://api.sunrise-sunset.org/json?lat=-43.525650&lng=172.639847&formatted=0'
response = requests.get(api_url)

nz_zone = pytz.timezone('Pacific/Auckland')
        
if response.status_code == 200:
    sunset_today = response.json()['results']['sunset']
    converted_date = parser.parse(sunset_today).astimezone(nz_zone)
    print(converted_date) # outputs 2021-09-26 19:31:41+13:00