Security News
JSR Working Group Kicks Off with Ambitious Roadmap and Plans for Open Governance
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
javascript-time-ago
Advanced tools
The `javascript-time-ago` npm package is used to format dates and times in a human-readable way, such as '5 minutes ago' or '2 days ago'. It supports multiple languages and locales, making it a versatile tool for internationalization.
Basic Usage
This feature allows you to format a date into a human-readable string indicating the time elapsed since that date. The example shows how to set up the package for English and format a date to '1 minute ago'.
const TimeAgo = require('javascript-time-ago');
const en = require('javascript-time-ago/locale/en');
TimeAgo.addLocale(en);
const timeAgo = new TimeAgo('en-US');
console.log(timeAgo.format(new Date(Date.now() - 60 * 1000))); // '1 minute ago'
Custom Styles
This feature allows you to define custom styles for formatting the elapsed time. The example demonstrates how to create a custom style and use it to format a date.
const TimeAgo = require('javascript-time-ago');
const en = require('javascript-time-ago/locale/en');
TimeAgo.addLocale(en);
const timeAgo = new TimeAgo('en-US');
const customStyle = {
steps: [
{ formatAs: 'second' },
{ formatAs: 'minute' },
{ formatAs: 'hour' },
{ formatAs: 'day' },
{ formatAs: 'week' },
{ formatAs: 'month' },
{ formatAs: 'year' }
]
};
console.log(timeAgo.format(new Date(Date.now() - 60 * 1000), customStyle)); // '1 minute ago'
Localization
This feature supports multiple languages and locales, allowing you to format dates in different languages. The example shows how to set up the package for both English and Spanish.
const TimeAgo = require('javascript-time-ago');
const en = require('javascript-time-ago/locale/en');
const es = require('javascript-time-ago/locale/es');
TimeAgo.addLocale(en);
TimeAgo.addLocale(es);
const timeAgoEn = new TimeAgo('en-US');
const timeAgoEs = new TimeAgo('es-ES');
console.log(timeAgoEn.format(new Date(Date.now() - 60 * 1000))); // '1 minute ago'
console.log(timeAgoEs.format(new Date(Date.now() - 60 * 1000))); // 'hace 1 minuto'
Moment.js is a widely-used library for parsing, validating, manipulating, and formatting dates. It offers extensive functionality for date and time manipulation, but it is larger in size compared to `javascript-time-ago` and has been deprecated in favor of more modern solutions.
date-fns provides a comprehensive set of functions for working with dates in JavaScript. It is modular, allowing you to import only the functions you need, which can result in smaller bundle sizes. It also supports internationalization, similar to `javascript-time-ago`.
timeago.js is a small library used to format dates in a 'time ago' style. It is lightweight and easy to use, but it may not offer as many customization options or support for as many locales as `javascript-time-ago`.
International higly customizable relative date/time formatter (both for past and future dates).
Formats a date to something like:
npm install intl-messageformat --save
npm install javascript-time-ago --save
This package assumes that the Intl
global object exists in the runtime. Intl
is present in all modern browsers except Internet Explorer 10 and Safari 9 (which can be solved with the Intl polyfill).
Node.js starting from 0.12
has the Intl
APIs built-in, but only includes English locale data by default. If your app needs to support more locales than English on server side then you'll need to get Node to load the extra locale data, or (a much simpler approach) just use the Intl polyfill.
If you decide you need the Intl polyfill then here are some basic installation and configuration instructions.
First, the library must be initialized with a set of desired locales.
// Load number pluralization functions for the locales.
// (the ones that decide if a number is gonna be
// "zero", "one", "two", "few", "many" or "other")
// http://cldr.unicode.org/index/cldr-spec/plural-rules
// https://github.com/eemeli/make-plural.js
// http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html
//
// `IntlMessageFormat` global variable must exist
// in order for this to work:
// https://github.com/yahoo/intl-messageformat/issues/159
// For Webpack this is done via `ProvidePlugin` (see below).
//
import 'intl-messageformat/dist/locale-data/en'
import 'intl-messageformat/dist/locale-data/ru'
// Time ago formatter.
import javascriptTimeAgo from 'javascript-time-ago'
// Load locale-specific relative date/time formatting rules.
import en from 'javascript-time-ago/locales/en'
import ru from 'javascript-time-ago/locales/ru'
// Add locale-specific relative date/time formatting rules.
javascriptTimeAgo.locale(en)
javascriptTimeAgo.locale(ru)
javascript-time-ago
uses intl-messageformat
internally. IntlMessageFormat
is a helper library made by Yahoo which formats plurals internationally (e.g. "1 second", "2 seconds", etc).
Both these libraries must be initialized with a set of desired locales first. For that, IntlMessageFormat
needs to be accessible as a global variable (though I don't agree with such a design choice). For Webpack that would be:
plugins: [
new webpack.ProvidePlugin({
IntlMessageFormat: ['intl-messageformat', 'default'],
}),
// ...
]
After the initialization step is complete it is ready to format relative dates.
import javascriptTimeAgo from 'javascript-time-ago'
const timeAgoEnglish = new javascriptTimeAgo('en-US')
timeAgoEnglish.format(new Date())
// "just now"
timeAgoEnglish.format(new Date(Date.now() - 60 * 1000))
// "a minute ago"
timeAgoEnglish.format(new Date(Date.now() - 2 * 60 * 60 * 1000))
// "2 hours ago"
timeAgoEnglish.format(new Date(Date.now() - 24 * 60 * 60 * 1000))
// "a day ago"
const timeAgoRussian = new javascriptTimeAgo('ru-RU')
timeAgoRussian.format(new Date())
// "только что"
timeAgoRussian.format(new Date(Date.now() - 60 * 1000)))
// "минуту назад"
timeAgoRussian.format(new Date(Date.now() - 2 * 60 * 60 * 1000)))
// "2 часа назад"
timeAgoRussian.format(new Date(Date.now() - 24 * 60 * 60 * 1000))
// "днём ранее"
Mimics Twitter style of time ago ("1m", "2h", "Mar 3", "Apr 4, 2012")
…
const timeAgo = new javascriptTimeAgo('en-US')
// A `style` is simply an `options` object
// passed to the `.format()` function as a second parameter.
const twitter = timeAgo.style.twitter()
timeAgo.format(new Date(), twitter)
// ""
timeAgo.format(new Date(Date.now() - 60 * 1000), twitter)
// "1m"
timeAgo.format(new Date(Date.now() - 2 * 60 * 60 * 1000), twitter)
// "2h"
timeAgo.style.fuzzy()
Similar to the default style but with "ago" omitted:
Since thread safety is hard most likely intl-messageformat
isn't thread safe. Same goes for Intl.DateTimeFormat
(both native and polyfill): most likely they aren't thread safe either. Therefore javascript-time-ago
should be considered non-thread-safe.
But it doesn't really matter because javascript is inherently single-threaded: both in a web browser and in Node.js.
A javascript-time-ago
instance caches formatters once it has used them therefore there can be a single javascript-time-ago
instance for the whole application (including server side) which is supposed to be a bit (perhaps negligibly) faster while staying safe.
To install the Intl polyfill (supporting 200+ languages):
npm install intl --save
Then configure the Intl polyfill:
This library currently comes with English and Russian localization built-in, but any other locale can be added easily at runtime (Pull Requests adding new locales are accepted too).
The built-in localization resides in the locales
folder.
The format of the localization is:
{
…
"day":
{
"past":
{
"one": "{0} day ago",
"other": "{0} days ago"
},
"future":
{
"one": "in {0} day",
"other": "in {0} days"
}
},
…
}
The past
and future
can be defined by any of: zero
, one
, two
, few
, many
and other
. For more info on which is which read the official Unicode CLDR documentation. Unicode CLDR (Common Locale Data Repository) is an industry standard and is basically a collection of formatting rules for all locales (date, time, currency, measurement units, numbers, etc).
One can also pass raw Unicode CLDR locale data .json
files (found in CLDR repository) which will be automatically converted by this library to the format described above.
Example CLDR data for en-US-POSIX locale
{
"main": {
"en-US-POSIX": {
"dates": {
"fields": {
…
"day": {
"displayName": "day", // ignored
"relative-type--1": "yesterday", // ignored
"relative-type-0": "today", // ignored
"relative-type-1": "tomorrow", // ignored
"relativeTime-type-future": {
"relativeTimePattern-count-one" : "in {0} day",
"relativeTimePattern-count-other" : "in {0} days"
},
"relativeTime-type-past": {
"relativeTimePattern-count-one" : "{0} day ago",
"relativeTimePattern-count-other" : "{0} days ago"
}
},
…
}
}
}
}
}
So, to add support for a specific language one can install CLDR dates package:
npm install cldr-dates-modern --save
And then add the neccessary locales from it:
import javascriptTimeAgo from 'javascript-time-ago'
import ru from 'cldr-dates-modern/main/ru/dateFields.json'
javascriptTimeAgo.locale(ru)
const timeAgo = new javascriptTimeAgo('ru')
timeAgo.format(new Date(Date.now() - 60 * 1000))
// "1 минуту назад"
No locales are loaded by default. This is done to allow tools like Webpack take advantage of code splitting to reduce the resulting javascript bundle size.
On the other hand, server side doesn't need code splitting, so to load all available locales in Node.js one can use this shortcut:
// A faster way to load all localization data for Node.js
// (`intl-messageformat` will load everything automatically when run in Node.js)
require('javascript-time-ago/load-all-locales')
Localization data described in the above section can be further customized, for example, supporting long
and short
formats. Refer to locales/en.js
for an example.
Built-in localization data is presented in different variants:
import english from 'javascript-time-ago/locales/en'
english.tiny // '1s', '2m', '3h', '4d', …
english.short // '1 sec. ago', '2 min. ago', …
english.long // '1 second ago', '2 minutes ago', …
One can pass style
as a second parameter to the .format(date, style)
function. The style
object can specify:
flavour
– preferred labels variant (e.g. tiny
, short
, long
)units
– a list of time interval measurement units which can be used in the formatted output (e.g. ['second', 'minute', 'hour']
)gradation
– custom time interval measurement units scaleoverride
– is a function of { elapsed, time, date, now }
. If the override
function returns a value, then the .format()
call will return that value. Otherwise the date/time is formatter as usual.(see twitter
style for an example)
A gradation
is a list of time interval measurement steps. A simple example:
[
{
unit: 'second',
},
{
unit: 'minute',
factor: 60,
threshold: 59.5
},
{
unit: 'hour',
factor: 60 * 60,
threshold: 59.5 * 60
},
…
]
factor
is a divider for the supplied time interval (in seconds)threshold
is a minimum time interval value (in seconds) required for this gradation stepthreshold
customization is possible, see ./source/gradation.js
for more info)granularity
can also be specified (for example, 5
for minute
to allow only 5-minute intervals)For more gradation examples see source/gradation.js
Built-in gradations:
import { gradation } from 'javascript-time-ago'
gradation.canonical() // '1 second ago', '2 minutes ago', …
gradation.convenient() // 'just now', '5 minutes ago', …
When given future dates .format()
produces the corresponding output, e.g. "in 5 minutes", "in a year", etc.
There is also a React component built upon this library which autorefreshes itself.
After cloning this repo, ensure dependencies are installed by running:
npm install
This module is written in ES6 and uses Babel for ES5 transpilation. Widely consumable JavaScript can be produced by running:
npm run build
Once npm run build
has run, you may import
or require()
directly from
node.
After developing, the full test suite can be evaluated by running:
npm test
When you're ready to test your new functionality on a real project, you can run
npm pack
It will build
, test
and then create a .tgz
archive which you can then install in your project folder
npm install [module name with version].tar.gz
FAQs
Localized relative date/time formatting
The npm package javascript-time-ago receives a total of 289,690 weekly downloads. As such, javascript-time-ago popularity was classified as popular.
We found that javascript-time-ago demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
Security News
Research
An advanced npm supply chain attack is leveraging Ethereum smart contracts for decentralized, persistent malware control, evading traditional defenses.
Security News
Research
Attackers are impersonating Sindre Sorhus on npm with a fake 'chalk-node' package containing a malicious backdoor to compromise developers' projects.