
Research
/Security News
Compromised npm Packages in the AsyncAPI Namespace Deliver Miasma Botnet Loader
4 compromised asyncapi packages deliver miasma botnet loader on macOS, Linux and Windows.
@secvisogram/is-leap-second
Advanced tools
Provides a basic check whether an RFC 3339 timestamp is a leap second
Provides a basic check whether an RFC 3339 timestamp is a leap second.
npm install @secvisogram/is-leap-second
import { isLeapSecond } from 'is-leap-second'
isLeapSecond('2016-12-31T23:59:60Z') // true
isLeapSecond('2017-01-01T00:59:60+01:00') // true (same UTC moment)
isLeapSecond('2016-12-31T23:59:60.5Z') // true (fractional seconds accepted)
isLeapSecond('2020-06-30T23:59:60Z') // false (not a known leap second date)
isLeapSecond('2016-12-31T23:59:59Z') // false (seconds != 60)
isLeapSecond('not-a-timestamp') // false
isLeapSecond(timestamp)Returns true if timestamp is a known positive leap second, false
otherwise.
Parameters
| Name | Type | Description |
|---|---|---|
timestamp | string | An RFC 3339 timestamp with an explicit timezone offset, e.g. "2016-12-31T23:59:60Z". |
Returns boolean
Throws TypeError if timestamp is not a string.
toTime(timestamp)Converts an RFC 3339 / ISO 8601 timestamp string (with explicit timezone offset)
to a Unix nanosecond timestamp as a bigint, handling leap seconds correctly.
new Date(timestamp).getTime() * 1_000_000n."2016-12-31T23:59:60Z"), returns the
nanosecond value for the leap second (i.e., one second after
23:59:59).isLeapSecond).null for invalid or non-leap-second timestamps with seconds=60.TypeError if the input is not a string.import { toTime } from 'is-leap-second'
toTime('2016-12-31T23:59:60Z') // millisecond value for the leap second
toTime('2024-03-15T12:30:00+02:00') // same as BigInt(new Date(...).getTime()) * 1_000_000n
toTime('not-a-timestamp') // null
toTime(42) // throws TypeError
Parameters
| Name | Type | Description |
|---|---|---|
timestamp | string | An RFC 3339 timestamp with an explicit timezone offset, e.g. "2016-12-31T23:59:60Z". |
Returns bigint | null — Nanoseconds since the Unix epoch, or null if invalid.
Throws TypeError if timestamp is not a string.
roundLeapSecond(timestamp)Rounds a leap-second RFC 3339 timestamp down to the nearest valid instant accepted by the Temporal API.
Because leap seconds (:60) are not representable in the Temporal API, this
function normalises them to the last nanosecond of the preceding second:
<UTC-date>T23:59:59.999999999Z.
If the input is not a leap second (seconds field ≠ 60, or the
UTC-normalised time is not 23:59, or the date is not a known leap second),
the timestamp is returned unchanged.
import { roundLeapSecond } from 'is-leap-second'
roundLeapSecond('2016-12-31T23:59:60Z') // '2016-12-31T23:59:59.999999999Z'
roundLeapSecond('2017-01-01T00:59:60+01:00') // '2016-12-31T23:59:59.999999999Z'
roundLeapSecond('2016-12-31T23:59:60.5Z') // '2016-12-31T23:59:59.999999999Z'
roundLeapSecond('2016-12-31T23:59:59Z') // '2016-12-31T23:59:59Z' (unchanged)
roundLeapSecond('2020-06-30T23:59:60Z') // '2020-06-30T23:59:60Z' (not a known leap second, unchanged)
roundLeapSecond('not-a-timestamp') // 'not-a-timestamp' (unchanged)
Parameters
| Name | Type | Description |
|---|---|---|
timestamp | string | An RFC 3339 timestamp with an explicit timezone offset, e.g. "2016-12-31T23:59:60Z". |
Returns string — A Temporal-compatible UTC instant string, or the original timestamp if it is not a leap second.
Throws TypeError if timestamp is not a string.
A timestamp is considered a leap second when both conditions hold:
60.23:59:60 UTC) match one of the
leap seconds announced by the IERS.Timestamps without an explicit timezone (e.g. "2016-12-31T23:59:60") are
rejected — RFC 3339 requires a timezone designator.
Fractional seconds (e.g. "23:59:60.5Z") are accepted; only the integer part of
the seconds field is evaluated.
The library contains a hardcoded list of all 27 positive leap seconds up to and including 2016-12-31.
Source: IERS Bulletin C / NIST
When a new leap second is announced, run the following command to fetch the
latest data from the IANA time zone database and regenerate lib/leapSeconds.js:
npm run update-leap-seconds
Package sources (index.js, lib/) are plain JavaScript with
JSDoc type annotations. No compilation step is needed
before publishing — what you author is what gets distributed.
The key benefit of this approach is that the package can be linked directly into
other projects with npm link without releasing a new version first. This makes
it practical to test new features end-to-end in a consuming project before
committing to a release.
The test suite (index.test.ts) and maintenance scripts (scripts/update.ts)
are dev-only and never published, so they use real TypeScript syntax.
TypeScript checks the JavaScript sources via checkJs: true and emits
declaration files to dist/ with emitDeclarationOnly: true. No .js output
is produced. The prepublishOnly script in package.json runs this
automatically before every npm publish, but you can also run it manually to
verify types:
tsc -b tsconfig.src.json
JSDoc cannot express every TypeScript feature (e.g. mapped types, template
literal types). When you need them, define the types in a dedicated .ts
type-only file and import them into JSDoc annotations via @import or
@typedef {import('./types.js').MyType} MyType. This keeps the distributed
files as plain JavaScript while still supporting the full TypeScript type system.
The test suite uses the Node.js built-in test runner (node:test) together with
the built-in assertion library (node:assert/strict). No third-party test
framework is installed.
Run the tests with coverage:
npm test
This executes c8 node --test, collecting coverage in the same step without a
separate runner invocation. The familiar describe / it API is used throughout
— the style will be recognisable to developers coming from Jest or Mocha.
Because node:test is part of Node.js itself, there is no test-framework
dependency to install, update, or audit. The minimum required Node.js version is
20, where node:test became stable.
FAQs
Provides a basic check whether an RFC 3339 timestamp is a leap second
The npm package @secvisogram/is-leap-second receives a total of 12 weekly downloads. As such, @secvisogram/is-leap-second popularity was classified as not popular.
We found that @secvisogram/is-leap-second 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.

Research
/Security News
4 compromised asyncapi packages deliver miasma botnet loader on macOS, Linux and Windows.

Research
/Security News
A compromised jscrambler npm release added a malicious preinstall hook that runs hidden native binaries on Linux, macOS, and Windows.

Research
/Security News
A malicious .NET package is typosquatting the Braintree SDK to steal live payment card data, merchant API keys, and host secrets from production apps.