diff --git a/docs/src/guide/use/currency.md b/docs/src/guide/use/currency.md index 2c08768..19ffa3d 100644 --- a/docs/src/guide/use/currency.md +++ b/docs/src/guide/use/currency.md @@ -1,5 +1,32 @@ ---- -title: 货币 ---- # 货币 +## 概述 + +`voerkai18n`内置支持`currency`和`rmb`两个货币相关的格式化器,用来输出多语言场景下的货币显示。 + + +## 基本用法 + +当需要对货币本地化显示时,请使用相对应的格式化器,可以在`t`函数中使用来对`Number`类型进行本地化格式输出。 + +- **无参数(默认格式)** + ```javascript | pure + t("{ value | currency}",1234.56) // == ¥1234.56 + t("{ value | currency('long')}",1234.56) // == 长格式输出: RMB¥1234.56元 + t("{ value | currency('short')}",1234.56) // ==短格式输出 ¥1234.56 + await scope.change("en") + t("{ value | currency}",1234.56) // == $1,234.56 + t("{ value | currency('long')}",1234.56) // == $1,234.56 + t("{ value | currency('short')}",1234.56) // == USD $1,234.56 + + ``` +- **预定义格式** + 内置支持`default`、`long` 、`short`、`custom`等预定义 +- **无参数(默认格式)** + ```javascript | pure + ``` + +- **指定对象参数** + ```javascript | pure + ``` + diff --git a/docs/src/guide/use/datetime.md b/docs/src/guide/use/datetime.md index 9dfe5d4..bbd6b71 100644 --- a/docs/src/guide/use/datetime.md +++ b/docs/src/guide/use/datetime.md @@ -369,7 +369,61 @@ t("{ value | weekday('number') }","2022/12/9 09:12:36") } ``` +### 相对时间 - `relativeTime` +显示相对当前时间,如6分钟前、一小时后等。 +#### 用法 +```javascript | pure +t("{ value | relativeTime }","2022/12/9 09:12:36") +// 指定基准时间 +t("{ value | relativeTime('2022/12/2 09:12:36') }","2022/12/9 09:12:36") +t("{ value | relativeTime('"+"2022/12/2 09:12:36" + "') }","2022/12/9 09:12:36") +``` +#### 参数 +| 参数 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +**特别注意:** + + 当`t`函数中使用字符中拼接来生成格式化器参数时也可以生效,`t("{ value | relativeTime('"+"2022/12/2 09:12:36" + "') }","2022/12/9 09:12:36")`也可以输出基于`"2022/12/2 09:12:36"`的相对时间,但是由于`voerkai18n extract`扫描时无法识别,所以无法提取翻译的内容。因此,一般`relativeTime`格式化器只用在相对当前时间时使用。 +#### 示例 + +```javascript | pure +const NOW = new Date("2022/08/12 10:12:36") +t("{value | relativeTime }",NOW) +``` +执行以下翻译,当时间和语言不同时的输出如下: + +| 时间 | zh | en | +| --- | --- | --- | +| 2022/08/12 10:12:30 | `6秒前` | `6 seconds ago` | +| 2022/08/12 10:2:36 | `10分钟前` | `10 minutes ago` | +| 2022/08/12 8:12:36 | `2小时前` | `2 hours ago` | +| 2022/08/08 8:12:36 | `4天前` | `4 days ago` | +| 2022/07/12 10:12:36 | `1月前` | `1 months ago` | +| 2018/08/12 10:12:36 | `4年前` | `4 years ago` | +| 2022/08/12 10:12:45 | `9秒后` | `after 9 seconds` | +| 2022/08/12 10:18:36 | `6分钟后` | `after 6 minutes` | +| 2022/08/12 12:12:36 | `2小时后` | `after 2 hours` | +| 2022/08/13 10:12:36 | `1天后` | `after 1 days` | + +#### 配置 +- **配置文件**:`languages/formatters/<语言名称>.js` +- **配置位置**: `$config.datetime.relativeTime` +- **配置参数**: + ```javascript + export default { + $config:{ + datetime:{ + weekday:{ + units : ["seconds","minutes","hours","days","weeks","months","years"], + now : "Now", + before : "{value} {unit} ago", + after : "after {value} {unit}" + } + } + } + } + ``` ## 扩展配置 `voerkai18n`运行时已经内置了`zh`、`en`两种语言的日期时间相关的的格式化器。 @@ -464,7 +518,7 @@ export default { date:{ long:"" short:"" - format:"long" + format:"long" // 默认使用long格式,也可以使用一个模板字符串 } } } @@ -497,7 +551,7 @@ export default { ### 自定义模板 -日期时间格式化时可以自定义显示格式模板,模板字符串中可以使用以下占位符: +日期时间格式化时可以自定义显示格式模板,模板字符串中支持以下占位符: | 占位符 | 说明 | | --- | --- | @@ -518,4 +572,6 @@ export default { |s | 0-59 秒| |SSS | 000-999 毫秒,三位数| |A | AM / PM 上/下午,大写| -|a | am / pm 上/下午,小写| \ No newline at end of file +|a | am / pm 上/下午,小写| +|t | 时间段,如凌晨、早上、上午、中午、下午、晚上 | +|T | 时间段,如凌晨、早上、上午、中午、下午、晚上 | \ No newline at end of file diff --git a/packages/runtime/cnutils.js b/packages/runtime/cnutils.js deleted file mode 100644 index 4c99768..0000000 --- a/packages/runtime/cnutils.js +++ /dev/null @@ -1,105 +0,0 @@ -/** - * - * 处理中文数字和货币相关 - * - */ -const { isNumber } = require('./utils') - -const CN_DATETIME_UNITS = ["年","季度","月","周","日","小时","分钟","秒","毫秒","微秒"] -const CN_WEEK_DAYS = ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"] -const CN_SHORT_WEEK_DAYS =["周日","周一","周二","周三","周四","周五","周六"] -const CN_MONTH_NAMES= ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"] -const CN_SHORT_MONTH_NAMES = ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"] - - const CN_NUMBER_DIGITS = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"] - const CN_NUMBER_UNITS = ['', '十', '百', '千', '万', '十', '百', '千', '亿', '十', '百', '千', '兆', '十', '百', '千', '京', '十', '百', '千', '垓'] - const CN_NUMBER_BIG_DIGITS = ["零", '壹', '貳', '參', '肆', '伍', '陸', '柒', '捌', '玖'] - const CN_NUMBER_BIG_UNITS = ['', '拾', '佰', '仟', '萬', '拾', '佰', '仟', '億', '拾', '佰', '仟', '兆', '拾', '佰', '仟', '京', '拾', '佰', '仟', '垓'] - - /** - * - * 将数字转换为中文数字 - * - * 注意会忽略掉小数点后面的数字 - * - * @param {*} value 数字 - * @param {*} isBig 是否大写数字 - * @returns - */ -function toChineseNumber(value,isBig) { - if(!isNumber(value)) return value; - let [wholeValue,decimalValue] = String(value).split(".") // 处理小数点 - const DIGITS = isBig ? CN_NUMBER_BIG_DIGITS : CN_NUMBER_DIGITS - const UNITS = isBig ? CN_NUMBER_BIG_UNITS : CN_NUMBER_UNITS - let result = '' - if(wholeValue.length==1) return DIGITS[parseInt(wholeValue)] - for(let i=wholeValue.length-1; i>=0; i--){ - let bit = parseInt(wholeValue[i]) - let digit = DIGITS[bit] - let unit = UNITS[wholeValue.length-i-1] - if(bit==0){ - let preBit =i< wholeValue.length ? parseInt(wholeValue[i+1]) : null// 上一位 - let isKeyBits = ((wholeValue.length-i-1) % 4)==0 - if(preBit && preBit!=0 && !isKeyBits) result = "零" + result - if(isKeyBits) result = UNITS[wholeValue.length-i-1] + result - }else{ - result=`${digit}${unit}` + result - } - } - if(isBig){ - result = result.replace("垓京","垓") - .replace("京兆","京") - .replace("兆億","兆") - .replace("億萬","億") - .replace("萬仟","萬") - }else{ - result = result.replace("垓京","垓") - .replace("京兆","京") - .replace("兆亿","兆") - .replace("亿万","亿") - .replace("万千","万") - if(result.startsWith("一十")) result=result.substring(1) - } - return result // 中文数字忽略小数部分 - } - - function toChineseBigNumber(value) { - return toChineseNumber(value,true) - } - /** - * 转换为中文大写货币 - * @param {*} value - * @param {*} division 分割符号位数,3代表每3个数字添加一个,号 - * @param {*} prefix 前缀 - * @param {*} suffix 后缀 - * @param {*} precision 小数点精确到几位 - */ -function toChineseCurrency(value,{big=false,prefix="",unit="元",suffix=""}={}){ - let [wholeValue,decimalValue] = String(value).split(".") - let result - if(big){ - result = toChineseBigNumber(wholeValue)+unit - }else{ - result = toChineseNumber(wholeValue)+unit - } - if(decimalValue){ - if(decimalValue[0]) result =result+ CN_NUMBER_DIGITS[parseInt(decimalValue[0])]+"角" - if(decimalValue[1]) result =result+ CN_NUMBER_DIGITS[parseInt(decimalValue[1])]+"分" - } - return prefix+result+suffix -} - - module.exports ={ - toChineseCurrency, - toChineseNumber, - toChineseBigNumber, - CN_DATETIME_UNITS, - CN_WEEK_DAYS, - CN_SHORT_WEEK_DAYS, - CN_MONTH_NAMES, - CN_SHORT_MONTH_NAMES, - CN_NUMBER_DIGITS, - CN_NUMBER_UNITS, - CN_NUMBER_BIG_DIGITS, - CN_NUMBER_BIG_UNITS -} \ No newline at end of file diff --git a/packages/runtime/datatypes/chinese.js b/packages/runtime/datatypes/chinese.js index 4e77574..dabe1b1 100644 --- a/packages/runtime/datatypes/chinese.js +++ b/packages/runtime/datatypes/chinese.js @@ -3,30 +3,31 @@ * 处理中文数字和货币相关 * */ - const { FlexFormatter } = require('../dist/index.cjs') -const { isNumber } = require('./utils') - - const CN_DATETIME_UNITS = ["年","季度","月","周","日","小时","分钟","秒","毫秒","微秒"] - const CN_WEEK_DAYS = ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"] - const CN_SHORT_WEEK_DAYS =["周日","周一","周二","周三","周四","周五","周六"] - const CN_MONTH_NAMES= ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"] - const CN_SHORT_MONTH_NAMES = ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"] - const CN_NUMBER_DIGITS = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"] - const CN_NUMBER_UNITS = ['', '十', '百', '千', '万', '十', '百', '千', '亿', '十', '百', '千', '兆', '十', '百', '千', '京', '十', '百', '千', '垓'] - const CN_NUMBER_BIG_DIGITS = ["零", '壹', '貳', '參', '肆', '伍', '陸', '柒', '捌', '玖'] - const CN_NUMBER_BIG_UNITS = ['', '拾', '佰', '仟', '萬', '拾', '佰', '仟', '億', '拾', '佰', '仟', '兆', '拾', '佰', '仟', '京', '拾', '佰', '仟', '垓'] +const { isNumber } = require('../utils') +const { FlexFormatter,Formatter } = require('../formatter') + +const CN_DATETIME_UNITS = ["年","季度","月","周","日","小时","分钟","秒","毫秒","微秒"] +const CN_WEEK_DAYS = ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"] +const CN_SHORT_WEEK_DAYS =["周日","周一","周二","周三","周四","周五","周六"] +const CN_MONTH_NAMES= ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"] +const CN_SHORT_MONTH_NAMES = ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"] + +const CN_NUMBER_DIGITS = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"] +const CN_NUMBER_UNITS = ['', '十', '百', '千', '万', '十', '百', '千', '亿', '十', '百', '千', '兆', '十', '百', '千', '京', '十', '百', '千', '垓'] +const CN_NUMBER_BIG_DIGITS = ["零", '壹', '貳', '參', '肆', '伍', '陸', '柒', '捌', '玖'] +const CN_NUMBER_BIG_UNITS = ['', '拾', '佰', '仟', '萬', '拾', '佰', '仟', '億', '拾', '佰', '仟', '兆', '拾', '佰', '仟', '京', '拾', '佰', '仟', '垓'] - /** - * - * 将数字转换为中文数字 - * - * 注意会忽略掉小数点后面的数字 - * - * @param {*} value 数字 - * @param {*} isBig 是否大写数字 - * @returns - */ +/** + * + * 将数字转换为中文数字 + * + * 注意会忽略掉小数点后面的数字 + * + * @param {*} value 数字 + * @param {*} isBig 是否大写数字 + * @returns + */ function toChineseNumber(value,isBig) { if(!isNumber(value)) return value; let [wholeValue,decimalValue] = String(value).split(".") // 处理小数点 @@ -64,9 +65,16 @@ const { isNumber } = require('./utils') return result // 中文数字忽略小数部分 } - function toChineseBigNumber(value) { +function toChineseBigNumber(value) { return toChineseNumber(value,true) - } +} + +const chineseNumberFormatter = Formatter((value,isBig,$config)=>{ + return toChineseNumber(value,isBig,$config) + },{ + params:["isBig"] +}) + /** * 转换为中文大写货币 * @param {*} value @@ -74,9 +82,8 @@ const { isNumber } = require('./utils') * @param {*} prefix 前缀 * @param {*} suffix 后缀 * @param {*} showWhole 显示 - * @param {*} precision 小数点精确到几位 */ -function toChineseCurrency(value,{big=false,prefix="",unit="元",suffix="",precision=2,showWhole=true}={}){ +function toChineseCurrency(value,{big,prefix,unit,suffix}={},$config){ let [wholeValue,decimalValue] = String(value).split(".") let result if(big){ @@ -85,8 +92,14 @@ function toChineseCurrency(value,{big=false,prefix="",unit="元",suffix="",preci result = toChineseNumber(wholeValue)+unit } if(decimalValue){ - if(decimalValue[0]) result =result+ CN_NUMBER_DIGITS[parseInt(decimalValue[0])]+"角" - if(decimalValue[1]) result =result+ CN_NUMBER_DIGITS[parseInt(decimalValue[1])]+"分" + if(decimalValue[0]) { + let bit0 = parseInt(decimalValue[0]) + result =result+ (big ? CN_NUMBER_BIG_DIGITS[bit0] : CN_NUMBER_DIGITS[bit0])+"角" + } + if(decimalValue[1]){ + let bit1 = parseInt(decimalValue[1]) + result =result+ (big ? CN_NUMBER_BIG_DIGITS[bit1] : CN_NUMBER_DIGITS[bit1])+"分" + } } return prefix+result+suffix } @@ -94,7 +107,7 @@ function toChineseCurrency(value,{big=false,prefix="",unit="元",suffix="",preci const rmbFormater = FlexFormatter((value,params,$config)=>{ return toChineseCurrency(value,params,$config) },{ - params:["big","prefix","unit","suffix","precision","showWhole"], + params:["big","prefix","unit","suffix"], configKey:"rmb" }) @@ -103,6 +116,7 @@ module.exports ={ toChineseNumber, toChineseBigNumber, rmbFormater, + chineseNumberFormatter, CN_DATETIME_UNITS, CN_WEEK_DAYS, CN_SHORT_WEEK_DAYS, diff --git a/packages/runtime/datatypes/datetime.js b/packages/runtime/datatypes/datetime.js index aad855b..a435e79 100644 --- a/packages/runtime/datatypes/datetime.js +++ b/packages/runtime/datatypes/datetime.js @@ -212,12 +212,42 @@ const weekdayFormatter = createDateTimeFormatter({ } },formatTime) +/** + * 返回相对于rel的时间 + * @param {*} value + * @param {*} baseTime 基准时间,默认是相对现在 + */ +// 对应:秒,分钟,小时,天,周,月,年的毫秒数,月取30天,年取365天概数 +const TIME_SECTIONS = [1000,60000,3600000,86400000,604800000,2592000000,31536000000,Number.MAX_SAFE_INTEGER] +const relativeTimeFormatter = Formatter((value,baseTime,$config)=>{ + const { units,now,before,base = Date.now() , after } = $config + let ms = value.getTime() + let msBase = (baseTime instanceof Date) ? baseTime.getTime() : toDate(base).getTime() + let msDiff = ms - msBase + let msIndex = TIME_SECTIONS.findIndex(x=>Math.abs(msDiff) < x) - 1 + if(msIndex < 0) msIndex = 0 + if(msIndex > TIME_SECTIONS.length-1 ) msIndex = TIME_SECTIONS.length-1 + if(msDiff==0){ + return now + }else if(msDiff<0){// 之前 + let result = parseInt(Math.abs(msDiff) / TIME_SECTIONS[msIndex]) + return before.replace("{value}",result).replace("{unit}",units[msIndex]) + }else{// 之后 + let result = parseInt(Math.abs(msDiff) / TIME_SECTIONS[msIndex]) + return after.replace("{value}",result).replace("{unit}",units[msIndex]) + } +},{ + normalize:toDate, + params:["base"], + configKey:"datetime.relativeTime" +}) module.exports = { toDate, formatTime, formatDatetime, createDateTimeFormatter, + relativeTimeFormatter, dateFormatter, quarterFormatter, monthFormatter, diff --git a/packages/runtime/formatter.js b/packages/runtime/formatter.js index d925131..cc95de7 100644 --- a/packages/runtime/formatter.js +++ b/packages/runtime/formatter.js @@ -323,12 +323,12 @@ const Formatter = createFormatter * @param {*} defaultParams */ const createFlexFormatter = function(fn,options={},defaultParams={}){ - const $formatter = Formatter(function(value,...args){ + const $flexFormatter = Formatter(function(value,...args){ // 1. 最后一个参数是格式化器的参数,不同语言不一样 let $config = args[args.length-1] // 2. 从语言配置中读取默认参数 let finalParams = options.params.reduce((r,name) =>{ - r[name] = $config[name] || defaultParams[name] + r[name] = $config[name]==undefined ? defaultParams[name] : $config[name] return r } ,{}) // 3. 从格式化器中传入的参数具有最高优先级,覆盖默认参数 @@ -345,7 +345,7 @@ const createFlexFormatter = function(fn,options={},defaultParams={}){ return fn.call(this,value,finalParams,$config) },{...options,params:null}) // 变参工式化器需要指定params=null - return $formatter + return $flexFormatter } diff --git a/packages/runtime/formatters/en.js b/packages/runtime/formatters/en.js index b988d99..a865c64 100644 --- a/packages/runtime/formatters/en.js +++ b/packages/runtime/formatters/en.js @@ -5,7 +5,7 @@ const { isFunction,isPlainObject} = require("../utils") const { Formatter } = require("../formatter") -const { dateFormatter,quarterFormatter,monthFormatter,weekdayFormatter,timeFormatter } = require("../datatypes/datetime") +const { dateFormatter,quarterFormatter,monthFormatter,weekdayFormatter,timeFormatter,relativeTimeFormatter } = require("../datatypes/datetime") const { numberFormartter } = require("../datatypes/numeric") const { currencyFormatter } = require("../datatypes/currency") @@ -102,8 +102,14 @@ module.exports = { }, timeSlots : { slots : [12], - lowerCases : ["am","pm"], - upperCases : ["AM","PM"] + lowerCases : ["am","pm"], + upperCases : ["AM","PM"] + }, + relativeTime : { + units : ["seconds","minutes","hours","days","weeks","months","years"], + now : "Now", + before : "{value} {unit} ago", + after : "after {value} {unit}" } }, currency : { @@ -159,6 +165,7 @@ module.exports = { weekday : weekdayFormatter, // ******************* 时间 ******************* time : timeFormatter, + relativeTime : relativeTimeFormatter, // ******************* 货币 ******************* currency : currencyFormatter, // ******************* 数字 ******************* diff --git a/packages/runtime/formatters/zh.js b/packages/runtime/formatters/zh.js index c5a7c3b..41cd108 100644 --- a/packages/runtime/formatters/zh.js +++ b/packages/runtime/formatters/zh.js @@ -3,7 +3,10 @@ * */ -const { toChineseCurrency,toChineseNumber,CN_DATETIME_UNITS,CN_WEEK_DAYS,CN_SHORT_WEEK_DAYS, CN_MONTH_NAMES, CN_SHORT_MONTH_NAMES} = require("../cnutils") +const { + CN_DATETIME_UNITS,CN_WEEK_DAYS,CN_SHORT_WEEK_DAYS, CN_MONTH_NAMES, CN_SHORT_MONTH_NAMES, + chineseNumberFormatter,rmbFormater +} = require("../datatypes/chinese") module.exports = { // 配置参数: 格式化器函数的最后一个参数就是该配置参数 @@ -39,6 +42,12 @@ module.exports = { slots : [6,9,11,13,18], lowerCases : ["凌晨","早上","上午","中午","下午","晚上"], upperCases : ["凌晨","早上","上午","中午","下午","晚上"] + }, + relativeTime : { + units : ["秒","分钟","小时","天","周","月","年"], + now : "现在", + before : "{value}{unit}前", + after : "{value}{unit}后" } }, currency : { @@ -53,13 +62,19 @@ module.exports = { number : { division : 4, precision : 0 - } + }, + rmb :{ + big : false, + prefix : "", + unit : "元", + suffix : "" + } }, $types: { Boolean : value =>value ? "是":"否" }, // 中文货币,big=true代表大写形式 - rmb : (value,big,unit="元",prefix,suffix)=>toChineseCurrency(value,{big,prefix,suffix,unit}), - // // 中文数字,如一千二百三十一 - chineseNumber :(value,isBig)=>toChineseNumber(value,isBig) + rmb : rmbFormater, + // // 中文数字,如一千二百三十一,或大写数字 + chineseNumber : chineseNumberFormatter } \ No newline at end of file diff --git a/test/runtime.test.js b/test/runtime.test.js index dae57e7..27b5df1 100644 --- a/test/runtime.test.js +++ b/test/runtime.test.js @@ -490,10 +490,40 @@ describe("翻译函数",()=>{ expect(enTranslatedResults).toStrictEqual(expectEnDatetimes) }) + test("相对时间格式化",async ()=>{ + //const NOW = new Date("2022/08/12 10:12:36") + let times = [ + // Before + "2022/08/12 10:12:30", + "2022/08/12 10:2:36", + "2022/08/12 8:12:36", + "2022/08/08 8:12:36", + "2022/07/12 10:12:36", + "2018/08/12 10:12:36", + // After + "2022/08/12 10:12:45", + "2022/08/12 10:18:36", + "2022/08/12 12:12:36", + "2022/08/13 10:12:36", + ] + let expectCNTimes = [ + "6秒前","10分钟前","2小时前","4天前","1月前","4年前", + "9秒后","6分钟后","2小时后","1天后" + ] + let expectENTimes = [ + "6 seconds ago","10 minutes ago","2 hours ago","4 days ago","1 months ago","4 years ago", + "after 9 seconds","after 6 minutes","after 2 hours","after 1 days" + ] + scope.activeFormatterConfig.datetime.relativeTime.base = NOW + let relTimes = times.map(v=>t("{value | relativeTime }",v)) + expect(relTimes).toStrictEqual(expectCNTimes) + await scope.change("en") + scope.activeFormatterConfig.datetime.relativeTime.base = NOW + let relEnTimes = times.map(v=>t("{value | relativeTime }",v)) + expect(relEnTimes).toStrictEqual(expectENTimes) + }) test("货币格式化",async ()=>{ - const v= t("商品价格: { value | currency({symbol:'¥¥',prefix:'人民币:'})}",MONEY) // 长格式: 万元 - let zhMoneysResults = zhMoneys.map(v=>t(v,MONEY)) const p = diffArray(zhMoneysResults,expectZhMoneys) expect(zhMoneysResults).toStrictEqual(expectZhMoneys) @@ -521,5 +551,102 @@ describe("翻译函数",()=>{ expect(t("{value | number(3,2) }",123456789.8888)).toBe("1,23,45,67,89.889+") }) + test("中文数字格式化",(done)=>{ + let cnNumbers = [ + 1, + 12, + 123, + 1234, + 12345, + 123456, + 1234567, + 12345678, + 123456789, + ] + let expectCNumbers = [ + "一", + "十二", + "一百二十三", + "一千二百三十四", + "一万二千三百四十五", + "十二万三千四百五十六", + "一百二十三万四千五百六十七", + "一千二百三十四万五千六百七十八", + "一亿二千三百四十五万六千七百八十九" + ] + let expectCNBigumbers=[ + "壹", + "壹拾貳", + "壹佰貳拾參", + "壹仟貳佰參拾肆", + "壹萬貳仟參佰肆拾伍", + "壹拾貳萬參仟肆佰伍拾陸", + "壹佰貳拾參萬肆仟伍佰陸拾柒", + "壹仟貳佰參拾肆萬伍仟陸佰柒拾捌", + "壹億貳仟參佰肆拾伍萬陸仟柒佰捌拾玖" + ] + let cnTanslated = cnNumbers.map(n=>t("{value |chineseNumber}",n)) + expect(cnTanslated).toStrictEqual(expectCNumbers) + let cnBigTanslated = cnNumbers.map(n=>t("{value |chineseNumber(true)}",n)) + expect(cnBigTanslated).toStrictEqual(expectCNBigumbers) + done() + }) + + test("中文货币格式化",(done)=>{ + let cnNumbers = [ + 1.88, + 12.88, + 123.88, + 1234.88, + 12345.88, + 123456.88, + 1234567.88, + 12345678.88, + 123456789.88, + ] + let expectCNumbers = [ + "一元八角八分", + "十二元八角八分", + "一百二十三元八角八分", + "一千二百三十四元八角八分", + "一万二千三百四十五元八角八分", + "十二万三千四百五十六元八角八分", + "一百二十三万四千五百六十七元八角八分", + "一千二百三十四万五千六百七十八元八角八分", + "一亿二千三百四十五万六千七百八十九元八角八分", + ] + let expectCNBigumbers=[ + "壹元捌角捌分", + "壹拾貳元捌角捌分", + "壹佰貳拾參元捌角捌分", + "壹仟貳佰參拾肆元捌角捌分", + "壹萬貳仟參佰肆拾伍元捌角捌分", + "壹拾貳萬參仟肆佰伍拾陸元捌角捌分", + "壹佰貳拾參萬肆仟伍佰陸拾柒元捌角捌分", + "壹仟貳佰參拾肆萬伍仟陸佰柒拾捌元捌角捌分", + "壹億貳仟參佰肆拾伍萬陸仟柒佰捌拾玖元捌角捌分", + ] + let expectCNBigumbers2=[ + "人民币:壹元捌角捌分整", + "人民币:壹拾貳元捌角捌分整", + "人民币:壹佰貳拾參元捌角捌分整", + "人民币:壹仟貳佰參拾肆元捌角捌分整", + "人民币:壹萬貳仟參佰肆拾伍元捌角捌分整", + "人民币:壹拾貳萬參仟肆佰伍拾陸元捌角捌分整", + "人民币:壹佰貳拾參萬肆仟伍佰陸拾柒元捌角捌分整", + "人民币:壹仟貳佰參拾肆萬伍仟陸佰柒拾捌元捌角捌分整", + "人民币:壹億貳仟參佰肆拾伍萬陸仟柒佰捌拾玖元捌角捌分整", + ] + + let cnTanslated = cnNumbers.map(n=>t("{value |rmb }",n)) + expect(cnTanslated).toStrictEqual(expectCNumbers) + let cnBigTanslated = cnNumbers.map(n=>t("{value |rmb(true)}",n)) + expect(cnBigTanslated).toStrictEqual(expectCNBigumbers) + + let cnBigTanslated2 = cnNumbers.map(n=>t("{value |rmb({big:true,prefix:'人民币:', unit:'元',suffix:'整'})}",n)) + expect(cnBigTanslated2).toStrictEqual(expectCNBigumbers2) + done() + }) + })