wagtail / bakerydemo

Next generation Wagtail demo, born in Reykjavik
BSD 3-Clause "New" or "Revised" License
972 stars 542 forks source link

TUE versus TUES, THU versus THURS #298

Closed Amondale closed 9 months ago

Amondale commented 3 years ago

Here on the Pacific Coast of the USA, I have tried adding a few of our local bakeries in Portland, OR [amondale/bakerydemo_nginx:app] and they stay closed all the time? It seems to be a Docker-specific issue, I changed settings/base.py to the following snippet:

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'America/Los_Angeles'

USE_I18N = True

USE_L10N = True

USE_TZ = True

as well as added the following two lines to my Dockerfile:

ARG ARG_TIMEZONE=America/Los_Angeles ENV ENV_TIMEZONE ${ARG_TIMEZONE}

and also in the Admin Settings, set TZ to America/Los Angeles but it seems everything evals to UTC somewhere in the code; this is from locations/models.py:

# Determines if the location is currently open. It is timezone naive

So please explain the use of the word "naive", as I cannot see the true open/closed status of any bakery in my neighborhood.

Really would be cool if we could figure TZ from Lat/Long, maybe I can scrounge a DB of TZ of all the world's major cities; then I can begin my blog of "Great Bakeries of the Whole World" and we could calculate T or F based on that tablespace. Maybe just scrapping the "Sorry location is closed" text would be the lazy coder's way out of the issue.

TIA, Alex

Amondale commented 3 years ago
lovejoy models models2
Amondale commented 3 years ago

Looks like the models.py in locations is honoring the TZ and has valid data back from the DB (using SQLite) but somehow failing on the opening_time__lte or closing_time__gte lines?

Amondale commented 3 years ago

AHA! This fixed the issue: [locations/choices.py] DAY_CHOICES = ( ('MON', 'Monday'), ('TUE', 'Tuesday'), ('WED', 'Wednesday'), ('THU', 'Thursday'), ('FRI', 'Friday'), ('SAT', 'Saturday'), ('SUN', 'Sunday'), )

Evidently the use of TUES and THURS versus TUE and THU was an issue when it hit the equate in models.py:

current_day = now.strftime('%a').upper()

I validated this in python 3.8 as well. Maybe those two days didn't translate from the Icelandic?

Amondale commented 3 years ago

I'd like to work on a fork based on this google API:

Maybe call gmaps API with lat/long to get current offset https://maps.googleapis.com/maps/api/timezone/json?location=12.9716,77.5946&timestamp=1629304488&key=xxxxxxxx

which returns this JSON: { dstOffset: 0, rawOffset: 19800, status: "OK", timeZoneId: "Asia/Calcutta", timeZoneName: "India Standard Time" }

from which could be calculated real time open hours, based on lat/long and operating hours from the model.

I tried the approach of adding this code to locations/models.py:

timezone = models.TextField(
    max_length=5,
    help_text="GMT offset that is naive (not aware of DST, example India \
               has GMT offset of 19800/3600 = 5.5 with no DST",
    default='0',
    validators=[
        RegexValidator(
            regex = r'^(\-?\d)+?(\.?[5]?){1,5}$',
            message ='Examples: -6.5|11|-3|3.5',
            code='invalid_tz'
        )
    ]
)

but it would be inaccurate in locations that transition to Daylight Savings Time twice per year. The google API (there are others but I haven't found one that doesn't need a "developer key" at minimum) solves the issue as it is real time, but, like the static map delivered on each location page, may require $$$. It is fairly reasonable to charge for this as the polygon/vector math and mapping shifting timezone and political boundaries required is CPU-intensive no doubt.

If anyone knows of a free DB of world cities with:

that data probably wouldn't be too much to add as a fixture file.

I'd like to hear whether this boat could/should float for a future revision?

allcaps commented 1 year ago

The comment states that the timezone is naive. To obtain the local time in the current time zone:

from django.utils import timezone
timezone.localtime(timezone.now())

I also think this code will render a string in your locale.

strftime('%a').upper()

That probably won't match the choice values:

DAY_CHOICES = (
    ("MON", "Monday"),
    ("TUES", "Tuesday"),
    ("WED", "Wednesday"),
    ("THUR", "Thursday"),
    ("FRI", "Friday"),
    ("SAT", "Saturday"),
    ("SUN", "Sunday"),
)