
Security News
/Company News
Socket Is Sponsoring Composer and Packagist
Socket has joined the new Composer and Packagist sponsorship program as a launch sponsor, supporting the team that keeps PHP's package ecosystem secure.
@master4n/temporal-transformer
Advanced tools
TypeScript library to convert epoch timestamps (seconds, milliseconds, microseconds, nanoseconds) to human-readable dates, parse date strings to epoch, compute calendar-accurate durations, and handle IANA timezones. Powered by Luxon — small bundle, immuta
Convert any epoch timestamp to a human-readable date in TypeScript — auto-detects seconds, milliseconds, microseconds, and nanoseconds with zero configuration. Also converts date strings to epoch, computes calendar-accurate durations, and handles any IANA timezone.
v2.0 is out. Engine swapped from moment.js to Luxon — same API, ~60% smaller bundle (~71 KB vs ~180 KB), no maintenance-mode dependency. Upgrade with
npm i @master4n/temporal-transformer@2and runnpx @master4n/temporal-transformer-codemod ./srcto migrate format strings automatically. See MIGRATION.md.
Working with epoch timestamps in TypeScript is surprisingly painful:
new Date(epoch) silently produces wrong dates if the unit is wrong.temporal-transformer solves all of these in one small, fully-typed package:
// No idea what unit this is? No problem.
// (All four resolve to the same instant — 2021-06-01T11:43:20Z. Display below in IST for illustration.)
convertEpoch(1622547800).dateTime; // seconds → "2021-06-01 17:13:20.000"
convertEpoch(1622547800000).dateTime; // millis → "2021-06-01 17:13:20.000"
convertEpoch(1622547800000000).dateTime; // micros → "2021-06-01 17:13:20.000"
convertEpoch(1622547800000000000).dateTime; // nanos → "2021-06-01 17:13:20.000"
safeXxx variant returning { ok, value | error } instead of throwingisValidEpoch / isValidTimezone that never throwObject.freeze()'d to prevent downstream tamperingFormatInvalid instead of silently producing garbageInfinity, NaN, prototype-pollution attempts, and clock-corruption edge casesIntl API, no moment.js, Node 18+npm install @master4n/temporal-transformer
# or
yarn add @master4n/temporal-transformer
# or
pnpm add @master4n/temporal-transformer
import {
convertEpoch,
convertDateToEpoch,
convertEpochToTimezone,
parseToEpoch,
getDurationBetween,
isValidEpoch,
} from '@master4n/temporal-transformer';
// Convert any epoch to a readable date — unit is auto-detected
const result = convertEpoch(1622547800000);
console.log(result.dateTime); // e.g. "2021-06-01 17:13:20.000" (your local TZ — IST shown)
console.log(result.dateTimeInGMT); // "2021-06-01 11:43:20.000"
console.log(result.epochUnit); // "milliseconds"
console.log(result.relative); // e.g. "4 years 11 months ago"
// Convert a Date object to epoch values
const epoch = convertDateToEpoch(new Date(), 'America/New_York');
console.log(epoch.epochInSeconds); // e.g. 1748000000
console.log(epoch.epochInMilliseconds); // e.g. 1748000000000
// Parse a date string to epoch (strict, timezone-aware)
const parsed = parseToEpoch('2024-12-25T00:00:00', undefined, 'Asia/Kolkata');
console.log(parsed.epochInMilliseconds);
// Format an epoch in a specific timezone
const formatted = convertEpochToTimezone(1622547800000, 'Asia/Tokyo', 'yyyy-MM-dd HH:mm');
console.log(formatted); // "2021-06-02 02:43"
// Calendar-accurate duration between two timestamps
const duration = getDurationBetween(1609459200000, 1622547800000);
console.log(duration.humanReadable); // "4 months, 15 days, 17 hours, 43 minutes, 20 seconds"
// Safe validation — never throws
console.log(isValidEpoch(1622547800000)); // true
console.log(isValidEpoch('bad value')); // false
console.log(isValidEpoch(Infinity)); // false
convertEpoch(epoch, format?)Converts any epoch value to a human-readable date. Automatically detects the epoch unit (seconds / milliseconds / microseconds / nanoseconds).
function convertEpoch(epoch: number, format?: string): EpochToDate
| Parameter | Type | Default | Description |
|---|---|---|---|
epoch | number | — | Epoch value in any unit |
format | string | 'yyyy-MM-dd HH:mm:ss.SSS' | Luxon format token (validated against SUPPORTED_FORMAT_TOKENS) |
Returns: EpochToDate
const result = convertEpoch(1622547800000, 'yyyy-MM-dd');
// { epoch: 1622547800000, epochUnit: 'milliseconds', timezone: 'Asia/Kolkata',
// dateTime: '2021-06-01', dateTimeInGMT: '2021-06-01', relative: '...' }
convertDateToEpoch(date, timezone?)Converts a Date object to epoch values (seconds and milliseconds) in the specified timezone.
function convertDateToEpoch(date: Date, timezone?: string): DateToEpoch
| Parameter | Type | Default | Description |
|---|---|---|---|
date | Date | — | Any valid JavaScript Date |
timezone | string | System local timezone | IANA timezone name |
Returns: DateToEpoch
const result = convertDateToEpoch(new Date('2024-01-15'), 'America/New_York');
// { epochInSeconds: 1705276800, epochInMilliseconds: 1705276800000,
// dateTime: '2024-01-14 19:00:00', dateTimeInGMT: '2024-01-15 00:00:00',
// timezone: 'America/New_York' }
convertEpochToTimezone(epoch, timezone, format?)Formats an epoch value as a date string in a specific IANA timezone.
function convertEpochToTimezone(epoch: number, timezone: string, format?: string): string
convertEpochToTimezone(1622547800000, 'America/Los_Angeles', 'yyyy-MM-dd HH:mm:ss');
// "2021-06-01 04:43:20" (PDT, UTC−7 in June)
convertEpochToTimezone(1622547800000, 'Asia/Tokyo');
// "2021-06-01 20:43:20.000" (JST, UTC+9)
getEpochUnit(epoch)Returns just the detected unit of an epoch value — useful for routing logic without doing the full conversion.
function getEpochUnit(epoch: number | string): EpochUnit
getEpochUnit(1622547800); // EpochUnit.SECONDS === 'seconds'
getEpochUnit(1622547800000); // EpochUnit.MILLI_SECONDS === 'milliseconds'
getEpochUnit(1622547800000000); // EpochUnit.MICRO_SECONDS === 'microseconds'
getEpochUnit(1622547800000000000); // EpochUnit.NANO_SECONDS === 'nanoseconds'
parseToEpoch(input, format?, timezone?)Parses a date string into epoch values. Uses strict parsing when a format is provided — never silently produces a wrong date.
function parseToEpoch(input: string, format?: string, timezone?: string): DateToEpoch
| Parameter | Type | Default | Description |
|---|---|---|---|
input | string | — | Date string to parse |
format | string or undefined | Auto (ISO 8601) | Luxon format token (validated against SUPPORTED_FORMAT_TOKENS) |
timezone | string | System local timezone | IANA timezone to interpret the date in |
Returns: DateToEpoch
Throws: EpochValidationError with EpochError.ParseError if the string cannot be parsed, or EpochError.TimezoneError for an unknown timezone.
// ISO 8601 auto-parsing
parseToEpoch('2024-12-25T00:00:00Z');
// Explicit format (strict mode — wrong format throws immediately)
parseToEpoch('25/12/2024', 'dd/MM/yyyy', 'Europe/London');
// With timezone context
parseToEpoch('2024-12-25 09:00:00', 'yyyy-MM-dd HH:mm:ss', 'Asia/Kolkata');
getDurationBetween(fromEpoch, toEpoch)Computes a calendar-accurate duration between two epoch timestamps.
function getDurationBetween(fromEpoch: number, toEpoch: number): ParsedDuration
Returns: ParsedDuration
Throws: EpochValidationError with EpochError.RangeError if fromEpoch > toEpoch.
const d = getDurationBetween(1609459200000, 1748000000000);
console.log(d.years); // 4
console.log(d.months); // 5
console.log(d.days); // 18
console.log(d.humanReadable); // "4 years, 5 months, 18 days, ..."
console.log(d.totalMilliseconds); // exact diff in ms
Calendar-accurate: months and years account for actual calendar boundaries (Feb 28/29, 30/31-day months), not fixed 30.44-day approximations.
getTimezoneOffset(timezone, epoch?)Returns the UTC offset for an IANA timezone, optionally at a specific point in time (useful for DST-aware offsets).
function getTimezoneOffset(timezone: string, epoch?: number): TimezoneOffset
getTimezoneOffset('Asia/Kolkata');
// { offset: '+05:30', offsetMinutes: 330 }
getTimezoneOffset('America/New_York');
// { offset: '-05:00', offsetMinutes: -300 } (or -04:00 during DST)
// DST-aware: pass the epoch you care about
getTimezoneOffset('America/New_York', 1622547800000);
// { offset: '-04:00', offsetMinutes: -240 }
getTimezoneList()Returns the full list of supported IANA timezone names (600+).
function getTimezoneList(): string[]
const zones = getTimezoneList();
zones.includes('Asia/Kolkata'); // true
zones.includes('America/Chicago'); // true
getEpochNow()Returns the current moment as epoch values (seconds, milliseconds, ISO string, and detected timezone).
function getEpochNow(): EpochNow
const now = getEpochNow();
// { seconds: 1748000000, milliseconds: 1748000000000,
// iso: '2025-05-23T10:13:20.000Z', timezone: 'Asia/Kolkata' }
formatDuration(milliseconds)Formats a duration in milliseconds as a human-readable string.
function formatDuration(milliseconds: number): string
formatDuration(3661000); // "1 hour, 1 minute, 1 second"
formatDuration(86400000); // "1 day"
formatDuration(90061000); // "1 day, 1 hour, 1 minute, 1 second"
formatDuration(500); // "0 seconds"
isValidEpoch(epoch) · isValidTimezone(timezone)Safe predicates that return boolean without throwing. Useful for conditional logic and input validation at system boundaries.
function isValidEpoch(epoch: unknown): boolean
function isValidTimezone(timezone: string): boolean
isValidEpoch(1622547800000); // true
isValidEpoch('1622547800000'); // true (numeric string)
isValidEpoch(null); // false
isValidEpoch(Infinity); // false
isValidEpoch(NaN); // false
isValidTimezone('UTC'); // true
isValidTimezone('Asia/Kolkata'); // true
isValidTimezone('Not/ATimezone'); // false
EpochToDateinterface EpochToDate {
epoch: number; // original input
epochUnit: string; // 'seconds' | 'milliseconds' | 'microseconds' | 'nanoseconds'
timezone: string; // IANA timezone used for dateTime
dateTime: string; // formatted date in local timezone
dateTimeInGMT: string; // formatted date in GMT
relative: string; // e.g. "3 hours 15 minutes ago"
}
DateToEpochinterface DateToEpoch {
epochInSeconds: number;
epochInMilliseconds: number;
timezone: string;
dateTime: string; // formatted in the given timezone
dateTimeInGMT: string;
}
ParsedDurationinterface ParsedDuration {
years: number;
months: number;
days: number;
hours: number;
minutes: number;
seconds: number;
milliseconds: number;
totalMilliseconds: number;
humanReadable: string; // e.g. "1 year, 2 months, 3 days"
}
EpochNowinterface EpochNow {
seconds: number;
milliseconds: number;
iso: string; // ISO 8601 UTC string
timezone: string; // detected local timezone
}
TimezoneOffsetinterface TimezoneOffset {
offset: string; // e.g. "+05:30"
offsetMinutes: number; // e.g. 330
}
EpochUnit enumenum EpochUnit {
SECONDS = 'seconds',
MILLI_SECONDS = 'milliseconds',
MICRO_SECONDS = 'microseconds',
NANO_SECONDS = 'nanoseconds',
}
DurationUnit typetype DurationUnit =
| 'years' | 'months' | 'weeks' | 'days'
| 'hours' | 'minutes' | 'seconds' | 'milliseconds';
| Absolute value range | Detected unit | Example value |
|---|---|---|
< 10,000,000,000 | seconds | 1622547800 |
< 10,000,000,000,000 | milliseconds | 1622547800000 |
< 10,000,000,000,000,000 | microseconds | 1622547800000000 |
< 1e19 | nanoseconds | 1622547800000000000 |
Negative epochs (dates before Unix epoch, i.e. before 1970-01-01) are fully supported.
All functions throw EpochValidationError (extends Error) with a message from the EpochError enum.
import { EpochValidationError, EpochError } from '@master4n/temporal-transformer';
try {
convertEpoch(null as any);
} catch (err) {
if (err instanceof EpochValidationError) {
console.log(err.message); // 'Epoch Is Undefined Or Null'
console.log(err.name); // 'EpochValidationError'
}
}
EpochError value | Thrown when |
|---|---|
UndefinedOrNull | Input is null or undefined |
NotANumber | Input is not numeric, is Infinity, or is NaN |
Empty | Input is an empty or whitespace-only string |
EpochUnit | Epoch value is too large to classify into any unit |
DateError | Date object passed to convertDateToEpoch is invalid |
TimezoneError | Timezone string is not a recognized IANA timezone |
ParseError | Date string cannot be parsed (in parseToEpoch) |
RangeError | fromEpoch > toEpoch in getDurationBetween |
Every function has a safeXxx counterpart that returns a discriminated Result<T> object instead of throwing. This is ideal for code paths handling untrusted input — API endpoints, form validation, batch processors — where try/catch becomes noise.
import { safeConvertEpoch, safeParseToEpoch, safeGetEpochNow } from '@master4n/temporal-transformer';
const result = safeConvertEpoch(req.body.timestamp);
if (result.ok) {
console.log(result.value.dateTime); // typed as EpochToDate
} else {
console.log(result.error.message); // typed as EpochValidationError
}
| Safe variant | Wraps | Returns |
|---|---|---|
safeConvertEpoch | convertEpoch | Result<EpochToDate, EpochValidationError> |
safeConvertDateToEpoch | convertDateToEpoch | Result<DateToEpoch, EpochValidationError> |
safeConvertEpochToTimezone | convertEpochToTimezone | Result<string, EpochValidationError> |
safeParseToEpoch | parseToEpoch | Result<DateToEpoch, EpochValidationError> |
safeGetDurationBetween | getDurationBetween | Result<ParsedDuration, EpochValidationError> |
safeGetTimezoneOffset | getTimezoneOffset | Result<TimezoneOffset, EpochValidationError> |
safeGetEpochNow | getEpochNow | Result<EpochNow, EpochValidationError> |
safeGetEpochUnit | getEpochUnit | Result<EpochUnit, EpochValidationError> |
Result<T> typetype Result<T, E = Error> =
| { ok: true; value: T; error?: never }
| { ok: false; value?: never; error: E };
The discriminant is ok. TypeScript narrows value and error automatically once you branch on it.
temporal-transformer treats every input as untrusted. The library has been audited against the OWASP-style threat model below; the test suite test/epoch/security.test.ts pins each defense.
| Threat | Defense |
|---|---|
Prototype pollution via __proto__ | Object inputs are rejected with NotANumber before any property access |
Infinity, -Infinity, NaN | Explicit isFinite guard, throws NotANumber |
| String DoS (e.g. 1M-char numeric string) | MAX_INPUT_STRING_LENGTH = 256 → throws InputTooLong |
| Format-string DoS (memory amplification) | MAX_FORMAT_STRING_LENGTH = 256 → throws FormatTooLong |
XSS / HTML in parseToEpoch | Character allowlist regex rejects payloads before reaching moment |
| Stderr leakage of payloads | Strict ISO 8601 mode bypasses moment's js Date() fallback path |
| Timezone injection | validTimezone checks input against the IANA name list |
| Result object tampering | All return values are Object.freeze()'d |
| Internal array mutation | getTimezoneList returns a defensive copy |
System clock corruption (Date.now()) | getEpochNow validates against ±MAX_EPOCH_MS, throws ClockOutOfRange |
| Reversed-range duration | getDurationBetween throws RangeError if from > to |
| ReDoS | All regexes are linear-time (no nested quantifiers, no backreferences) |
[bracketed] literals in a format string are emitted verbatim. If you pass user-controlled format strings and output the result to HTML, you must HTML-escape on output. The library does not interpret format strings as user-supplied content.convertDateToEpoch(date) trusts date.getTime(): a Date subclass with an overridden valueOf()/getTime() returns whatever those methods return. Validate instanceof Date and untainted construction at your trust boundary if this matters.import {
MAX_EPOCH_MS, // 8.64e15 — JS Date upper bound
MIN_EPOCH_MS, // -8.64e15 — JS Date lower bound
MAX_INPUT_STRING_LENGTH, // 256
MAX_FORMAT_STRING_LENGTH, // 256
} from '@master4n/temporal-transformer';
If you discover a security issue, please open a private advisory on github.com/Master4Novice/temporal-transformer/security rather than a public issue. See SECURITY.md for the full policy.
Real numbers, run yourself with npm run bench. See bench/RESULTS.md for the full report. Headline on Node 24 / Apple Silicon:
| Operation | Native JS | Raw Luxon | This library | Library overhead |
|---|---|---|---|---|
getEpochUnit (auto-detect) | — | — | 170M ops/s | the unique feature is essentially free |
isValidEpoch (safe predicate) | 227M ops/s | — | 167M ops/s | 1.4× — JIT-friendly |
convertEpochToTimezone | — | 183K ops/s | 168K ops/s | 1.1× — thin wrapper |
getDurationBetween (calendar) | — | 87K ops/s | 92K ops/s | actually faster than raw Luxon diff |
parseToEpoch (ISO + allowlist) | 7.76M ops/s | 603K ops/s | 219K ops/s | 35× over native (security cost) |
convertEpoch (dual-TZ + relative) | 2.08M ops/s | 527K ops/s | 25K ops/s | 82× — does dual-TZ format + relative time |
| Use case | Verdict |
|---|---|
| Backend ingest / API endpoints (10K req/s) | Imperceptible. Use freely. |
| Per-request formatting (handful of calls) | Network/DB latency dominates by 1000×. |
| Batch processing 100K+ rows/second | convertEpoch is hot — use getEpochUnit once to determine units, then loop with raw Date. |
| Frontend display | Imperceptible. |
Bottom line: This library is a validation + ergonomics layer. Its job is to be correct (auto-detect, security guards, frozen results, Result API) — not to be the fastest format-string emitter. The auto-detect itself is essentially free; the cost is the dual-output convenience and the safety checks.
| Feature | temporal-transformer | moment.js | dayjs | date-fns | luxon | Native Date |
|---|---|---|---|---|---|---|
| Auto-detect epoch unit | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
Result-style safe API ({ok, value|error}) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Frozen results (immutable by construction) | ✅ | ❌ | ✅ | ✅ | ✅ | n/a |
| Input length DoS caps | ✅ | ❌ | ❌ | ❌ | ❌ | n/a |
| Format-token allowlist (rejects typos) | ✅ | ❌ | ❌ | ❌ | ❌ | n/a |
| HTML/XSS payload rejection in parse | ✅ | ❌ | ❌ | ❌ | ❌ | n/a |
| IANA timezone support | ✅ (Intl) | ✅ (bundled) | plugin | plugin | ✅ (Intl) | partial |
| TypeScript-first | ✅ | ❌ (@types/moment) | ✅ | ✅ | ✅ | ✅ |
| Tree-shakeable | partial | ❌ | ✅ | ✅ | partial | n/a |
| Min+gzip size | ~25 KB + Luxon | ~290 KB w/tz | ~7 KB | ~13 KB (modular) | ~71 KB | 0 |
| Maintenance status | active | maintenance-only | active | active | active | spec |
| Best for | Ingesting untrusted, mixed-unit epochs | Legacy codebases | Lightweight client bundles | Functional/modular use | Heavy timezone work | Trivial / known-format use |
temporal-transformer if you process timestamps where the unit isn't known up front, or you handle untrusted input and want the safe Result API.dayjs if bundle size is paramount and you don't need timezone-aware parsing.date-fns if you want a treeshakeable, functional API and you control the input.luxon directly if you already know your epoch unit and need raw speed for timezone formatting at scale.Date directly if your input is always milliseconds, you don't care about timezones beyond UTC, and you live by toISOString().moment only if you're maintaining an existing codebase that depends on it.// API returns epoch in unknown unit — temporal-transformer handles it
const ts = apiResponse.created_at; // could be seconds or ms
const { dateTime, epochUnit } = convertEpoch(ts);
const userInput = req.body.timestamp;
if (!isValidEpoch(userInput)) {
return res.status(400).json({ error: 'Invalid timestamp' });
}
const { dateTime } = convertEpoch(Number(userInput));
const { relative } = convertEpoch(event.createdAt);
console.log(`Event created ${relative}`); // "Event created 2 days 4 hours ago"
// User enters "25/12/2024" in a UK-locale date picker
const { epochInMilliseconds } = parseToEpoch('25/12/2024', 'dd/MM/yyyy', 'Europe/London');
const duration = getDurationBetween(job.startedAt, job.finishedAt);
console.log(`Job ran for ${duration.humanReadable}`);
npm run bench) with results published in bench/RESULTS.md. Headline: getEpochUnit ~170M ops/s, getDurationBetween slightly faster than raw Luxon diff, convertEpoch 82× slower than raw Date.toISOString() (cost of dual-TZ + relative-time).Date with explicit "when to pick what" guidance.SECURITY.md, CONTRIBUTING.md, GitHub issue & PR templates.yyyy-MM-dd instead of YYYY-MM-DD, cccc instead of dddd, 'literal' instead of [literal], and so on. Run the migration codemod: npx @master4n/temporal-transformer-codemod ./src.'yyyy-MM-dd HH:mm:ss.SSS' (was 'YYYY-MM-DD HH:mm:ss.SSSSSS'). JS Date has millisecond precision; the 6-digit fractional was always zero-padded fiction.EpochError.FormatInvalid — thrown when a format string contains a token outside the allowlist. Typos like 'YYYY' (still moment syntax) now surface immediately instead of producing garbage output.DEFAULT_FORMAT, SUPPORTED_FORMAT_TOKENS (the runtime-enforced allowlist).@master4n/temporal-transformer-codemod — one-shot CLI that rewrites moment-style format strings in your codebase. Handles greedy token matching, [literal] → 'literal' escape conversion (with proper '' escaping for embedded quotes), and emits warnings for tokens with no Luxon equivalent (X, x, Q).Intl.supportedValuesOf).legacy dist-tag; install with npm i @master4n/temporal-transformer@legacy. Security backports continue on v1.x-maintenance for 12 months.See MIGRATION.md for the full upgrade guide.
test/golden/) pinning v1.x behavior for the v2.0 parity gate. No runtime behavior changes.safeXxx counterpart returning { ok, value | error } instead of throwing (8 functions, see Result-Style Safe API)getEpochUnit(epoch) — standalone helper that returns just the detected EpochUnitObject.freeze) prevent downstream tamperingMAX_INPUT_STRING_LENGTH (256) caps DoS via outsized numeric/date strings — throws InputTooLongMAX_FORMAT_STRING_LENGTH (256) caps memory-amplification via format strings — throws FormatTooLonggetEpochNow validates Date.now() against MIN_EPOCH_MS / MAX_EPOCH_MS and throws ClockOutOfRange instead of a raw RangeError on a corrupted system clockgetTimezoneList returns a defensive copy, preventing mutation of the shared internal arrayparseToEpoch now rejects non-string input early with ParseError'UTC' when moment.tz.guess() returns an empty stringResult<T, E>, MAX_EPOCH_MS, MIN_EPOCH_MS, MAX_INPUT_STRING_LENGTH, MAX_FORMAT_STRING_LENGTH, EpochThresholdEpochError.InputTooLong, EpochError.FormatTooLong, EpochError.ClockOutOfRangeparseToEpoch now validates input against an allowlist of date-safe characters before passing to moment, preventing HTML/XSS payloads from reaching moment's internal parser and appearing in stderr stack tracesparseToEpoch without an explicit format now uses strict ISO 8601 parsing (moment.ISO_8601, true) instead of moment's lenient auto-detection, eliminating the js Date() fallback that could behave inconsistently across environmentsconvertEpochToTimezone — format epoch in any IANA timezoneparseToEpoch — parse date strings to epoch with strict, timezone-aware parsinggetDurationBetween — calendar-accurate duration between two epochsgetTimezoneOffset — get UTC offset (DST-aware) for any IANA timezonegetTimezoneList — list all supported IANA timezone namesgetEpochNow — current time as seconds, milliseconds, ISO string, and timezoneformatDuration — format a duration in ms as a human-readable stringisValidEpoch / isValidTimezone — safe boolean predicates (never throw)ParsedDuration, EpochNow, TimezoneOffset, DurationUnit, StartEndUnitEpochUnit enum, EpochError enum, EpochValidationError classvalidateEpoch no longer crashes on Infinity, -Infinity, NaN, or whitespace-only strings@types/moment; moved typescript and @types/node to devDependencies; updated moment-timezone to ^0.5.46 and typescript to ^5.8.3Initial release — convertEpoch and convertDateToEpoch.
Issues and PRs are welcome at github.com/Master4Novice/temporal-transformer. The companion codemod lives at github.com/Master4Novice/temporal-transformer-codemod.
Written by Master4Novice.
MIT © Master4Novice
FAQs
TypeScript library to convert epoch timestamps (seconds, milliseconds, microseconds, nanoseconds) to human-readable dates, parse date strings to epoch, compute calendar-accurate durations, and handle IANA timezones. Powered by Luxon — small bundle, immuta
The npm package @master4n/temporal-transformer receives a total of 32 weekly downloads. As such, @master4n/temporal-transformer popularity was classified as not popular.
We found that @master4n/temporal-transformer 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
/Company News
Socket has joined the new Composer and Packagist sponsorship program as a launch sponsor, supporting the team that keeps PHP's package ecosystem secure.

Research
/Security News
Benign-looking npm packages split malicious functionality across a dependency chain that deploys a cross-platform RAT targeting Alibaba developers.

Research
/Security News
Two Joyfill npm beta releases contain an import-time implant that uses blockchain transactions to retrieve a remote-access trojan.