{"_id":"@appents/human-time","_rev":"2-18dec824bc35d52707da43113b17d864","name":"@appents/human-time","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@appents/human-time","version":"0.1.0","keywords":["time","datetime","relative-time","intl","pluralrules","ui","formatter"],"author":{"name":"Taman Islam"},"license":"MIT","_id":"@appents/human-time@0.1.0","maintainers":[{"name":"hedayet","email":"hedayetshi@yahoo.com"}],"homepage":"https://github.com/taman-islam/human-time#readme","bugs":{"url":"https://github.com/taman-islam/human-time/issues"},"dist":{"shasum":"b7b4d167787a0abcd4d454d11f5a326fd30ebe0f","tarball":"https://registry.npmjs.org/@appents/human-time/-/human-time-0.1.0.tgz","fileCount":5,"integrity":"sha512-MyI4u09joTs+8IFb0fgBvjT8L6ls0oApNliwgCecuhLLgUfGJ08MlTkjklzfqeBVjkyUKvCotCsK+1Bim+3JsQ==","signatures":[{"sig":"MEYCIQD/XqFBo3dk2nInjtVe4wGqDlT04glyO2XvtqhHv3a7RwIhAOaLHhbZpaqwq4AEYuCkN/FW1dN3Oxxm7zLEm5E50qtr","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":16003},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"839d3c5d2d082655103ec7271f0a59825bc9bf00","scripts":{"lint":"eslint .","test":"jest","build":"tsc","format":"prettier --write .","lint:fix":"eslint . --fix","test:watch":"jest --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"hedayet","email":"hedayetshi@yahoo.com"},"repository":{"url":"git+https://github.com/taman-islam/human-time.git","type":"git"},"_npmVersion":"10.9.3","description":"Zero-dependency relative time formatter for UI systems. Built on native Intl.PluralRules.","directories":{},"sideEffects":false,"_nodeVersion":"22.19.0","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^9.17.0","postcss":"^8","ts-jest":"^29.1.5","prettier":"^3.4.2","typescript":"^5.4.5","@types/jest":"^29.5.14","eslint-plugin-jest":"^28.11.0","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.2.1","jest-environment-jsdom":"^30.2.0","@stylistic/eslint-plugin":"^2.12.1","@typescript-eslint/parser":"^8.18.0","eslint-plugin-unused-imports":"^4.1.4","@typescript-eslint/eslint-plugin":"^8.18.0"},"_npmOperationalInternal":{"tmp":"tmp/human-time_0.1.0_1775857760082_0.36800210474847406","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@appents/human-time","version":"0.2.0","type":"module","description":"Zero-dependency relative time formatter for UI systems. Built on native Intl.PluralRules.","main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"}},"sideEffects":false,"scripts":{"build":"tsc","prepublishOnly":"npm run build","test":"jest","test:watch":"jest --watch","lint":"eslint .","lint:fix":"eslint . --fix","format":"prettier --write ."},"repository":{"type":"git","url":"git+https://github.com/taman-islam/human-time.git"},"homepage":"https://github.com/taman-islam/human-time#readme","bugs":{"url":"https://github.com/taman-islam/human-time/issues"},"keywords":["time","datetime","relative-time","intl","pluralrules","ui","formatter"],"author":{"name":"Taman Islam"},"license":"MIT","devDependencies":{"@types/jest":"^29.5.14","@typescript-eslint/eslint-plugin":"^8.18.0","@typescript-eslint/parser":"^8.18.0","eslint-config-prettier":"^9.1.0","eslint-plugin-jest":"^28.11.0","eslint-plugin-prettier":"^5.2.1","eslint-plugin-unused-imports":"^4.1.4","eslint":"^9.17.0","jest-environment-jsdom":"^30.2.0","jest":"^29.7.0","postcss":"^8","prettier":"^3.4.2","ts-jest":"^29.1.5","typescript":"^5.4.5","@stylistic/eslint-plugin":"^2.12.1"},"_id":"@appents/human-time@0.2.0","gitHead":"28a4e28c5db883cac67f9be026fa1e9c2278b914","_nodeVersion":"22.19.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-UrjMm8YhfDBw5mf6D1Or4gqDY/caBgUveJppdwXw58QUf2p1e8oWKx24pL6VNPStuT5Vq4G7NI1acmPGWHLb5Q==","shasum":"5f3d39007a3b1bc5f7b61369da04458c307c83d5","tarball":"https://registry.npmjs.org/@appents/human-time/-/human-time-0.2.0.tgz","fileCount":5,"unpackedSize":16081,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCpJZMQq3eH0siN26mkXZf4drIH4FScKSeOqG0JnzTxgAIhAOaSykdyWXk+Gqo/nX38Q+0MgdQ/ClviT/IcqjfW3MOI"}]},"_npmUser":{"name":"hedayet","email":"hedayetshi@yahoo.com"},"directories":{},"maintainers":[{"name":"hedayet","email":"hedayetshi@yahoo.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/human-time_0.2.0_1775859933270_0.09856423092797173"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-10T21:49:20.015Z","modified":"2026-04-10T22:25:33.508Z","0.1.0":"2026-04-10T21:49:20.246Z","0.2.0":"2026-04-10T22:25:33.403Z"},"bugs":{"url":"https://github.com/taman-islam/human-time/issues"},"author":{"name":"Taman Islam"},"license":"MIT","homepage":"https://github.com/taman-islam/human-time#readme","keywords":["time","datetime","relative-time","intl","pluralrules","ui","formatter"],"repository":{"type":"git","url":"git+https://github.com/taman-islam/human-time.git"},"description":"Zero-dependency relative time formatter for UI systems. Built on native Intl.PluralRules.","maintainers":[{"name":"hedayet","email":"hedayetshi@yahoo.com"}],"readme":"# @appents/human-time\n\nA zero-dependency relative time formatter built on native `Intl.PluralRules` — designed for UI systems that treat time perception as a first-class concern.\n\n[**✨ Try the Interactive Live Demo**](http://appents.com/tech/human-time)\n\n\n```\n3m ago · In 2h · Just now · Mar 15\n```\n\n## Why this exists\n\nTime formatting looks simple until it isn't.\n\nThe moment a product spans multiple surfaces — feeds, notifications, dashboards, activity logs — time stops being a formatting problem and becomes a consistency problem.\n\n\"Just now\" lasts 30 seconds in one place and 2 minutes in another.\n\"5m ago\" becomes \"0h ago\" when rounding leaks through.\nA week boundary behaves differently depending on who implemented it.\n\nNone of these are bugs in isolation. They're the natural result of each surface reimplementing its own idea of time perception.\n\n`human-time` exists to remove that drift. It defines time as a single, explicit set of rules — how quickly it fades, how it groups, how it transitions between units — and applies them deterministically across every surface.\n\n## Installation\n\n```bash\nnpm install @appents/human-time\n```\n\n## Usage\n\n### Compact format (feeds, notifications)\n\n```typescript\nimport { formatRelative } from '@appents/human-time';\n\nconst past = new Date(Date.now() - 5 * 60_000);\nformatRelative(past); // \"5m ago\"\n\nconst future = new Date(Date.now() + 3 * 3_600_000);\nformatRelative(future); // \"In 3h\"\n```\n\n### Long format (tables, dashboards, timelines)\n\n```typescript\nimport { formatRelativeLong } from '@appents/human-time';\n\nconst past = new Date(Date.now() - 5 * 60_000);\nformatRelativeLong(past); // \"5 minutes ago\"\n```\n\n## Configuration\n\nEvery threshold is explicit and overridable:\n\n```typescript\nformatRelative(date, {\n  config: {\n    smoothMs: 30_000, // \"Just now\" window — 30s instead of default 90s\n    weekCutoff: 5, // switch to weeks after 5 days, not 7\n    monthCutoff: 6, // switch to months after 6 weeks, not 4\n  },\n});\n```\n\n| Option        | Default  | Effect                           |\n| ------------- | -------- | -------------------------------- |\n| `smoothMs`    | `90_000` | Milliseconds shown as \"Just now\" |\n| `weekCutoff`  | `7`      | Days before switching to weeks   |\n| `monthCutoff` | `4`      | Weeks before switching to months |\n\nBeyond 12 months, output falls back to a localized absolute date (`Mar 15` or `Mar 15, 2023`).\n\n## Localization\n\nSupply a full dictionary to override every string:\n\n```typescript\nimport { formatRelative, LocaleDictionary } from '@appents/human-time';\n\nconst esDictionary: LocaleDictionary = {\n  smoothed: {\n    past: 'Hace un momento',\n    future: 'En un momento',\n  },\n  relative: {\n    past: (val) => `Hace ${val}`,\n    future: (val) => `En ${val}`,\n  },\n  units: {\n    short: {\n      minute: 'm',\n      hour: 'h',\n      day: 'd',\n      week: 'w',\n      month: 'mo',\n    },\n    long: {\n      minute: { one: 'minuto', other: 'minutos' },\n      hour: { one: 'hora', other: 'horas' },\n      day: { one: 'día', other: 'días' },\n      week: { one: 'semana', other: 'semanas' },\n      month: { one: 'mes', other: 'meses' },\n    },\n  },\n};\n\nformatRelative(date, { locale: 'es', dictionary: esDictionary });\n```\n\nPlural forms are resolved via `Intl.PluralRules` — no hardcoded rules, no locale bundles.\n\n## Features\n\n- **Zero dependencies** — native platform APIs only\n- **2.3 KB minified, ~1.0 KB gzipped**\n- **Tree-shakeable** — import only what you use\n- **Native `Intl.PluralRules` pluralization** — correct across locales\n- **Configurable thresholds** — tune every time perception boundary\n- **Symmetric past/future formatting**\n- **Full TypeScript support** — strictly typed options, configs, and dictionaries\n- **Dictionary-based i18n** — override any string, any language\n\n## Bundle size\n\n| Library                 | Minified                            | Gzipped                    |\n| ----------------------- | ----------------------------------- | -------------------------- |\n| moment                  | ~290 KB                             | ~65 KB                     |\n| luxon                   | ~40 KB                              | ~14 KB                     |\n| date-fns                | ~1–10 KB per function (tree-shaken) | up to ~70 KB (full import) |\n| **@appents/human-time** | **2.3 KB**                          | **~1.0 KB**                |\n\nNo dependencies. No date parsing. No locale bundles.\n\n## When to use\n\nSocial feeds · notifications · messaging apps · activity timelines · dashboards · CRMs\n","readmeFilename":"README.md"}