geekskai Logogeekskai
ToolsBlogPricing
Sign in
Sign in
ToolsBlogSign in
Sunday, September 15, 2024|2.905Mins Read

Remove Milliseconds in JavaScript: ISO Text, Dates, and Unix Seconds

Authors
  • avatar
    Name
    Geeks Kai
    Twitter
    @KaiGeeks
Discuss on Twitter • View on GitHub

Tags

javascriptdatemillisecondsprogrammingtoisostring-without-milliseconds

Next Article

How to Override CSS Style in PrimeVue: Best Practices for 2026
← Back to the blog
geekskai Logo
geekskai

Public tools for developers and creators, plus optional Geekskai Audio Toolkit plans. Built with care.

Popular Tools

SoundCloud DownloaderSoundCloud to MP3SoundCloud to WAVSoundCloud PlaylistSoundCloud Artwork
View All Tools

Resources

BlogAbout MePricingTagsProjectsPrivacy PolicyTerms of ServiceRefund Policy

Connect With Us

mailMail
githubGitHub
twitterTwitter
linkedinLinkedin
© 2026 geekskai • All rights reserved

Choose the output type first

“Remove milliseconds” can mean hiding fractional seconds in a string, creating a Date at a whole second, or converting integer Unix milliseconds to integer Unix seconds. These operations have different output types and units.

GoalResultChanges the input Date?
ISO text without a fractional partUTC string ending in ZNo
A copy at the preceding whole UTC secondDate; ISO output still has .000ZNo
Integer Unix secondsNumber in seconds, not millisecondsNo

Complete native JavaScript examples

The first two helpers accept a valid Date object. The conversion helper accepts safe integer Unix milliseconds. Supply an explicit offset or Z when constructing a Date from a date-time string; do not guess a numeric timestamp’s unit from its length.

function getValidEpochMilliseconds(date) {
  if (!(date instanceof Date)) {
    throw new TypeError("Expected a Date object.")
  }
  const epochMilliseconds = date.getTime()
  if (!Number.isFinite(epochMilliseconds)) {
    throw new RangeError("Expected a valid Date.")
  }
  return epochMilliseconds
}

function isoWithoutMilliseconds(date) {
  getValidEpochMilliseconds(date)
  return date.toISOString().slice(0, -5) + "Z"
}

function atWholeUtcSecond(date) {
  const copy = new Date(getValidEpochMilliseconds(date))
  copy.setUTCMilliseconds(0)
  return copy
}

function unixSecondsFloor(epochMilliseconds) {
  if (!Number.isSafeInteger(epochMilliseconds)) {
    throw new TypeError("Expected integer Unix milliseconds within the safe integer range.")
  }
  return Math.floor(epochMilliseconds / 1000)
}

const sourceDate = new Date("2025-01-01T12:00:00.987+02:00")
console.log(isoWithoutMilliseconds(sourceDate)) // 2025-01-01T10:00:00Z
console.log(atWholeUtcSecond(sourceDate).toISOString()) // 2025-01-01T10:00:00.000Z
console.log(sourceDate.toISOString()) // 2025-01-01T10:00:00.987Z: unchanged
console.log(unixSecondsFloor(sourceDate.getTime())) // integer seconds, not milliseconds
console.log(unixSecondsFloor(-1)) // -1: floor to the preceding whole second
console.log(atWholeUtcSecond(new Date(-1)).getTime()) // -1000: still milliseconds

Hiding fractional seconds does not change the instant

isoWithoutMilliseconds() formats in UTC because toISOString() produces UTC text. Slicing its final five characters removes the .sssZ suffix, then the example restores Z. This operation changes the returned text’s precision, not the source Date. The explicit validation rejects an invalid Date rather than pretending any input string can be formatted.

A whole-second Date still formats with .000Z

atWholeUtcSecond() makes a copy and uses setUTCMilliseconds(0). Calling a setter directly on the original Date would mutate it. setMilliseconds(0) is a local-time setter; use the UTC operation when that is the intended boundary. Either way, toISOString() still includes a milliseconds field even when its value is zero.

Negative timestamps: floor is not truncation toward zero

For the millisecond immediately before the epoch, Math.floor(-1 / 1000) is -1 second. Math.trunc(-1 / 1000) produces negative zero. The example deliberately chooses the preceding whole-second boundary. If your contract requires truncation toward zero, choose that explicitly and decide how to represent negative zero.

Multiplying the floored seconds by 1000 gives an epoch value in milliseconds again; it does not return Unix seconds. Keep unit-bearing names such as epochMilliseconds and unixSeconds at API boundaries.

What about Day.js or Moment formatting?

If a project already uses a date library, its formatting tokens can omit fractional seconds. A format containing a numeric timezone-offset token is not automatically equivalent to UTC text ending in Z; confirm the library’s mode and token rules. Native Date is sufficient for the specific examples above, without adding a dependency.

Using integer seconds in Discord

Discord timestamps use Unix seconds. Use the Discord timestamp generator for that message-format task, and see the timestamp formats guide for examples. Removing .987 from a formatted string is not a substitute for converting milliseconds to seconds.

References

  • ECMAScript: Date, Math.floor and Math.trunc
  • MDN: Date time values and UTC/local behavior