Skip to content

Add temporal utility as optional template variant#113

Merged
zahraaalizadeh merged 5 commits intomainfrom
utility/temporal
May 5, 2026
Merged

Add temporal utility as optional template variant#113
zahraaalizadeh merged 5 commits intomainfrom
utility/temporal

Conversation

@zahraaalizadeh
Copy link
Copy Markdown
Contributor

@zahraaalizadeh zahraaalizadeh commented Apr 30, 2026

This change makes the timezone-aware datetime utilities optional through a new use_temporal configuration flag. When disabled, the utils folders and related dependencies are excluded from generated projects.

The temporal utility now includes only universally useful datetime helpers: now(), today(), yesterday(), tomorrow(), midnight(), make_tz_aware(), DatetimeRange, extract_datetime_from_string(), get_weekdays(), and get_weekdays_between().

Copy link
Copy Markdown
Contributor

@a-musing-moose a-musing-moose left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than use both the exclude option in copier.yml and adding the if use_temporal tags in each file - you can change the file name to include the if statement directly.

I am also concerned that these test specify the Melbourne Time zone, but settings.py have UTC.

Finally - Does this need to be an option? Should we just include it regardless? I think it is useful set of utilities any any project.

Comment thread template/src/tests/system/utils/test_temporal.py.jinja Outdated
Comment thread template/src/tests/system/utils/test_temporal.py.jinja Outdated
Comment thread template/src/tests/system/utils/test_temporal.py.jinja
@zahraaalizadeh zahraaalizadeh force-pushed the utility/temporal branch 2 times, most recently from 9fec36e to 1eeca9e Compare April 30, 2026 06:15
Copy link
Copy Markdown
Contributor

@a-musing-moose a-musing-moose left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nearly there - the only blocking change I need to see resolved is the param renaming in the extract_datetime_from_string function (or it's removal). Although the documentation re-framing would be nice to have now too.



def extract_datetime_from_string(
file_name: str, delimiters: abc.Iterable[str] = (".", "_")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: Rename the parameter file_name to something generic like value

The use of file_name feels like a hang over from this functions use in the Middy's project to extra datetime from transferred filenames.

In fact I might consider dropping this function entirely from the generic temporal implementation both because it is feels a little too Middy's file name specific and because it is the only part of temporal that requires the addition of dateutils. That said, if you think it still has sufficient re-usability - then just go for the parameter rename.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! I renamed the param and left it for now since I believe this can be a helpful in some projects.

Comment thread template/src/{{ project_module }}/utils/temporal.py
Comment thread template/docs/reference/temporal.md Outdated
|--------------|----------------|
| `datetime.datetime.now()` | `temporal.now()` |
| `datetime.datetime.today()` | `temporal.today()` |
| `datetime.datetime.utcnow()` | `temporal.now()` |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: you can drop utcnow

utcnow is a deprecated function already, and our temporal.now() is not a direct equivalent unless the TZ is set to UTC.

Comment thread template/docs/reference/temporal.md Outdated
| `datetime.datetime.utcnow()` | `temporal.now()` |
| `datetime.date.today()` | `temporal.today()` |

## Available Functions
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Drop the exhaustive list of functions

This document will be out of date as soon as anything changes in the temporal module. So the module is a better source of truth... unless you use mkdocstring to generate this portion of the document.

Comment thread template/docs/reference/temporal.md Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Reframe this as a "how-to" on working with dates and times

I think this document floats a little between pure reference and guidance. So a how-to is probably a better fit.

Move to how-tos/datetimes.md and talk more generally about working with dates, times and timezones.

You can introduce the temporal modules as a collection of functions to help you do the right thing.

You can also talk in a how to about good practices when testing code that uses or manipulates datetimes. Calling out that this is the number one cause of flaky tests and that any tests that rely on "now" or datetime/timezone manipulations should use time_machine to ensure a consistent time in which the test operates.

You could even talk about trying to call temporal.now() only at the top level interfaces (views, tasks) and passing them down to business logic. So that the business logic can be more easily isolated for testing purposes. .i.e. if a function takes now (or as_of) as a parameter is probably doesn't need to use time_machine as the supplied date never changes.

Makes the timezone-aware datetime utilities
optional through a new use_temporal
configuration flag. When disabled, the utils
folders and related dependencies are excluded
from generated projects.

The temporal utility now includes only universally
useful datetime helpers:
`now()`, `today()`, `yesterday()`, `tomorrow()`,
`midnight()`, `make_tz_aware()`, `DatetimeRange`,
`extract_datetime_from_string()`, `get_weekdays()`,
and `get_weekdays_between()`.
Copy link
Copy Markdown
Contributor

@a-musing-moose a-musing-moose left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code is fine now - just one little correction in the documentation and a couple of thoughts/notes that might be worth discussing.

datetimes timezone-aware immediately:

```python
from {{ project_module }}.utils.temporal import make_tz_aware
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: from {{ project_module }}.utils import temporal

I know this only an examples, but I would like to continue to re-enforce importing modules not properties.

Comment thread template/docs/how-tos/datetimes.md.jinja
Comment on lines +146 to +148
**Important:** Even if your users are all in one timezone (e.g., "Australia/Melbourne"),
use `"UTC"` as your `TIME_ZONE`. Django will store all data in UTC and convert to user
timezones when displaying. This avoids DST bugs and makes your data portable.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If USE_TZ is set to true than Django will store in UTC regardless of what TIME_ZONE is set to. I cannot remember if this is a Django or Postgres thing - but the outcome is the same.

But I don't think Django will automatically know the user's timezone and perform the conversion in render. I think you need to either set TIME_ZONE or use the timezone.activate() method to set the timezone for the current request.

If you only really care about the local tz, it might be easier to just set TIME_ZONE to that. We do that for Middy's I think.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a section to explain this.

Copy link
Copy Markdown
Contributor

@a-musing-moose a-musing-moose left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Zahra!

@zahraaalizadeh zahraaalizadeh merged commit 2ae43bd into main May 5, 2026
4 checks passed
@zahraaalizadeh zahraaalizadeh deleted the utility/temporal branch May 5, 2026 08:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants