any_timeago 2.1.0 copy "any_timeago: ^2.1.0" to clipboard
any_timeago: ^2.1.0 copied to clipboard

Feature-rich relative-time formatting for Flutter with four presentation formats, 197 localizations, customizable output, and synchronized live-updating widgets.

any_timeago #

Tests

Feature-rich relative-time formatting for Flutter, with four presentation formats and 197 localizations. Customize steps, per-step rounding, granularity, cutoffs, and multi-unit output. Includes ready-made inherited configuration and synchronized, live-updating widgets.

App Screenshot

The core implementation was initially based on the javascript-time-ago library.

You might also like my other packages: any_sparklines, any_borders

Showcases #

Each shortcut highlights one option; ... stands for the input and other required arguments.

  • Presentation formats
    • Long: timeAgo(..., format: TimeAgoFormat.long)
      • 3 minutes ago
    • Short: timeAgo(..., format: TimeAgoFormat.short)
      • 3 min ago
    • Narrow: timeAgo(..., format: TimeAgoFormat.narrow)
      • 3m ago
    • Mini: timeAgo(..., format: TimeAgoFormat.mini)
      • 3m
  • 197 localizations
    • Norwegian: timeAgo(..., locale: nb.locale)
      • for 3 minutter siden
    • Italian: timeAgo(..., locale: it.locale)
      • 3 minuti fa
  • Step presets
    • Precise: timeAgo(..., steps: TimeAgoSteps.precise)
      • 45 seconds ago — Includes seconds instead of rounding the interval to a minute.
    • From-minute-now: timeAgo(..., steps: TimeAgoSteps.fromMinuteNow)
      • just now — Uses the localized now label below the first rounded minute.
    • Twitter: timeAgo(..., steps: twitter.steps)
      • 20 May 2020 — Switches older values from relative units to a localized calendar date.
    • Calendar: timeAgo(..., steps: calendar.steps)
      • heute um 14:35 — Uses now through one minute, relative minutes through 30 minutes, then fully localized named-day or calendar date-time output.
    • Calendar with seconds: timeAgo(..., steps: calendar.stepsWithSeconds)
      • gestern um 14:35:42
  • Per-step rounding
    • Floor: timeAgo(..., steps: [TimeAgoStep.unit(..., rounding: TimeAgoRounding.floor)])
      • 1 minute ago — Counts only completed minutes in a 1-minute, 36-second interval.
    • Round: timeAgo(..., steps: [TimeAgoStep.unit(..., rounding: TimeAgoRounding.round)])
      • 2 minutes ago — Rounds the same interval to the nearest minute.
  • Granularity
    • 5 seconds: timeAgo(..., steps: [TimeAgoStep.unit(TimeAgoUnit.second, granularity: 5)])
      • 15 seconds ago — Snaps 13 seconds to the nearest 5-second increment.
    • 30 minutes: timeAgo(..., steps: [TimeAgoStep.unit(TimeAgoUnit.minute, granularity: 30)])
      • 30 minutes ago — Snaps 43 minutes to the nearest 30-minute increment.
  • Cutoffs
    • 3 minutes: timeAgo(..., cutoffStep: TimeAgoStep.unit(TimeAgoUnit.minute, cutoffAmount: 3))
      • 3+ minutes ago — Caps values beyond 3 minutes and adds the + suffix.
    • 9 years: timeAgo(..., cutoffStep: TimeAgoStep.unit(TimeAgoUnit.year, cutoffAmount: 9))
      • 9+ years ago — Caps values beyond 9 calendar years.
  • Multi-unit output
    • Default: timeAgoMulti(...)
      • 2 hours, 3 minutes, and 4 seconds ago — Includes every nonzero default unit.
    • Years and days: timeAgoMulti(..., units: [TimeAgoUnit.year, TimeAgoUnit.day])
      • 1 year and 5 days ago — Decomposes the interval using only the requested units.
  • Past and future
    • Past: timeAgo(pastTime, ...)
      • 3 minutes ago
    • Future: timeAgo(futureTime, ...)
      • in 3 minutes
  • Directional output
    • Directional: timeAgo(..., directional: true)
      • 3 minutes ago — Includes localized past or future wording.
    • Directionless: timeAgo(..., directional: false)
      • 3 minutes — Returns only the localized amount and unit.
  • Custom units
    • Fortnight: durationAgo(..., steps: [en.fortnight])
      • 1 fortnight ago
    • Decade: durationAgo(..., steps: [en.decade])
      • 3 decades ago
    • Century: durationAgo(..., steps: [en.century])
      • 2 centuries ago

Setup #

any_timeago has no global locale registry and exports no default locale. Import only the locale files your application uses:

import 'package:any_timeago/any_timeago.dart';
import 'package:any_timeago/locales/en.dart' as en;
import 'package:any_timeago/locales/en_us.dart' as en_us;
import 'package:any_timeago/locales/it.dart' as it;
import 'package:any_timeago/locales/nb.dart' as nb;

Intl-backed step presets are also opt-in:

import 'package:any_timeago/steps/intl_twitter.dart' as twitter;
import 'package:any_timeago/steps/intl_calendar.dart' as calendar;

NB! Bundled locales use package:intl for localized number, plural, date, and time operations. Number and plural data are available immediately. Applications using the intl_twitter or intl_calendar presets must call initializeTimeAgoDateFormatting() before runApp() as described in

Intl date initialization.

API #

  • timeAgo() and durationAgo() format one localized relative-time unit.
  • timeAgoMulti() and durationAgoMulti() format a localized list of units.
  • Matching *Result() variants return TimeAgoResult with localized text, the pre-format values, the pending replacement step in nextCutoff, and nextUpdate for scheduling.

For example, durationAgoMultiResult(const Duration(days: 400), ...) exposes year, month, and day TimeAgoStep.unit records with values 1, 1, and 10 in values, independently of the selected locale and presentation format. Single-step results contain the exact selected step, including custom steps.

Features #

Presentation formats #

TimeAgoFormat controls label width only. It never changes thresholds or rounding.

  • TimeAgoFormat.long: 2 minutes ago, in 2 minutes
  • TimeAgoFormat.short: 2 min ago, in 2 min
  • TimeAgoFormat.narrow: CLDR narrow labels, such as 2m ago, in 2m
  • TimeAgoFormat.mini: the shortest available labels, such as 2m

Every locale provides long and short labels. Dedicated narrow labels are kept only when they differ from short; otherwise narrow falls back to short. A locale can also omit dedicated mini labels, which fall back to narrow and then short. Use locale.supportsFormat(format) to test whether narrow or mini has dedicated labels instead of resolving a fallback.

Multi-unit output uses the unit labels and localized list patterns of the selected presentation format. In English, the same interval is rendered as 2 years and 3 months ago, 2 yr and 3 mo ago, 2y and 3mo ago, or 2y 3mo for long, short, narrow, and mini respectively.

197 localizations #

The package ships 197 locale configurations as separate libraries, so applications import and bundle only the locales they use. Pass a locale to a formatting call or provide it once with TimeAgoProvider:

timeAgo(message.sentAt, locale: it.locale);

Every bundled locale provides long and short labels. Dedicated narrow and mini labels are included where they add a distinct width; otherwise they resolve through the fallback chain described above. Localized numbers and plural rules are powered by package:intl. See Locale customization to override individual labels or locale operations.

Step presets #

Step presets are organized under steps/. Only steps/basic.dart is exported by package:any_timeago/any_timeago.dart; other presets must be imported explicitly as package:any_timeago/steps/<preset>.dart.

The progressions below show representative English TimeAgoFormat.mini output. They summarize the output stages, not every exact selection threshold.

Basic presets

No additional import is needed.

  • TimeAgoSteps.precise0s1m1h1d1wk1mo1yr
    • Uses every unit from seconds through years.
  • TimeAgoSteps.preciseNownow1s1m → … → 1yr
    • Adds a localized now step before precise.
  • TimeAgoSteps.fromMinute0m1m1h → … → 1yr
    • Starts at minutes and renders zero as 0 minutes.
  • TimeAgoSteps.fromMinuteNownow1m1h → … → 1yr
    • Adds now before fromMinute; this is the default preset.
  • TimeAgoSteps.approximatenow1s1m5m30m1h1d1wk1mo1yr
    • Uses fuzzy thresholds and rounded minute increments.

Calendar presets

import 'package:any_timeago/steps/intl_calendar.dart' as calendar;
  • calendar.stepsnow1m30mtoday at 14:35yesterday at 14:3520 Jul at 14:3520 Jul 2025 at 14:35
    • Uses now through one minute and relative minutes through 30 minutes. Older values use localized yesterday, today, tomorrow, or calendar dates combined with a localized clock.
  • calendar.stepsWithSecondsnow1m30mtoday at 14:35:42 → … → 20 Jul 2025 at 14:35:42
    • Uses the same stages while retaining seconds in calendar timestamps.

Twitter presets

import 'package:any_timeago/steps/intl_twitter.dart' as twitter;
  • twitter.steps0s1m1h20 Jul20 Jul 2025
  • twitter.stepsNownow1s1m1h20 Jul20 Jul 2025
  • twitter.stepsFromMinute0m1m1h20 Jul20 Jul 2025
  • twitter.stepsFromMinuteNownow1m1h20 Jul20 Jul 2025
  • twitter.stepsFirstMinute — empty → 1m1h20 Jul20 Jul 2025

The opt-in intl_twitter and intl_calendar presets require Intl date initialization. Every bundled LocaleConfig.calendar supplies CLDR 48.1 yesterday, today, and tomorrow labels plus separate fixed-date and relative-date clock-combination patterns.

A step can define minTime, minTimeResolver, rounding, granularity, cutoffAmount, and nextUpdate. Custom step variants can also provide their own formatting. TimeAgoStep is sealed; its factories create a TimeAgoUnitStep, TimeAgoCustomStep, or TimeAgoCustomUnitStep.

Per-step rounding #

TimeAgoRounding.round selects the nearest unit, while TimeAgoRounding.floor counts only completed units.

TimeAgoStep.unit(
  TimeAgoUnit.minute,
  rounding: TimeAgoRounding.floor, // Completed minutes
)

Granularity #

granularity groups a step into increments before its rounding policy is applied. With the default round policy, 13 seconds becomes 15 seconds. Using floor with the same step would produce 10 seconds.

TimeAgoStep.unit(
  TimeAgoUnit.second,
  granularity: 5, // Five second steps
)

Cutoffs #

Use cutoffStep to cap output independently of the configured step list:

const threeYears = TimeAgoStep.unit(
  TimeAgoUnit.year,
  cutoffAmount: 3,
);

durationAgo(
  const Duration(days: 1400),
  locale: en.locale,
  cutoffStep: threeYears,
); // 3+ years ago

The boundary is strict, so exactly three years remains 3 years. Cutoffs use the absolute interval and therefore apply equally to past and future values. In multi-unit mode, an exceeded cutoff replaces the complete list with its single capped unit.

Before a cutoff is exceeded, result APIs expose the nearest pending cutoff as nextCutoff, even when its unit or multiplier differs from the current values. At the strict boundary it remains pending. Once cutoff formatting is active, nextCutoff is null and the cutoff step is the current value's step instead. Consumers using its amount as a bound for a current value must first verify that their units and multipliers match.

timeAgo() and timeAgoMulti() use calendar-aware year, quarter, and month boundaries for a standalone cutoff. Duration functions and cutoffs embedded in steps use the unit's fixed microseconds value. A cutoff embedded in a step becomes terminal once that step is active:

const cappedSteps = [
  TimeAgoStep.unit(TimeAgoUnit.minute),
  TimeAgoStep.unit(TimeAgoUnit.hour),
  TimeAgoStep.unit(TimeAgoUnit.day),
  TimeAgoStep.unit(TimeAgoUnit.year, cutoffAmount: 3),
];

When several cutoffs apply, the earliest boundary wins. Custom step formatters receive TimeAgoStepContext.isCutoff == true and the capped amount.

Multi-unit output #

timeAgoMulti() and durationAgoMulti() decompose an interval into a localized list. By default, they use year, month, day, hour, minute, and second. Pass units to select another ordered set:

durationAgoMulti(
  const Duration(days: 91),
  locale: en.locale,
  units: const [TimeAgoUnit.quarter, TimeAgoUnit.day],
); // 1 quarter and 1 day ago

TimeAgoUnit contains now, second, minute, hour, day, week, month, quarter, and year. now is only valid in single-unit step lists. Multi-unit lists must contain unique values ordered largest to smallest.

Use TimeAgoUnit.upperBound() to obtain the value at which a unit reaches its next configured unit:

TimeAgoUnit.minute.upperBound(); // 60, before hour
TimeAgoUnit.hour.upperBound(); // 24, before day
TimeAgoUnit.day.upperBound(); // 31, before month
TimeAgoUnit.day.upperBound(
  nextUnits: const {TimeAgoUnit.day: TimeAgoUnit.week},
); // 7
TimeAgoUnit.year.upperBound(cutoff: 3); // 3

The optional nextUnits map overrides individual entries in TimeAgoUnit.defaultNextUnits. A positive cutoff takes precedence.

DateTime decomposition uses calendar-aware years, quarters, and months with month-end clamping. Duration decomposition uses 360-day years, 90-day quarters, and 30-day months. Zero components are skipped, but no nonzero component is truncated. A nonzero interval smaller than the smallest requested unit is shown as one smallest unit.

Past and future #

timeAgo() compares time with to ?? DateTime.now(). durationAgo() treats positive values as past and negative values as future. The multi variants use the same direction rules while decomposing the interval into a localized component list.

Pass future: true to force future grammar. This is especially useful when an exact-zero difference should be formatted as a future value:

durationAgo(
  Duration.zero,
  locale: en.locale,
  future: true,
); // in a moment

The override also applies to nonzero values. When omitted, grammatical direction continues to be inferred from the date or signed duration.

Directional output #

directional controls whether the result includes localized past or future wording. It is independent of the selected presentation format:

durationAgo(
  const Duration(minutes: 2),
  locale: en.locale,
  directional: false,
); // 2 minutes

When directional is omitted, it defaults to true for long, short, and narrow, and to false for mini. Passing it explicitly overrides that default. Past and future inference still determines which grammatical form is used whenever directional output is enabled.

Custom time units #

Built-in custom units #

The package ships opt-in steps for three units that are not members of TimeAgoUnit:

  • fortnight: two weeks
  • decade: ten years
  • century: one hundred years

They are exported only by locale files whose labels and directional grammar have been reviewed:

  • en (en-GB): fortnight, decade, and century
  • en-US, en-AU, en-CA, and en-SG: decade and century
  • fr/fr-CA, es and its regional variants, it, pt/pt-AO, nl, zh/zh-Hans-HK, and ja: decade and century

The exports are const TimeAgoStep values and remain opt-in:

durationAgo(
  const Duration(days: 3650),
  locale: en.locale,
  steps: const [en.fortnight, en.decade, en.century],
); // 1 decade ago

Defining a custom step #

TimeAgoStep.custom() attaches a formatter directly to one step. Use it for one-off behavior, including steps without a numeric unit. A unitless step must provide minTime or minTimeResolver.

String formatReleaseWindow(TimeAgoStepContext context) {
  return context.isPast ? 'released earlier' : 'coming later';
}

const releaseWindow = TimeAgoStep.custom(
  minTime: Duration(days: 30),
  formatter: formatReleaseWindow,
);

A custom step can also represent a multiplied numeric unit by supplying unit and unitMultiplier. A top-level or static formatter function keeps the step const.

Defining a reusable custom-unit step #

TimeAgoStep.customUnit() accepts a TimeAgoCustomUnit definition that keeps the base unit, multiplier, and formatter together. Use it when the same translated unit should be reusable or exported by a locale library.

TimeAgoCustomUnitTranslation is the standard implementation for plural-label-based units:

const centuryUnit = TimeAgoCustomUnitTranslation(
  unit: TimeAgoUnit.year,
  unitMultiplier: 100,
  units: TimeAgoFormatSet(
    long: TimeAgoPluralLabels.oneOther(
      one: '{0} century',
      other: '{0} centuries',
    ),
    short: TimeAgoPluralLabels.same('{0} c'),
    narrow: TimeAgoPluralLabels.same('{0}c'),
  ),
);

const TimeAgoStep century = TimeAgoStep.customUnit(centuryUnit);

TimeAgoCustomUnit is an open interface, not a fixed list. Implement it directly when formatting needs behavior beyond translated plural labels.

The translation helper localizes numbers, selects plural forms and label widths, applies cutoffs, and composes past or future direction using the selected locale. Long and short labels are required; narrow and mini are optional. Narrow falls back to short, while mini falls back to narrow and then short. For languages whose unit changes grammatical form, provide explicit TimeAgoFormatSet<TimeAgoRelativeUnitLabels> values through relative.

Choose between them based on ownership and reuse:

  • custom() stores a formatter callback directly on one step. Its unit is optional, so it also supports non-numeric and threshold-only behavior.
  • customUnit() stores a reusable numeric-unit contract containing the base unit, multiplier, and formatter. It is the better fit for translated units shared by locale libraries or multiple step configurations.

Both support thresholds, rounding, granularity, cutoffs, update scheduling, and const construction.

For multiplied units, inferred thresholds, amounts, cutoffs, and update boundaries use unit.microseconds * unitMultiplier. context.unit remains the base unit, while context.amount is expressed in custom units. context.unitMultiplier exposes the multiplier, and granularity is applied after multiplication. Explicit minTime and minTimeResolver values remain final threshold overrides and are not multiplied. Custom units are available only in single-unit steps, not multi-unit units.

Flutter configuration #

Put defaults in a provider. Nested providers override configuration without mutating global state:

TimeAgoProvider(
  locale: en.locale,
  fallbackFunctions: englishTimeAgoLocaleFunctions,
  format: TimeAgoFormat.long,
  directional: true,
  steps: TimeAgoSteps.fromMinuteNow,
  cutoffStep: const TimeAgoStep.unit(
    TimeAgoUnit.year,
    cutoffAmount: 3,
  ),
  multiUnits: const [
    TimeAgoUnit.year,
    TimeAgoUnit.month,
    TimeAgoUnit.day,
    TimeAgoUnit.hour,
    TimeAgoUnit.minute,
    TimeAgoUnit.second,
  ],
  child: const MyApp(),
);

Omitted context-extension arguments resolve from the nearest provider:

final label = context.timeAgo(message.sentAt);
final detailedLabel = context.timeAgoMulti(message.sentAt);
final result = context.timeAgoResult(message.sentAt);
final durationLabel = context.durationAgo(const Duration(hours: 3));

The context extension exposes the same eight methods as the top-level API: timeAgo, timeAgoMulti, timeAgoResult, timeAgoMultiResult, durationAgo, durationAgoMulti, durationAgoResult, and durationAgoMultiResult.

These methods are one-shot. For automatic updates, use TimeAgoText or TimeAgoBuilder:

TimeAgoText(time: message.sentAt);

TimeAgoBuilder(
  time: message.sentAt,
  builder: (context, value) => Semantics(
    label: 'Sent $value',
    child: Text(value),
  ),
);

For direct access to the complete live result, use TimeAgoRenderer. Its timeAgo callback resolves the current value, and its builder receives the corresponding TimeAgoResult:

TimeAgoRenderer(
  timeAgo: (context) => context.timeAgoResult(message.sentAt),
  builder: (context, result) => Semantics(
    label: 'Sent ${result.text}',
    child: Text(result.text),
  ),
);

TimeAgoRenderer owns subscription coordination. TimeAgoBuilder is the higher-level configuration adapter: it calls the matching BuildContext result extension and delegates scheduling to the renderer. Results with TimeAgoUpdate.never() do not retain a subscription.

Widgets under one provider share one TimeAgoScheduler. It targets the earliest registered transition and rebuilds only due subscriptions. It also handles app resume, long web timer limits, disposal, manual refresh(), and unknown custom-step timing. TimeAgoProvider(frozenAt: ...) freezes the shared clock for deterministic previews and tests.

Custom nextUpdate requests are combined with step and cutoff transitions, so structural boundaries cannot be skipped. Without nextUpdate, custom formatters retain fallback polling. TimeAgoUpdate.unknown(maximumDelay: ...) can cap that fallback when another exact deadline is known.

Locale customization #

LocaleConfig and every nested label type have copyWith() methods, so an application can replace a single string while preserving the rest:

final locale = en.locale.copyWith(
  now: en.locale.now.copyWith(past: 'a blink ago'),
  long: en.locale.long.copyWith(
    cutoffResolver: (amount) => (
      plural: TimeAgoPluralCategory.many,
      pattern: '{0} or more',
    ),
  ),
);

Each TimeAgoFormatLabels has its own cutoffResolver, so long, short, narrow, and mini output can use different wording. The resolver receives the cutoff amount and returns a plural category plus a pattern for the already-localized number. Its default result is (plural: TimeAgoPluralCategory.many, pattern: '{0}+').

Plural resolution plus number, date, and clock formatting are grouped under LocaleConfig.functions. Implement TimeAgoLocaleFunctions, or extend the non-Intl English implementation to override selected behavior:

final class HashEnglishFunctions extends EnTimeAgoLocaleFunctions {
  const HashEnglishFunctions();

  @override
  String formatNumber(num value) => '#$value';
}

final locale = en.locale.copyWith(
  functions: const HashEnglishFunctions(),
);

Named calendar days and the patterns that combine dates with clocks live in LocaleConfig.calendar. They can be customized independently:

final locale = en.locale.copyWith(
  calendar: en.locale.calendar.copyWith(
    today: 'this day',
    relativeDateTime: '{1} @ {0}', // {1} = date, {0} = clock
  ),
);

Every bundled locale uses IntlTimeAgoLocaleFunctions. If an Intl operation is unavailable, only that operation uses fallbackFunctions; the selected locale's translated labels remain in use. The default fallback is the const, non-Intl englishTimeAgoLocaleFunctions.

Fallback functions can be supplied to every top-level formatting function, TimeAgoProvider, context extensions, TimeAgoBuilder, or TimeAgoText. Explicit widget or context-extension values take precedence over the nearest provider. Nested providers inherit their parent's fallback when omitted.

Intl date initialization #

Intl number and plural data are immediately available, but localized date and time symbols must be initialized when Twitter-style or calendar-style output is needed:

import 'package:any_timeago/any_timeago.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await initializeTimeAgoDateFormatting();
  runApp(const MyApp());
}

This convenience helper bundles and loads all local date symbols provided by package:intl. Applications that need another loading strategy can initialize Intl directly. Call initialization before runApp(); until it completes, date operations use the configured fallback. Failed lookups are not cached, so subsequent calls use Intl after initialization.

Formats are stored in an immutable TimeAgoFormatSet: long and short are required, while narrow and mini are nullable. labelsFor() resolves narrow to short and mini to narrow then short. formats.exact() and supportsFormat() expose exact availability without applying those fallbacks.

Locale files document their exact source provenance. Relative labels use the checked-in javascript-time-ago locale sources as a starting point, wording is cross-checked against time_ago_provider, and plural/date/duration/list behavior follows Unicode CLDR 48.1. Manually completed Bokmål values are marked inline.

Locale core sharing #

Relative-time locale data started from javascript-time-ago-main/locale and was then reviewed and extended for this package.

Supported locales: af, ak, am, ar, ar_ae, as, ast, az, ba, bal_latn, be, be_tarask, bg, bgc, blo, bn, br, brx, bs, bs_cyrl, bua, ca, ccp, ce, ceb, chr, cs, csw, cv, cy, da, de, doi, dsb, dz, ee, el, en, en_au, en_ca, en_sg, en_us, eo, es, es_419, es_ar, es_mx, es_py, es_sv, es_us, et, eu, fa, ff_adlm, fi, fil, fo, fr, fr_ca, fur, fy, ga, gd, gl, gu, ha, he, hi, hi_latn, hr, hsb, ht, hu, hy, ia, id, ie, ig, ii, is, it, ja, jgo, jv, ka, kaa, kea, kgp, kk, kk_arab, kl, km, kn, ko, kok, kok_latn, ks, ksh, ku, ky, lb, lkt, lld, lo, lt, lv, mai, mi, mk, ml, mn, mni, mr, ms, ms_arab, mt, my, mzn, nb, ne, nl, nn, no, nqo, nso, om, or, pa, pcm, pl, ps, ps_pk, pt, pt_ao, qu, raj, rhg, rm, ro, ru, rw, sah, sc, scn, sd, sd_deva, se, se_fi, shn, si, sk, sl, so, sq, sr, sr_cyrl_ba, sr_latn, sr_latn_ba, su, sv, sw, syr, ta, te, tg, th, ti, tk, tn, to, tok, tr, tt, tyv, ug, uk, ur, ur_in, uz, uz_cyrl, vec, vi, wae, wo, xh, xnr, yi, yo, yo_bj, yrl, yue, yue_hans, zh, zh_hans_hk, zh_hant, zh_hant_hk, zu.

Migrations #

Migrating to 2.0.0 #

Twitter presets are now opt-in. Import package:any_timeago/steps/intl_twitter.dart as twitter and update these references:

Before 2.0.0
TimeAgoSteps.twitter twitter.steps
TimeAgoSteps.twitterNow twitter.stepsNow
TimeAgoSteps.twitterFromMinute twitter.stepsFromMinute
TimeAgoSteps.twitterFromMinuteNow twitter.stepsFromMinuteNow
TimeAgoSteps.twitterFirstMinute twitter.stepsFirstMinute

Custom LocaleConfig values must now provide calendar:

calendar: const TimeAgoCalendarLabels(
  yesterday: 'Yesterday',
  today: 'Today',
  tomorrow: 'Tomorrow',
  dateTime: '{1} at {0}',
),

Classes that implement TimeAgoLocaleFunctions must also implement formatTime(). Classes that extend a bundled locale-functions implementation inherit its clock formatting.

5
likes
150
points
311
downloads
screenshot

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Feature-rich relative-time formatting for Flutter with four presentation formats, 197 localizations, customizable output, and synchronized live-updating widgets.

Repository (GitHub)
View/report issues

Topics

#timeago #relative-time #localization #datetime #duration

License

unknown (license)

Dependencies

flutter, intl

More

Packages that depend on any_timeago