Library / SDK
jama5262/jiffy avatar
jama5262/jiffy

Jiffy: date and time handling for Flutter with familiar formatting patterns

Jiffy is a Flutter (Android, IOS and Web) date time package for parsing, manipulating, querying and formatting dates

630 stars141 forksDartMIT

At a glance

What is it?
Jiffy is a Dart and Flutter package for parsing, manipulating, querying and formatting dates and times, with a pattern syntax taken from moment.js and named getters for common output formats. It suits a Flutter developer who wants familiar date formatting without pulling in a full internationalisation stack, and its locale support covers a smaller set of languages than the platform's own date formatting.
Who is it for?
Jiffy fits a Flutter developer who is porting date formatting code from a JavaScript project, or who wants a named getter such as yMMMMEEEEdjm rather than a format string at every call site, and it does not fit a team that needs the full set of locales the Flutter platform provides or the timezone database awareness that a specialised date library brings.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 144 days ago.
What is it written in?
Mainly Dart, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A date package for Flutter that borrows moment's vocabulary

Jiffy is a Flutter date time package for parsing, manipulating, querying and formatting dates, and it is described as working on Android, iOS and Web, with a platform badge covering flutter, web and the Dart VM.

The design reference is JavaScript's moment.js, and the borrowing is in the vocabulary rather than the implementation. A format is a pattern string with moment's tokens, Jiffy.now() is a static factory, and the relative time helpers are called from and to. A developer who has written moment code can read Jiffy code without a translation table, which is the practical reason to pick this package over a generic Dart date library.

The API is organised around five verbs, and the README's usage section is organised the same way. There is formatting, relative time, manipulation, querying and locale support. That is a complete list of what a date and time package needs to do, and the fact that the package covers all five without pulling in a large dependency tree is what makes it usable in a mobile app where the build size matters.

The repository structure backs that up. There is a lib directory with the package source, a test directory, an example directory with jiffy_example.dart, a doc directory for the full documentation, a bin directory, an analysis_options.yaml for the Dart analyzer, a CHANGELOG.md, a pubspec.yaml, and a .pubignore.

The package is MIT licensed, published on pub.dev as jiffy, the current version is 6.4.5, and the last push was on 2026-06-01, the same day as the v6.4.5 release. The README links the full documentation at a version pinned path, tree/v6.4.5/doc, so the docs are matched to the release rather than to the branch tip.

Formatting, and the named getters that save repeating a pattern

The formatting section is where the package shows what it is for. The first example parses a slash separated date and formats it with a moment style pattern.

dart
Jiffy.parse('2021/01/19').format(pattern: 'MMMM do yyyy, h:mm:ss a'); // January 19th 2021, 12:00:00 AM
Jiffy.now().format(pattern: 'EEEE'); // Tuesday
Jiffy.now().format(pattern: 'MMM do yy'); // Mar 2nd 21
Jiffy.now().format(pattern: 'yyyy [escaped] yyyy'); // 2021 escaped 2021
Jiffy.now().format(); // 2021-03-02T15:18:29.922343

Three things are worth pulling out of that. The square brackets escape literal text, so the yyyy pattern can be followed by the word escaped and still print the year twice. The no-argument format() gives an ISO style string, which is a sensible default for a value that is about to be serialised. And the day ordinal token, do, produces January 19th rather than January 19, which is the sort of detail that separates a date format library from a string concatenation.

The second style of API is the named getter, and this is the part that is distinctly JavaScript shaped rather than Dart shaped. The README shows that a parsed date has a property for the format it happens to need.

dart
Jiffy.parseFromList([2020, 10, 19]).yMMMMd; // January 19, 2021

There are several of these, one per common combination, yMMMMd, yMMMMEEEEdjm, dMMMMEEEEyjm, and the like, and the full set is in the API reference on pub.dev. The trade is a wider surface to learn against a small gain per call site, and the gain is real when the same format is used in several places, because a named getter is one identifier rather than a long string repeated with the risk of a typo.

