Skip to content

Instantly share code, notes, and snippets.

@kurumpa
Created September 2, 2021 18:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kurumpa/4f06a0327852ff3dfcd01cf7b2d0e8ee to your computer and use it in GitHub Desktop.
Save kurumpa/4f06a0327852ff3dfcd01cf7b2d0e8ee to your computer and use it in GitHub Desktop.
export function formatNumber(fmt: string, value: number) {
// special case for `#,##0.0###`
// warning! you can't use `,` as a decimal delimiter in that particular case
// also, you can use up to 8 decimal places here
if (fmt[fmt.length - 1] === "#") {
const dotPos = fmt.lastIndexOf(".")
if (dotPos > -1) {
// fractional part
// -0.345; toFixed() is used to get rid of 0.9994999999180436 that is formatted using 0.0## into 0.999 which is wrong
const fractPart = Number((number % 1).toFixed(8))
// 0.0###
const fractFmt = "0" + fmt.slice(dotPos)
// -0.3450 or 0.3460 or -1.0 or 0.0
const fractFormatted = SSF.format(fractFmt, fractPart)
// we'll use formatter's rounding and check for the fractional part overflow (0 or 1)
const absFractPartOverflow = Math.floor(Math.abs(Number(fractFormatted)))
// int part
// ##,##0 ; # is added to have the sign formatted when everything that's left from fmt is "0"
const intFmt = "#" + fmt.slice(0, dotPos)
// 123457
const absIntPart = Math.floor(Math.abs(number)) + absFractPartOverflow
// -123,457; 0.1 is to preserve the sign formatting
const intFormatted = SSF.format(intFmt, Math.sign(number) * (absIntPart + 0.1))
// altogether
const fractNoZero = /\.(.+)$/.exec(fractFormatted)
const res = intFormatted + (fractNoZero ? "." + fractNoZero[1] : "")
return res.trim()
}
}
return SSF.format(fmt, value).trim().replace(/\.$/, "")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment