Flask-Dayjs
This extension enhances Jinja2 templates with formatting of dates and times using day.js. It is a fork of Flask-Moment that replaces moment.js with day.js, the modern, actively maintained successor.
Why day.js?
moment.js is officially in maintenance mode — no longer developed, only patched — and its own maintainers recommend day.js as a drop-in alternative. day.js is API-compatible with moment.js for the common cases, immutable, and much smaller:
| Library | Default page payload* |
|---|---|
| Flask-Moment with all locales | ~73 KB gz |
| Flask-Moment core only (English) | ~19 KB gz |
| Flask-Dayjs (day.js core + 5 plugins) | ~6 KB gz |
| Flask-Dayjs core only (English) | ~3 KB gz |
*Measured at dayjs 1.11.19 vs. moment 2.29.4.
Flask-Moment bundled every locale into a single script, which is what made it so heavy. day.js ships only a tiny core, and Flask-Dayjs loads individual locales from the CDN only when you ask for them. Even against moment's English-only core build, day.js is about three times smaller.
Installation
Install the extension with pip:
pip install flask-dayjs
or with uv:
uv add flask-dayjs
Initialization
Once the extension is installed, create an instance and initialize it with the Flask application:
from flask_dayjs import Dayjs
dayjs = Dayjs(app)
If the application uses the application factory pattern, the two-step initialization method can be used instead:
dayjs = Dayjs()
def create_app():
app = Flask(__name__)
dayjs.init_app(app)
return app
To complete the initialization, add the following line inside the <head>
section of the template(s) that will use the extension. If you use template
inheritance, the best place to add this line is in your base template:
{{ dayjs.include_dayjs() }}
The include_dayjs() function accepts a few arguments that control settings
such as the version of day.js to use, or whether the library should be
imported from a CDN. See the
API reference below.
Note that older versions of Flask-Moment required jQuery; this is not the case anymore.
Usage
To render a date with Flask-Dayjs, use the dayjs() function with one of
the available formatting options. The following example uses a custom format
string to render the current time:
<p>Current date and time: {{ dayjs().format('MMMM D YYYY, h:mm:ss a') }}.</p>
To render a timestamp other than the current time, pass a datetime object
as an argument to the dayjs() function:
<p>Date: {{ dayjs(date).format('LL') }}</p>
Some of the rendering functions render the elapsed time between a datetime object and current time. The following example renders a timestamp in a "time ago" style:
<p>{{ author }} said {{ dayjs(comment_datetime).fromNow() }}</p>
Advanced options
Auto-Refresh
All the display functions take an optional refresh argument that when set
to True will re-render timestamps every minute. If a different time
interval is desired, pass the interval in minutes as the value of the
refresh argument.
This option is useful for relative time formats such as the one returned by
the fromNow() or fromTime() functions. For example, the date of a
comment would appear as "a few seconds ago" when the comment was just entered,
but a minute later it would automatically refresh to "a minute ago" without
the need to refresh the page.
By default automatic refreshing is disabled.
Default Format
The format() function can be invoked without arguments, in which case a
default format of ISO8601 defined by the day.js library is used. If you want
to set a different default, you can set the DAYJS_DEFAULT_FORMAT variable
in the Flask configuration. Consult the
day.js format documentation for
a list of accepted tokens.
Internationalization
By default dates and times are rendered in English. To change to a different
language add the following line in the <head> section of your template(s),
after the include_dayjs() line:
{{ dayjs.locale("es") }}
The above example sets the language to Spanish. Each dayjs.locale() call
both loads the requested locale's data from the CDN and activates it. Unlike
Flask-Moment, which bundled every locale into a single script, Flask-Dayjs
only downloads the locales you actually use (the browser caches them, so
calling dayjs.locale("es") on multiple pages costs nothing after the
first load). Day.js supports a large number of languages. Consult the
documentation for the list of languages and their corresponding codes.
This extension also supports auto-detection of the client's browser language:
{{ dayjs.locale(auto_detect=True) }}
With auto-detection enabled, the locale matching the browser's language is
loaded automatically from the CDN, so no manual dayjs.locale() call is
needed. If your application supports a known set of languages, you can still
pre-load them eagerly to avoid a brief flash of English:
{{ dayjs.locale("es") }}
{{ dayjs.locale("fr") }}
{{ dayjs.locale(auto_detect=True) }}
Custom locale data can be passed as a dictionary:
{{ dayjs.locale("es", customization={"months": ["enero", ...]}) }}
Ajax Support
It is also possible to create Flask-Dayjs timestamps in Python code that is invoked from the client page through Ajax, without the use of Jinja templates:
timestamp = dayjs.create(datetime.now(timezone.utc)).calendar()
The dayjs variable is the Dayjs instance that was created at
initialization time.
A timestamp created in this way is an HTML string that can be returned as part of a response. For example, here is how a timestamp can be returned in a JSON object:
return {'timestamp': dayjs.create(datetime.now(timezone.utc)).format('L')}
The Ajax callback in the browser needs to call flask_dayjs_render_all()
each time an element containing a timestamp is added to the DOM. The example
application in the Flask-Dayjs GitHub repository demonstrates how this is
done.
Subresource Integrity (SRI)
SRI is a security feature that enables browsers to verify that resources they fetch are not maliciously manipulated. To do so a cryptographic hash is provided that proves integrity.
SRI for the day.js library is enabled by default. If you wish to use a version different than the one bundled with this extension, or want to host your own JavaScript, a separate hash can be provided.
Just add sri=<YOUR-HASH> when calling dayjs.include_dayjs(). If no SRI
hash is provided when a custom day.js version is used, then SRI verification
is not used.
To disable SRI, pass sri=False in the include_dayjs() call.
Migrating from Flask-Moment
Flask-Dayjs is a drop-in replacement for Flask-Moment with the syntax renamed
from moment to dayjs:
| Flask-Moment | Flask-Dayjs |
|---|---|
from flask_moment import Moment |
from flask_dayjs import Dayjs |
moment = Moment(app) |
dayjs = Dayjs(app) |
{{ moment.include_moment() }} |
{{ dayjs.include_dayjs() }} |
{{ moment().format('LL') }} |
{{ dayjs().format('LL') }} |
moment.locale("es") |
dayjs.locale("es") |
MOMENT_DEFAULT_FORMAT config |
DAYJS_DEFAULT_FORMAT config |
The rendering methods (format, fromNow, fromTime, toNow,
toTime, calendar, valueOf, unix, diff), the create()
and lang() helpers, and the local and refresh arguments behave
identically.
Note that day.js and moment.js are different libraries, so a few formatting tokens may render differently, and day.js parses ISO 8601 strings more strictly than moment.js.
API Reference
The complete API is documented in the docstrings of the source module. In short:
dayjs.include_dayjs(version, local_js, no_js, sri, plugins)— include day.js and the supporting JavaScript in the<head>section.dayjs.locale(language, auto_detect, customization)anddayjs.lang(language)— configure the locale.dayjs.flask_day_js()— the raw supporting JavaScript, for custom setups.dayjs(timestamp=None, local=False)— create a dayjs object in a template, with the rendering methods listed above.Dayjs(app)/Dayjs().init_app(app)— initialize the extension.Dayjs.create(timestamp)— create a rendered timestamp outside of templates (e.g. for Ajax responses).
Resources
Metadata
Release files for Flask-Dayjs 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| flask_dayjs-1.0.0.tar.gz | 12.3 kB | Without provenance | Details for flask_dayjs-1.0.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| flask_dayjs-1.0.0-py3-none-any.whl | Python 3 | none | any | Details for flask_dayjs-1.0.0-py3-none-any.whl |
Total release size: 22.0 kB
Release files / flask_dayjs-1.0.0.tar.gz
| Download URL | flask_dayjs-1.0.0.tar.gz |
|---|---|
| Size | 12.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5f65f3d0c9efa8abcc2b8dd714744fb6a13b1e13f3ab14611e457ca392ef19be
|
|
BLAKE2b-256 checksum How to use checksums |
75f1e0debb2d9691350e3a755332902a2fe45cdf7284458f7eee127009c425a5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.2
|
Release files / flask_dayjs-1.0.0-py3-none-any.whl
| Download URL | flask_dayjs-1.0.0-py3-none-any.whl |
|---|---|
| Size | 9.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
77cb6a0960730536c85e759cf478394b7c786820db84dff06e6bc47bfb9997e2
|
|
BLAKE2b-256 checksum How to use checksums |
936e8817ca6ff3cf9815bb536bf1d2214bcbfae11f00c982a45dde030ac61713
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.2
|
Security for Flask-Dayjs 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.