{"id":19777361,"url":"https://github.com/catamphetamine/react-time-ago","last_synced_at":"2025-04-30T19:32:14.072Z","repository":{"id":45368577,"uuid":"55955738","full_name":"catamphetamine/react-time-ago","owner":"catamphetamine","description":"Localized relative date/time formatting in React","archived":false,"fork":false,"pushed_at":"2024-05-06T18:07:11.000Z","size":2619,"stargazers_count":100,"open_issues_count":1,"forks_count":13,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-06T04:31:59.554Z","etag":null,"topics":["react","time"],"latest_commit_sha":null,"homepage":"https://catamphetamine.github.io/react-time-ago/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/catamphetamine.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-04-11T08:40:04.000Z","updated_at":"2025-03-10T11:16:46.000Z","dependencies_parsed_at":"2024-02-26T11:49:32.966Z","dependency_job_id":"b87190f6-0495-4840-a63b-80a740f497f5","html_url":"https://github.com/catamphetamine/react-time-ago","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catamphetamine%2Freact-time-ago","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catamphetamine%2Freact-time-ago/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catamphetamine%2Freact-time-ago/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catamphetamine%2Freact-time-ago/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/catamphetamine","download_url":"https://codeload.github.com/catamphetamine/react-time-ago/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251769444,"owners_count":21640902,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["react","time"],"created_at":"2024-11-12T05:24:36.685Z","updated_at":"2025-04-30T19:32:13.070Z","avatar_url":"https://github.com/catamphetamine.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# react-time-ago\r\n\r\n[![npm version](https://img.shields.io/npm/v/react-time-ago.svg?style=flat-square)](https://www.npmjs.com/package/react-time-ago)\r\n\r\nLocalized relative date/time formatting (both for past and future dates).\r\n\r\nAutomatically chooses the right units (seconds, minutes, etc) to format a time interval.\r\n\r\nAutomatically refreshes itself.\r\n\r\n[See Demo](https://catamphetamine.gitlab.io/react-time-ago/)\r\n\r\nExamples:\r\n\r\n  * just now\r\n  * 45s\r\n  * 5m\r\n  * 15 minutes ago\r\n  * 3 hours ago\r\n  * in 2 months\r\n  * in 5 years\r\n  * …\r\n\r\n## Install\r\n\r\nThe `react-time-ago` component uses [`javascript-time-ago`](https://gitlab.com/catamphetamine/javascript-time-ago) library for generating date/time labels, so both of these packages should be installed:\r\n\r\n```sh\r\n$ npm install react-time-ago javascript-time-ago --save\r\n```\r\n\r\nIf you're not using a bundler then use a [standalone version from a CDN](#cdn).\r\n\r\n## Use\r\n\r\nFirst, `javascript-time-ago` must be [initialized](https://github.com/catamphetamine/javascript-time-ago#locales) with some locales:\r\n\r\n#### ./src/index.js\r\n\r\n```js\r\nimport TimeAgo from 'javascript-time-ago'\r\n\r\nimport en from 'javascript-time-ago/locale/en'\r\nimport ru from 'javascript-time-ago/locale/ru'\r\n\r\nTimeAgo.addDefaultLocale(en)\r\nTimeAgo.addLocale(ru)\r\n```\r\n\r\nThen, use `\u003cReactTimeAgo/\u003e` component:\r\n\r\n#### ./src/LastSeen.js\r\n\r\n```js\r\nimport React from 'react'\r\nimport ReactTimeAgo from 'react-time-ago'\r\n\r\nexport default function LastSeen({ date }) {\r\n  return (\r\n    \u003cdiv\u003e\r\n      Last seen: \u003cReactTimeAgo date={date} locale=\"en-US\"/\u003e\r\n    \u003c/div\u003e\r\n  )\r\n}\r\n```\r\n\r\n## Hook\r\n\r\nIf you prefer using a React Hook instead of a React Component, the parameters for it are the same as the [props](#props) for the React component, except:\r\n\r\n* `tooltip: boolean` \r\n* `component: React.Component`\r\n* `wrapperComponent: React.Component`\r\n* `wrapperProps: object`\r\n\r\n```js\r\nimport { useTimeAgo } from 'react-time-ago'\r\n\r\nconst result = useTimeAgo(parameters)\r\n```\r\n\r\nReturns an object with properties:\r\n\r\n* `date: Date` — Same as the `date` input parameter. If the input parameter was a timestamp (`number`) then it gets converted to a `Date`.\r\n* `formattedDate: string` — Formatted `date`. Example: `\"5 min ago\"`.\r\n* `verboseDate: string` — Formatted `date` (verbose variant). Example: `\"Thursday, December 20, 2012, 7:00:00 AM GMT+4\"`.\r\n\r\n## Style\r\n\r\n`\u003cReactTimeAgo/\u003e` component accepts an optional `timeStyle` property — it should be a `javascript-time-ago` [style](https://github.com/catamphetamine/javascript-time-ago#styles): either a built-in style name (like `\"round\"`, `\"round-minute\"`, `\"twitter\"`, etc) or a [custom](https://github.com/catamphetamine/javascript-time-ago#custom) style object.\r\n\r\n```js\r\n\u003cReactTimeAgo date={date} locale=\"en-US\" timeStyle=\"twitter\"/\u003e\r\n```\r\n\r\n## React Native\r\n\r\nBy default, this component renders a `\u003ctime/\u003e` HTML tag. When using this component in React Native, pass a custom `component` property:\r\n\r\n```js\r\nimport React from 'react'\r\nimport PropTypes from 'prop-types'\r\nimport ReactTimeAgo from 'react-time-ago'\r\n\r\nexport default function TimeAgo(props) {\r\n  return \u003cReactTimeAgo {...props} component={Time}/\u003e\r\n}\r\n\r\nfunction Time({ date, verboseDate, tooltip, children }) {\r\n  return \u003cText\u003e{children}\u003c/Text\u003e\r\n}\r\n\r\nTime.propTypes = {\r\n  date: PropTypes.instanceOf(Date).isRequired,\r\n  verboseDate: PropTypes.string,\r\n  tooltip: PropTypes.bool.isRequired,\r\n  children: PropTypes.string.isRequired\r\n}\r\n```\r\n\r\n## Tooltip\r\n\r\nBy default, the standard HTML `title` attribute is used to display a tooltip with the verbose date on mouse over.\r\n\r\nFor custom tooltip design, a custom tooltip component could be rendered. For that, `\u003cReactTimeAgo/\u003e` supports properties:\r\n\r\n* `tooltip={false}` — Instructs the component not to add the default HTML `title` attribute.\r\n* `wrapperComponent` — A React component that's gonna wrap the date/time label. Receives properties: `children` (Example: `\u003ctime\u003e2 days ago\u003c/time\u003e`) and `verboseDate: string` (Example: \"Wednesday, January 1, 2000, 10:45:10 PM\").\r\n* `wrapperProps` — If defined, these properties are passed through to the `wrapperComponent`.\r\n\r\nFor example, here's how to render a [`react-responsive-ui/Tooltip`](https://catamphetamine.gitlab.io/react-responsive-ui/#tooltip):\r\n\r\n```js\r\nimport React from 'react'\r\nimport PropTypes from 'prop-types'\r\nimport Tooltip from 'react-responsive-ui/commonjs/Tooltip'\r\nimport ReactTimeAgo from 'react-time-ago'\r\nimport 'react-time-ago/Tooltip.css'\r\n\r\nexport default function ReactTimeAgoWithTooltip(props) {\r\n  return (\r\n    \u003cReactTimeAgo\r\n      {...props}\r\n      wrapperComponent={TooltipContainer}\r\n      tooltip={false}/\u003e\r\n  )\r\n}\r\n\r\nconst TooltipContainer = ({ verboseDate, children, ...rest }) =\u003e (\r\n  \u003cTooltip {...rest} content={verboseDate}\u003e\r\n    {children}\r\n  \u003c/Tooltip\u003e\r\n)\r\n\r\nTooltipContainer.propTypes = {\r\n  // `verboseDate` is not generated on server side\r\n  // (because tooltips are only shown on mouse over),\r\n  // so it's not declared a \"required\" property.\r\n  verboseDate: PropTypes.string,\r\n  children: PropTypes.node.isRequired\r\n}\r\n```\r\n\r\n## Future\r\n\r\nWhen given future dates, `.format()` produces the corresponding output.: `\"in 5 minutes\"`, `\"in 10 days\"`, etc.\r\n\r\nTo restrict the formatted date to be future-only, pass `future` property, and it will stop when it reaches \"zero point\" (`\"in a moment\"`) and won't allow the `date` to be formatted as a past one.\r\n\r\n```js\r\n\u003cReactTimeAgo future date={date} .../\u003e\r\n```\r\n\r\n\u003c!--\r\n## ES6\r\n\r\nThis library uses ES6 `Set` so any ES6 polyfill for `Set` is required (e.g. `import 'babel-polyfill'` or `import 'core-js/fn/set'`).\r\n--\u003e\r\n\r\n## CDN\r\n\r\nOne can use any npm CDN service, e.g. [unpkg.com](https://unpkg.com) or [jsdelivr.com](https://jsdelivr.com)\r\n\r\n```html\r\n\u003c!-- Example `[version]`: `2.x` --\u003e\r\n\u003cscript src=\"https://unpkg.com/javascript-time-ago@[version]/bundle/javascript-time-ago.js\"\u003e\u003c/script\u003e\r\n\u003cscript src=\"https://unpkg.com/react-time-ago@[version]/bundle/react-time-ago.js\"\u003e\u003c/script\u003e\r\n\r\n\u003cscript\u003e\r\n  TimeAgo.addDefaultLocale({\r\n    locale: 'en',\r\n    now: {\r\n      now: {\r\n        current: \"now\",\r\n        future: \"in a moment\",\r\n        past: \"just now\"\r\n      }\r\n    },\r\n    long: {\r\n      year: {\r\n        past: {\r\n          one: \"{0} year ago\",\r\n          other: \"{0} years ago\"\r\n        },\r\n        future: {\r\n          one: \"in {0} year\",\r\n          other: \"in {0} years\"\r\n        }\r\n      },\r\n      ...\r\n    }\r\n  })\r\n\u003c/script\u003e\r\n\r\n\u003cscript\u003e\r\n  ...\r\n  \u003cReactTimeAgo date={new Date()} locale=\"en-US\" timeStyle=\"twitter\"/\u003e\r\n  ...\r\n\u003c/script\u003e\r\n```\r\n\r\n## Props\r\n\r\n```js\r\n// `date: Date` or `timestamp: number`.\r\n// E.g. `new Date()` or `1355972400000`.\r\ndate: PropTypes.oneOfType([\r\n  PropTypes.instanceOf(Date),\r\n  PropTypes.number\r\n]).isRequired,\r\n\r\n// Preferred locale.\r\n// Is 'en' by default.\r\n// E.g. 'ru-RU'.\r\nlocale: PropTypes.string,\r\n\r\n// Alternatively to `locale`, one could pass `locales`:\r\n// A list of preferred locales (ordered).\r\n// Will choose the first supported locale from the list.\r\n// E.g. `['ru-RU', 'en-GB']`.\r\nlocales: PropTypes.arrayOf(PropTypes.string),\r\n\r\n// If set to `true`, then will stop at \"zero point\"\r\n// when going from future dates to past dates.\r\n// In other words, even if the `date` has passed,\r\n// it will still render as if `date` is `now`.\r\nfuture: PropTypes.bool,\r\n\r\n// Date/time formatting style.\r\n// See `javascript-time-ago` docs on \"Styles\" for more info.\r\n// E.g. 'round', 'round-minute', 'twitter', 'twitter-first-minute'.\r\ntimeStyle: PropTypes.oneOfType([\r\n  PropTypes.string,\r\n  PropTypes.object\r\n]),\r\n\r\n// `round` parameter of `javascript-time-ago`.\r\n// See `javascript-time-ago` docs on \"Rounding\" for more info.\r\n// Examples: \"round\", \"floor\".\r\nround: PropTypes.string,\r\n\r\n// If specified, the time won't \"tick\" past this threshold (in seconds).\r\n// For example, if `minTimeLeft` is `60 * 60`\r\n// then the time won't \"tick\" past \"in 1 hour\".\r\nminTimeLeft: PropTypes.number,\r\n\r\n// A React component to render the relative time label.\r\n// Receives properties:\r\n// * date: Date — The date.\r\n// * verboseDate: string — Formatted verbose date.\r\n// * tooltip: boolean — The `tooltip` property of `\u003cReactTimeAgo/\u003e` component.\r\n// * children: string — The relative time label.\r\n// * All \"unknown\" properties that have been passed to `\u003cReactTimeAgo/\u003e` are passed through to this component.\r\ncomponent: PropTypes.elementType,\r\n\r\n// Whether to use HTML `tooltip` attribute to show a verbose date tooltip.\r\n// Is `true` by default.\r\n// Can be set to `false` to disable the native HTML `tooltip`.\r\ntooltip: PropTypes.bool,\r\n\r\n// Verbose date formatter.\r\n// By default it's `(date) =\u003e new Intl.DateTimeFormat(locale, {…}).format(date)`.\r\nformatVerboseDate: PropTypes.func,\r\n\r\n// `Intl.DateTimeFormat` format for formatting verbose date.\r\n// See `Intl.DateTimeFormat` docs for more info.\r\nverboseDateFormat: PropTypes.object,\r\n\r\n// (deprecated)\r\n// How often the component refreshes itself.\r\n// When not provided, will use `getNextTimeToUpdate()` feature\r\n// of `javascript-time-ago` styles to determine the update interval.\r\nupdateInterval: PropTypes.oneOfType([\r\n  PropTypes.number,\r\n  PropTypes.arrayOf(PropTypes.shape({\r\n    threshold: PropTypes.number,\r\n    interval: PropTypes.number.isRequired\r\n  }))\r\n]),\r\n\r\n// (deprecated).\r\n// Set to `false` to disable automatic refresh of the component.\r\n// Is `true` by default.\r\n// I guess no one actually turns auto-update off, so this parameter is deprecated.\r\ntick: PropTypes.bool,\r\n\r\n// Allows setting a custom baseline for relative time measurement.\r\n// https://gitlab.com/catamphetamine/react-time-ago/-/issues/4\r\nnow: PropTypes.number,\r\n\r\n// Allows offsetting the `date` by an arbitrary amount of milliseconds.\r\n// https://gitlab.com/catamphetamine/react-time-ago/-/issues/4\r\ntimeOffset: PropTypes.number,\r\n\r\n// Pass `false` to use native `Intl.RelativeTimeFormat` / `Intl.PluralRules`\r\n// instead of the polyfilled ones in `javascript-time-ago`.\r\npolyfill: PropTypes.bool,\r\n\r\n// (advanced)\r\n// A React Component to wrap the resulting `\u003ctime/\u003e` React Element.\r\n// Receives `verboseDate` and `children` properties.\r\n// Also receives `wrapperProps`, if they're passed.\r\n// `verboseDate` can be used for displaying verbose date label\r\n// in an \"on mouse over\" (or \"on touch\") tooltip.\r\n// See the \"Tooltip\" readme section for more info.\r\n// Another example could be having `wrapperComponent`\r\n// being rerendered every time the component refreshes itself.\r\nwrapperComponent: PropTypes.elementType,\r\n\r\n// Custom `props` passed to `wrapperComponent`.\r\nwrapperProps: PropTypes.object\r\n```\r\n\r\n## TypeScript\r\n\r\nThis library comes with TypeScript \"typings\". If you happen to find any bugs in those, create an issue.\r\n\r\n## GitHub\r\n\r\nOn March 9th, 2020, GitHub, Inc. silently [banned](https://medium.com/@catamphetamine/how-github-blocked-me-and-all-my-libraries-c32c61f061d3) my account (erasing all my repos, issues and comments) without any notice or explanation. Because of that, all source codes had to be promptly moved to [GitLab](https://gitlab.com/catamphetamine/react-time-ago). GitHub repo is now deprecated, and the latest source codes can be found on GitLab, which is also the place to report any issues.\r\n\r\n## License\r\n\r\n[MIT](LICENSE)\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcatamphetamine%2Freact-time-ago","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcatamphetamine%2Freact-time-ago","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcatamphetamine%2Freact-time-ago/lists"}