python-3.xflaskjinja2flask-sqlalchemypythonanywhere

Time discrepancy between local and PythonAnywhere environments (5-hour difference in datetime calculation)


I am encountering an issue where my time calculations are producing different results in two environments:

Local Environment: MacBook Air, time zone set to Ecuador (UTC-5). PythonAnywhere: UK-based server (UTC+0). I use a function datetime_continental() to ensure that the time is calculated based on Ecuador's time zone (UTC-5), regardless of the server location. Here is the function:

import pytz
from datetime import datetime

def datetime_continental():
    ecuador_tz = pytz.timezone('America/Guayaquil')
    return datetime.now(ecuador_tz)

The goal is to compare a constant KPI_AWAITING_TIME (set to 1 minute) with the result of subtracting turno.hora from datetime_continental.now(). The logic is implemented in a Jinja2 template as follows:

{% if datetime_continental.now() - turno.hora > KPI_AWAITING_TIME %}
{{ "GO TO RECEPTION" }}
{% else %}
{{ datetime_continental.now() - turno.hora }}
{% endif %}

This comparison works perfectly on my local machine. Here's a screenshot of the result on my local system, which correctly shows 0:00:29.170766 without adding 5 hours to the time:

correctly shows 0:00:29.170766 without adding 5 hours to the time

However, when running the same code on PythonAnywhere, the result unexpectedly adds 5 hours to the time. For example, the output on PythonAnywhere shows 5:00:33.440425, which is a 5-hour difference from the expected value:

the output on PythonAnywhere shows 5:00:33.440425, which is a 5-hour difference from the expected value

Questions:

  1. Does the function datetime_continental() handle the time zone conversion correctly, ensuring the Ecuadorian time zone (UTC-5) is applied consistently across environments?

  2. Why does PythonAnywhere show an additional 5 hours in the result, even though the same logic works correctly locally?

  3. Could this issue be related to PythonAnywhere's server configuration (possibly using UTC+0 by default), and how can I resolve this to make sure Ecuadorian time is used on both platforms?

SOLUTION: I wrote a new function called time_continental() which returns the data type datetime.time

def time_continental():

    '''
    Calculates the time according to the value of the
    TIME_ZONE constant, which will be configured with the
    constant value of the country where the application
    will be used. In the example, the
    time zone for ECUADOR_CONTINENTAL
    '''

    from pkg_app.data_dictionary import TIME_ZONE
    from zoneinfo import ZoneInfo
    from datetime import datetime
    
    
    datetime_timezone = datetime.now().astimezone(ZoneInfo(TIME_ZONE))    
    hora_continental = datetime_timezone.time()
    
    return hora_continental

Code segment that serves the .HTML template

from datetime import datetime

return render_template(
    time_continental = time_continental(),
    KPI_ESPERA       = KPI_ESPERA,
    lapseTime1       = datetime.now() - datetime.now(),
    lapseTime2       = datetime.now() - datetime.now(),
    ...)


<td class="text-info bg bg-dark">
{% set lapseTime2 = timedelta(days=0, hours=time_continental.hour, minutes=time_continental.minute, seconds=time_continental.second, microseconds=time_continental.microsecond) %}
{% set lapseTime1 = timedelta(days=0, hours=turno.hora.hour, minutes=turno.hora.minute, seconds=turno.hora.second, microseconds=turno.hora.microsecond) %}
{% set kpi_espera = KPI_ESPERA.total_seconds() %}
{% set lapseTime = lapseTime2 - lapseTime1 %}
{% set espera = lapseTime.total_seconds() %}
{% if espera > kpi_espera %}
{{ lapseTime }} -> <span class="badge bg-danger">{{ "GO TO RECEPTION"}}</span>
{% else %}
{{ lapseTime }}                         
{% endif %}
</td>

enter image description here


Solution

  • The possible issue is that turno.hora is lacking timezone information what might lead to PythonAnywhere assume it is UTC+0 and when you compare these two values extra 5 hours added.

    Make the both datetimes timezone aware. It should do the trick.