Parsing itself is forgiving. A string with a pattern, a list of numbers, a map keyed by the Unit enum, and the pre-set format helpers are all supported, and the map form is explicit about which field is which.

dart
Jiffy.parseFromMap({
  Unit.year: 2020,
  Unit.month: 10,
  Unit.day: 19,
  Unit.hour: 19
}).dMMMMEEEEyjm; // Monday, October 19, 2020 7:14 PM

Relative time, manipulation and querying, all as instance methods

The other three sections of the usage guide are short enough to read as a vocabulary, and they all work the same way, as methods on a parsed value.

Relative time comes in four forms, two of which are relative to another date and two of which are relative to now.

dart
// From X
Jiffy.parse('1997/09/23').from(Jiffy.parse('2002/10/26')); // 5 years ago
// From Now
Jiffy.parse('1997/09/23').fromNow(); // 25 years ago

The from and to methods, and the fromNow and toNow variants, cover both directions. The README examples use a date in 1997, which by the time of the documentation reads as a deliberate way of showing the phrasing for a distant past and a distant future.

Manipulation is a chain. You add or subtract a named quantity, and the units are the same Unit enum used for parsing.

dart
var jiffy = Jiffy.now().add(days: 1);
jiffy.yMMMMd; // March 3, 2021

Jiffy.now().subtract(days: 1).yMMMMd; // March 2, 2021

The mixed case is shown too, where add and subtract are combined in one chain with several units at once, and the result is a new formatted value.

The one operation here that is genuinely useful beyond arithmetic is startOf and endOf, which snap to a boundary of a unit.

dart
Jiffy.parse('1997/09/23')
    .startOf(Unit.year)
    .yMMMMEEEEd; // Wednesday, January 1, 1997

Jiffy.parse('1997/09/23')
    .endOf(Unit.month)
    .yMMMMEEEEd; // Tuesday, September 30, 1997

Querying is a set of four comparisons, and they return booleans rather than throwing, so they read as predicates.

dart
Jiffy.parse('1997/9/23').isBefore(Jiffy.parse('1997/9/24')); // true

Jiffy.parse('1997/9/23').isAfter(Jiffy.parse('1997/9/20')); // true

Jiffy.parse('1997/9/23').isSame(Jiffy.parse('1997/9/23')); // true

Jiffy.parse('1997/9/23')
  .isBetween(Jiffy.parse('1997/9/20'), Jiffy.parse('1997/9/24')); // true

Note that the querying examples use a slash separated date without zero padding, 1997/9/23 rather than the 1997/09/23 in the earlier sections, so the parser is more forgiving than the formatting output suggests.

Locale support, and where it stops short of the platform

The locale section is the one to read carefully before committing to the package, because it is where the scope is narrowest.

The API is a static locale code property and a static setter that is awaited, so the locale is global to the package rather than per instance.

dart
// Get current locale code, by default it is en_us
Jiffy.now().localeCode; // en_US

// Setting your preferred locale
await Jiffy.setLocale('fr_ca');
Jiffy.now().yMMMMEEEEdjm; // dimanche 26 février 2023 12 h 03

The default is en_us, and the examples show French Canadian, Japanese and Simplified Chinese, each producing output in that language with the appropriate date and time ordering.

dart
await Jiffy.setLocale('ja');
Jiffy.now().yMMMMEEEEdjm; // 2023年2月26日日曜日 12:02

await Jiffy.setLocale('zh_cn');
Jiffy.now().yMMMMEEEEdjm; // 2023年2月26日星期日 下午12:03

Two observations follow. The Japanese and Chinese outputs place the year first, which is the ordering a reader in those languages expects, and the Chinese output uses 下午 for the afternoon, which is a translated meridiem rather than a transliterated one. That is a real localisation of the format output and not just a different token order.

