Skip to content

Instantly share code, notes, and snippets.

@tonyc726
Created December 24, 2015 11:45
Show Gist options
  • Star 32 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save tonyc726/00c829a54a40cf80409f to your computer and use it in GitHub Desktop.
Save tonyc726/00c829a54a40cf80409f to your computer and use it in GitHub Desktop.
JS数字金额大写转换
var digitUppercase = function(n) {
var fraction = ['角', '分'];
var digit = [
'零', '壹', '贰', '叁', '肆',
'伍', '陆', '柒', '捌', '玖'
];
var unit = [
['元', '万', '亿'],
['', '拾', '佰', '仟']
];
var head = n < 0 ? '欠' : '';
n = Math.abs(n);
var s = '';
for (var i = 0; i < fraction.length; i++) {
s += (digit[Math.floor(n * 10 * Math.pow(10, i)) % 10] + fraction[i]).replace(/零./, '');
}
s = s || '整';
n = Math.floor(n);
for (var i = 0; i < unit[0].length && n > 0; i++) {
var p = '';
for (var j = 0; j < unit[1].length && n > 0; j++) {
p = digit[n % 10] + unit[1][j] + p;
n = Math.floor(n / 10);
}
s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s;
}
return head + s.replace(/(零.)*零元/, '元')
.replace(/(零.)+/g, '零')
.replace(/^整$/, '零元整');
};
console.log(digitUppercase(7682.01)); //柒仟陆佰捌拾贰元壹分
console.log(digitUppercase(7682)); //柒仟陆佰捌拾贰元整
console.log(digitUppercase(951434677682.00)); //玖仟伍佰壹拾肆亿叁仟肆佰陆拾柒万柒仟陆佰捌拾贰元整
@legend80s
Copy link

能否来一个单测,否则有些case很难覆盖

@Siykt
Copy link

Siykt commented Nov 10, 2023

看看我的,测试用例在这里,这是参考税务局的实现,差异主要在 1.01 -> 壹元零壹分

/**
 * 将阿拉伯数字价格转换为中文价格
 * @param price 阿拉伯数字价格
 * @returns 中文价格
 */
export function getChinesePrice(price: number) {
  if (price === 0) return '零元整'
  if (price >= 1e12) return '整数位已超过最大值'

  const CHINESE_NUMBER_MAP = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
  const CHINESE_UNIT_MAP = ['', '拾', '佰', '仟']
  const CHINESE_BIG_UNIT_MAP = ['', '万', '亿']
  const CHINESE_SMALL_UNIT_MAP = ['角', '分', '厘', '毫']

  const priceStr = price.toString()
  const priceArr = priceStr.split('.')
  const integer = priceArr[0]
  const decimal = priceArr[1]

  let chineseIntegerPrice = ''
  let zeroCount = 0

  for (let i = 0; i < integer.length; i++) {
    const num = +integer[i]
    const unit = integer.length - i - 1 // 当前数字的单位
    const quotient = Math.floor(unit / 4) // 1w为进位单位, 除 4 即为 万 亿
    const remainder = unit % 4 // 1w为进位单位, 取模 4 即为 个 十 百 千

    if (num === 0) {
      zeroCount++
    } else {
      // 处理前置的零
      if (zeroCount > 0) chineseIntegerPrice += CHINESE_NUMBER_MAP[0]
      zeroCount = 0
      chineseIntegerPrice += CHINESE_NUMBER_MAP[num] + CHINESE_UNIT_MAP[remainder]
    }
    if (remainder === 0 && zeroCount < 4) {
      chineseIntegerPrice += CHINESE_BIG_UNIT_MAP[quotient]
    }
  }

  // 价格为小数时,整数部分不显示
  if (price < 1) chineseIntegerPrice = ''
  else chineseIntegerPrice += '元'

  let chineseDecimalPrice = ''

  if (!decimal) {
    chineseDecimalPrice = '整'
  } else {
    let hasZero = false
    for (let i = 0; i < decimal.length; i++) {
      const num = +decimal[i]
      if (num) chineseDecimalPrice += CHINESE_NUMBER_MAP[num] + CHINESE_SMALL_UNIT_MAP[i]
      else hasZero = true
    }

    if (chineseIntegerPrice && hasZero) chineseIntegerPrice += '零'
  }

  return chineseIntegerPrice + chineseDecimalPrice
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment