Several endpoints using reltime(): TypeError: can't subtract offset-naive and offset-aware datetimes #15

Closed
opened 2025-11-20 12:53:05 -06:00 by digimint · 8 comments
Owner

When deploying with gunicorn and using postgres as a backing database, something goes wrong with the reltime() helper function. The invite code is successfully generated, but flask is then unable to render the result due to the aforementioned errors involving datetime arithmetic, thus leaving the afflicted pages permanently offline.

When deploying with gunicorn and using postgres as a backing database, something goes wrong with the `reltime()` helper function. The invite code is successfully generated, but flask is then unable to render the result due to the aforementioned errors involving datetime arithmetic, thus leaving the afflicted pages permanently offline.
Author
Owner

Seems like the database info is okay, but datetime.now() is returning timezone-unaware in prod???

i just checked and it seems like it's doing the same thing on my local machine, but it didn't cause problems in that case - probably because sqlite didn't store the timezone info.

Seems like the database info is okay, but `datetime.now()` is returning timezone-unaware in prod??? i just checked and it seems like it's doing the same thing on my local machine, but it didn't cause problems in that case - probably because sqlite didn't store the timezone info.
Author
Owner

A quick test indicates that using zoneinfo.ZoneInfo to insert a timezone into the locally-stored datetimes seems to resolve the issue. Need to turn this into a patch.

A quick test indicates that using `zoneinfo.ZoneInfo` to insert a timezone into the locally-stored datetimes seems to resolve the issue. Need to turn this into a patch.
digimint added this to the Taskflower v0.1.0 project 2025-11-20 13:30:26 -06:00
Author
Owner

it's happening in the expiration verification functions as well, bc of course it is.

it's happening in the expiration verification functions as well, bc of course it is.
Author
Owner

Files that need to be fiddled with:

  • __init__.py
  • auth/startup.py
  • db/model/codes.py
  • form/user.py
  • sanitize/task.py
  • web/invite/__init__.py
Files that need to be fiddled with: - `__init__.py` - `auth/startup.py` - `db/model/codes.py` - `form/user.py` - `sanitize/task.py` - `web/invite/__init__.py`
Author
Owner

Current plan is to implement timezone awareness in util/time, and switch everything over from datetime.now() to a timezone-aware system. Also going to try and implement client-side timestamp rendering while i'm at it.

Current plan is to implement timezone awareness in `util/time`, and switch everything over from `datetime.now()` to a timezone-aware system. Also going to try and implement client-side timestamp rendering while i'm at it.
Author
Owner

The template macro reltime() (usable within the codebase as util.time.render_reltime()) has been updated to return something like:

<span class="render-delta" data-timestamp="1763729100.0">
    23 minutes ago
</span>

Now, we can use javascript on the client side to update the timestamp in real time, but users with js disabled will still get a correct value (based on the time they requested the page).

Also, we now have abstime() (util.time.render_abstime within the codebase) which renders:

<span class="render-timestamp" data-timestamp="1763729100.0">
    2025-11-21 12:45:00
</span>

ALSO, we have util.time.from_local() which we need to use to ingest time data from the user. i'm thinking we use an invisble field on all forms that take in time (at present, that's just the task creation field).

ALSO, i'm working on parsing functions to make the input more user-friendly (so you can put in a due date as 'tomorrow' or 'next week')

The template macro `reltime()` (usable within the codebase as `util.time.render_reltime()`) has been updated to return something like: ```html <span class="render-delta" data-timestamp="1763729100.0"> 23 minutes ago </span> ``` Now, we can use javascript on the client side to update the timestamp in real time, but users with js disabled will still get a correct value (based on the time they requested the page). Also, we now have `abstime()` (`util.time.render_abstime` within the codebase) which renders: ```html <span class="render-timestamp" data-timestamp="1763729100.0"> 2025-11-21 12:45:00 </span> ``` ALSO, we have `util.time.from_local()` which we need to use to ingest time data from the user. i'm thinking we use an invisble field on all forms that take in time (at present, that's just the task creation field). ALSO, i'm working on parsing functions to make the input more user-friendly (so you can put in a due date as 'tomorrow' or 'next week')
Author
Owner

Structure of a 'relative' user timestamp is something like:

(
    YESTERDAY
   |TODAY
   |TOMORROW
   |((LAST |NEXT )?(MONDAY|TUESDAY|WEDNESDAY|THURSDAY|FRIDAY|SATURDAY|SUNDAY|WEEK|MONTH|YEAR|DECADE|CENTURY))
   |((IN ?)[0-9] (SECONDS?|MINUTES?|HOURS?|DAYS?|WEEKS?|MONTHS?|YEARS?|DECADES?|CENTURIES?)( AGO)?)
)

We can probably have both the relative time and the date picker, and let users fill out one or the other.

Structure of a 'relative' user timestamp is something like: ``` ( YESTERDAY |TODAY |TOMORROW |((LAST |NEXT )?(MONDAY|TUESDAY|WEDNESDAY|THURSDAY|FRIDAY|SATURDAY|SUNDAY|WEEK|MONTH|YEAR|DECADE|CENTURY)) |((IN ?)[0-9] (SECONDS?|MINUTES?|HOURS?|DAYS?|WEEKS?|MONTHS?|YEARS?|DECADES?|CENTURIES?)( AGO)?) ) ``` We can probably have both the relative time and the date picker, and let users fill out one or the other.
Author
Owner

taskflower.util.time now has several helper functions. taskflower.util.time.now() should be preferred over datetime.now() in most cases. taskflower.util.time.render_reltime() and render_abstime() should be used when rendering HTML for the user - or, from jinja, the always-available reltime() and abstime(). Make sure to mark the result as safe.

`taskflower.util.time` now has several helper functions. `taskflower.util.time.now()` should be preferred over `datetime.now()` in most cases. `taskflower.util.time.render_reltime()` and `render_abstime()` should be used when rendering HTML for the user - or, from jinja, the always-available `reltime()` and `abstime()`. Make sure to mark the result as safe.
Sign in to join this conversation.
No labels
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: digimint/taskflower#15
No description provided.