The limitation is that the package carries its own locale set rather than using the platform's date formatting data, which on Flutter is the intl package with its own locale data and a date symbol library. The consequence is that the locales Jiffy supports and the locales the platform supports are different lists, and a Jiffy user is choosing from a smaller menu. The README does not enumerate the available locales, so that list has to be checked in the documentation.

There is also a design consequence in the API shape itself. Because the locale is a static, setting it affects every Jiffy instance in the program, so two parts of an application cannot use different locales at the same time. For a single-locale app that is fine, and for an app that renders a user's chosen locale alongside a fixed one, it is a limitation.

Where it fits against a generic date library and the platform's own

Two comparisons are worth making, and they bracket what this package is.

Against a generic Dart date library, the difference is the surface area. A general purpose library gives you a date type, arithmetic, comparison and formatting, and you write the format string yourself each time. Jiffy gives you the same plus a pattern syntax borrowed from moment, a set of named getters for the formats people actually want, relative time phrasings that you would otherwise write by hand, and a locale layer. The cost is a dependency with its own API to learn, and the risk of a version that behaves differently from the generic library you already use.

Against the platform's own date formatting, the difference is scope again. Flutter's intl package with its date symbols handles localisation properly, with a much larger locale set and proper time zone data, and it is already in most Flutter projects. Jiffy's case is that it removes the need to reach for that machinery for the common cases, and that its syntax is the one a JavaScript developer or a moment.js user already has in their head.

The decision therefore turns on a fairly narrow question. If the dates in your app are mostly formatting and arithmetic, and the app is not localised beyond one or two languages, Jiffy is a good deal. If the app is a multi-language product where the date presentation is a core part of the experience, the platform's own date formatting is the safer choice, because the locale data is broader and it is the path the platform is built around.

One last point to keep in mind for a package in this position. The release history is steady but the push activity is not high, with v6.4.5 on 2026-06-01, v6.4.4 on 2025-11-18 and v6.4.3 on 2025-04-02, and the last push was the same day as the newest release. A six version 6.4.x line with no major changes in that window is a stable dependency, and a stable dependency that is not gaining features quickly is exactly what you want for a date library, since date handling does not benefit from churn.

Editorial conclusion

Jiffy fits a Flutter developer who is porting date formatting code from a JavaScript project, or who wants a named getter such as yMMMMEEEEdjm rather than a format string at every call site, and it does not fit a team that needs the full set of locales the Flutter platform provides or the timezone database awareness that a specialised date library brings. Before adopting it, check the locale list in the documentation, since the examples cover French, Japanese and Simplified Chinese and the package's locale set is not the same as the platform's, and note the release history, with v6.4.5 published on 2026-06-01.

Frequently asked questions

What does the Jiffy package do for Flutter apps?

Jiffy is a Dart package for parsing, manipulating, querying and formatting dates and times on Android, iOS and Web, using a moment.js style pattern syntax plus named getters for common output formats, and it is published on pub.dev under the MIT licence at version 6.4.5.

How do I change the locale in Jiffy?

The locale is a package-wide setting, read with the localeCode property and changed by awaiting Jiffy.setLocale, for example await Jiffy.setLocale('fr_ca'). The default is en_us, and the README shows French Canadian, Japanese and Simplified Chinese output.

How do I add or subtract time in Jiffy?

You chain add and subtract with named units, and the units come from the same Unit enum used for parsing. You can also snap to a boundary with startOf and endOf, for example Jiffy.parse('1997/09/23').startOf(Unit.year).

What is the difference between Jiffy format and the named getters?

The format method takes a pattern string such as pattern: 'MMMM do yyyy, h:mm:ss a' and can escape literal text in square brackets, while the named getters, for example yMMMMd or yMMMMEEEEdjm, are properties that return a preformatted string for a common combination without repeating a pattern at the call site.

Official sources

  1. jama5262/jiffy on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/jama5262-jiffy.svg)](https://hysenlabs.com/projects/jama5262-jiffy)

Was this useful?