update formatters
This commit is contained in:
parent
3c31d3fb67
commit
b8f59c43bc
@ -7,7 +7,7 @@ export default defineConfig({
|
|||||||
base:"/voerka-i18n/",
|
base:"/voerka-i18n/",
|
||||||
publicPath:"/voerka-i18n/",
|
publicPath:"/voerka-i18n/",
|
||||||
mode: 'site',
|
mode: 'site',
|
||||||
logo: "/images/i18n.png",
|
logo: "/voerka-i18n/images/i18n.png",
|
||||||
outputPath:"docs/dist",
|
outputPath:"docs/dist",
|
||||||
resolve:{
|
resolve:{
|
||||||
includes:["docs/src"]
|
includes:["docs/src"]
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
/**
|
import { toNumber,isFunction } from "../utils"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
* 字典格式化器
|
* 字典格式化器
|
||||||
* 根据输入data的值,返回后续参数匹配的结果
|
* 根据输入data的值,返回后续参数匹配的结果
|
||||||
* dict(data,<value1>,<result1>,<value2>,<result1>,<value3>,<result1>,...)
|
* dict(data,<value1>,<result1>,<value2>,<result1>,<value3>,<result1>,...)
|
||||||
@ -34,7 +37,156 @@
|
|||||||
if (args.length > 0 && (args.length % 2 !== 0)) return args[args.length - 1]
|
if (args.length > 0 && (args.length % 2 !== 0)) return args[args.length - 1]
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 空值: null,undefined
|
||||||
|
*
|
||||||
|
* 当输入空值时的行为
|
||||||
|
*
|
||||||
|
* { value | empty } == 转换显示为''
|
||||||
|
* { value | empty('无') } == 无
|
||||||
|
* { value | unit('KB') | empty('0') } == 0KB
|
||||||
|
*
|
||||||
|
* 有时在处理其他类型时,可能希望将0或者''也视为空值
|
||||||
|
* { value | empty('没钱了') } ==
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param {*} value
|
||||||
|
* @param {String} escapeValue
|
||||||
|
* @param {*} options
|
||||||
|
*/
|
||||||
|
function empty(value,escapeValue,next) {
|
||||||
|
if(next===true) next = 'break'
|
||||||
|
let opts = Object.assign({escape:"",next:'ignore'},options.empty || {})
|
||||||
|
if(!escapeValue) opts.escape = escapeValue
|
||||||
|
let emptyValues = [undefined,null]
|
||||||
|
if(Array.isArray(opts.values)) emptyValues.push(...opts.values)
|
||||||
|
if(emptyValues.includes(value)){
|
||||||
|
return {value:opts.escape,next: opts.next}
|
||||||
|
}else{
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
empty.paramCount = 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当执行格式化器出错时的显示内容.
|
||||||
|
|
||||||
|
{ value | error } ==
|
||||||
|
{ value | error('') } == 显示空字符串
|
||||||
|
{ value | error('ERROR') } == 显示ERROR字样
|
||||||
|
{ value | error('ERROR:{ message}') } == 显示error.message
|
||||||
|
{ value | error('ERROR:{ error}') } == 显示error.constructor.name
|
||||||
|
|
||||||
|
this--> scope实例
|
||||||
|
|
||||||
|
* @param {*} value
|
||||||
|
* @param {*} escapeValue
|
||||||
|
* @param {*} next 下一步的行为,取值,break,ignore
|
||||||
|
* @param {*} options 格式化器的全局配置参数
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function error(value,escapeValue,next,options) {
|
||||||
|
|
||||||
|
if(value instanceof Error){
|
||||||
|
try{
|
||||||
|
let opts = Object.assign({escape:"",next:'break'},options.error || {})
|
||||||
|
if(!escapeValue) opts.escape = escapeValue
|
||||||
|
if(!next) opts.next = next
|
||||||
|
return {
|
||||||
|
value : String(opts.escape).replace(/\{\s*message\s*\}/g,value.message)
|
||||||
|
.replace(/\{\s*error\s*\}/g,value.constructor.name)
|
||||||
|
next : opts.next
|
||||||
|
}
|
||||||
|
}cache(e){
|
||||||
|
if(this.debug) console.error(`Error while execute formatter: ${e.message}`)
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
error.paramCount = 2 // 声明该格式化器支持两个参数
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加前缀
|
||||||
|
* @param {*} value
|
||||||
|
* @param {*} prefix
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function prefix(value,prefix="") {
|
||||||
|
return prefix ? `${prefix}${value}` : value
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 添加后缀
|
||||||
|
* @param {*} value
|
||||||
|
* @param {*} suffix
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function suffix(value,suffix="") {
|
||||||
|
return suffix ? `${value}${suffix}` : value
|
||||||
|
}
|
||||||
|
|
||||||
|
const FILE_SIZE_SECTIONS = [
|
||||||
|
0,
|
||||||
|
1024,
|
||||||
|
1048576,
|
||||||
|
1073741824,
|
||||||
|
1099511627776,
|
||||||
|
1125899906842624,
|
||||||
|
1152921504606847000,
|
||||||
|
1.1805916207174113e+21,
|
||||||
|
1.2089258196146292e+24,
|
||||||
|
1.2379400392853803e+27,
|
||||||
|
1.2676506002282294e+30
|
||||||
|
]
|
||||||
|
const FILE_SIZE_BRIEF_UNITS = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB","NB","DB"]
|
||||||
|
const FILE_SIZE_WHOLE_UNITS = ["Bytes", "Kilobytes", "Megabytes", "Gigabytes", "TeraBytes", "PetaBytes", "ExaBytes", "ZetaBytes", "YottaBytes","DoggaBytes"]
|
||||||
|
//const getSizePoint= index=>index ==0 ? 0 : new Array(index).fill(0).reduce((pv,cv)=>pv*1024,1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出文件大小
|
||||||
|
*
|
||||||
|
* { value | fileSize }
|
||||||
|
* { value | fileSize('KB') }
|
||||||
|
* { value | fileSize('MB') }
|
||||||
|
*
|
||||||
|
* @param {*} value
|
||||||
|
* @param {*} unit 单位,未指定时采用自动方式,即<1024用字节,1024<v<1024*1024显示KB,...
|
||||||
|
* @param {*} brief
|
||||||
|
* @param {*} options
|
||||||
|
*/
|
||||||
|
function fileSize(value,unit,brief=true,options={}){
|
||||||
|
let opts = Object.assign({
|
||||||
|
precision: 2,
|
||||||
|
brief : FILE_SIZE_BRIEF_UNITS,
|
||||||
|
whole : FILE_SIZE_WHOLE_UNITS
|
||||||
|
},options.fileSize || {})
|
||||||
|
let v = toNumber(value)
|
||||||
|
let unitIndex
|
||||||
|
if(unit==undefined || unit=="auto"){
|
||||||
|
unitIndex = FILE_SIZE_SECTIONS.findIndex(x=>v<x) - 1
|
||||||
|
}else{
|
||||||
|
unit = unit.toUpperCase()
|
||||||
|
unitIndex =["B","BYTE","BYTES"].includes(unit) ? 0 : FILE_SIZE_BRIEF_UNITS.indexOf(unit)
|
||||||
|
}
|
||||||
|
if(unitIndex<0 || unitIndex>=FILE_SIZE_BRIEF_UNITS.length) unitIndex= 0
|
||||||
|
let result = (unitIndex == 0 ? v : v / FILE_SIZE_SECTIONS[unitIndex]).toFixed(opts.precision)
|
||||||
|
if( unitIndex>0 && (v % FILE_SIZE_SECTIONS[unitIndex])!==0) result = result+"+"
|
||||||
|
// 去除尾部的0
|
||||||
|
while(["0","."].includes(result[result.length-1])){
|
||||||
|
result = result.substring(0, result.length-2)
|
||||||
|
}
|
||||||
|
return brief ? `${result} ${opts.brief[unitIndex]}` : `${result} ${opts.brief[whole]}`
|
||||||
|
}
|
||||||
|
fileSize.paramCount = 2
|
||||||
|
fileSize.escape = 0
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
dict
|
dict,
|
||||||
|
prefix,
|
||||||
|
suffix,
|
||||||
|
filesize,
|
||||||
|
error,
|
||||||
|
empty
|
||||||
}
|
}
|
@ -5,6 +5,9 @@
|
|||||||
|
|
||||||
const { toDate,toCurrency } = require("../utils")
|
const { toDate,toCurrency } = require("../utils")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
// 配置参数: 格式化器函数的最后一个参数就是该配置参数
|
// 配置参数: 格式化器函数的最后一个参数就是该配置参数
|
||||||
$options:{
|
$options:{
|
||||||
@ -25,6 +28,21 @@
|
|||||||
number : {
|
number : {
|
||||||
division : 3,
|
division : 3,
|
||||||
precision : 2
|
precision : 2
|
||||||
|
},
|
||||||
|
empty:{
|
||||||
|
//values : [], // 可选,定义空值,如果想让0,''也为空值,可以指定values=[0,'']
|
||||||
|
escape : "", // 当空值时显示的备用值
|
||||||
|
next : null // 当空值时下一步的行为: break=中止;ignore=忽略
|
||||||
|
},
|
||||||
|
error : {
|
||||||
|
//当错误时显示的内容,支持的插值变量有message=错误信息,error=错误类名,也可以是一个返回上面内容的同步函数
|
||||||
|
escape : "", // 默认当错误时显示空内容
|
||||||
|
next : null // 当出错时下一步的行为: break=中止;ignore=忽略
|
||||||
|
},
|
||||||
|
fileSize:{
|
||||||
|
//brief: ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB","NB","DB"],
|
||||||
|
//whole:["Bytes", "Kilobytes", "Megabytes", "Gigabytes", "TeraBytes", "PetaBytes", "ExaBytes", "ZetaBytes", "YottaBytes","DoggaBytes"],
|
||||||
|
//precision: 2 // 小数精度
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 默认数据类型的格式化器
|
// 默认数据类型的格式化器
|
||||||
|
@ -288,28 +288,51 @@ function getFormatter(scope,activeLanguage,name){
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行格式化器并返回结果
|
* 执行格式化器并返回结果
|
||||||
|
*
|
||||||
|
* 格式化器this指向当前scope,并且最后一个参数是当前scope格式化器的$options
|
||||||
|
*
|
||||||
|
* 这样格式化器可以读取$options
|
||||||
|
*
|
||||||
* @param {*} value
|
* @param {*} value
|
||||||
* @param {*} formatters 多个格式化器顺序执行,前一个输出作为下一个格式化器的输入
|
* @param {Array[Function]} formatters 多个格式化器函数(经过包装过的)顺序执行,前一个输出作为下一个格式化器的输入
|
||||||
*/
|
*/
|
||||||
function executeFormatter(value,formatters,scope){
|
function executeFormatter(value,formatters,scope){
|
||||||
if(formatters.length===0) return value
|
if(formatters.length===0) return value
|
||||||
let result = value
|
let result = value
|
||||||
try{
|
|
||||||
for(let formatter of formatters){
|
const emptyChecker = formatters.find(func=>func.$name==='empty')
|
||||||
if(isFunction(formatter)) {
|
const errorChecker = formatters.find(func=>func.$name==='error')
|
||||||
result = formatter.call(scope,result)
|
|
||||||
}else{// 如果碰到无效的格式化器,则跳过过续的格式化器
|
// 当输入是一个空值时
|
||||||
return result
|
if(emptyChecker){
|
||||||
|
const { value,next } = emptyChecker(result)
|
||||||
|
if(next == 'break') return value
|
||||||
|
}
|
||||||
|
if(result instanceof Error && errorChecker){
|
||||||
|
const { value,next } = errorChecker(result)
|
||||||
|
if(next == 'break') return value
|
||||||
|
}
|
||||||
|
|
||||||
|
for(let formatter of formatters){
|
||||||
|
try{
|
||||||
|
result = formatter(result)
|
||||||
|
}catch(e){
|
||||||
|
if(scope.debug) console.error(`Error while execute i18n formatter<${formatter.$name}> for ${value}: ${e.message} ` )
|
||||||
|
const { value,next } = errorChecker(e)
|
||||||
|
if(next=="break"){
|
||||||
|
if(value!==undefined) result = value
|
||||||
|
break
|
||||||
|
}else if(next=="ignore"){
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
}
|
if(value!==undefined) result = value
|
||||||
}catch(e){
|
}
|
||||||
//console.error(`Error while execute i18n formatter for ${value}: ${e.message} ` )
|
}
|
||||||
}
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 将 [[格式化器名称,[参数,参数,...]],[格式化器名称,[参数,参数,...]]]格式化器转化为
|
* 将[[格式化器名称,[参数,参数,...]],[格式化器名称,[参数,参数,...]]]格式化器包装转化为
|
||||||
* 格式化器的调用函数链
|
* 格式化器的调用函数链
|
||||||
*
|
*
|
||||||
* @param {*} scope
|
* @param {*} scope
|
||||||
@ -318,29 +341,41 @@ function executeFormatter(value,formatters,scope){
|
|||||||
* @returns {Array} [(v)=>{...},(v)=>{...},(v)=>{...}]
|
* @returns {Array} [(v)=>{...},(v)=>{...},(v)=>{...}]
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function buildFormatters(scope,activeLanguage,formatters){
|
function wrapperFormatters(scope,activeLanguage,formatters){
|
||||||
let results = []
|
let wrappedFormatters = []
|
||||||
for(let formatter of formatters){
|
for(let [name,args] of formatters){
|
||||||
if(formatter[0]){
|
if(name){
|
||||||
const func = getFormatter(scope,activeLanguage,formatter[0])
|
const func = getFormatter(scope,activeLanguage,name)
|
||||||
if(isFunction(func)){
|
if(isFunction(func)){
|
||||||
results.push((v)=>{
|
let fn = (value) => {
|
||||||
return func(v,...formatter[1])
|
// 每一个格式式化器均支持若干输入参数,但是在使用时,可以支持可选参数
|
||||||
})
|
// 比currency(value,prefix,suffix, division,precision)支持4个参数,但是在使用时支持可选参数
|
||||||
|
// {value | currency} 或 {value | currency('元')} 或 {value | currency('元',"整")}
|
||||||
|
// 为了让格式化器能比较方便地处理最后一个配置参数,当格式化器函数指定了paramCount参数来声明其支持的参数后
|
||||||
|
// 在此就自动初始参数个数,这样在currency函数中,就可以使用这样的currency(value,prefix,suffix, division,precision,options)
|
||||||
|
// 不管开发者使用时的输入参数数是多少均可以保证在currency函数中总是可以得到有效的options参数
|
||||||
|
if(func.paramCount && args.length < func.paramCount ){
|
||||||
|
args.push(...new Array(parseInt(func.paramCount)-args.length).fill(undefined))
|
||||||
|
}
|
||||||
|
return func.call(scope,value,...args,scope.activeFormatterOptions)
|
||||||
|
}
|
||||||
|
fn.$name = name
|
||||||
|
wrappedFormatters.push(fn)
|
||||||
}else{
|
}else{
|
||||||
// 格式化器无效或者没有定义时,查看当前值是否具有同名的原型方法,如果有则执行调用
|
// 格式化器无效或者没有定义时,查看当前值是否具有同名的原型方法,如果有则执行调用
|
||||||
// 比如padStart格式化器是String的原型方法,不需要配置就可以直接作为格式化器调用
|
// 比如padStart格式化器是String的原型方法,不需要配置就可以直接作为格式化器调用
|
||||||
results.push((v)=>{
|
wrappedFormatters.push((value)=>{
|
||||||
if(isFunction(v[formatter[0]])){
|
if(isFunction(value[name])){
|
||||||
return v[formatter[0]].call(v,...formatter[1])
|
// 最后一个参数是当前作用域的格式化器配置参数
|
||||||
|
return value[name](value,...args)
|
||||||
}else{
|
}else{
|
||||||
return v
|
return value
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return results
|
return wrappedFormatters
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -353,14 +388,15 @@ function buildFormatters(scope,activeLanguage,formatters){
|
|||||||
*/
|
*/
|
||||||
function getFormattedValue(scope,activeLanguage,formatters,value){
|
function getFormattedValue(scope,activeLanguage,formatters,value){
|
||||||
// 1. 取得格式化器函数列表
|
// 1. 取得格式化器函数列表
|
||||||
const formatterFuncs = buildFormatters(scope,activeLanguage,formatters)
|
const formatterFuncs = wrapperFormatters(scope,activeLanguage,formatters)
|
||||||
// 2. 查找每种数据类型默认格式化器,并添加到formatters最前面,默认数据类型格式化器优先级最高
|
|
||||||
const defaultFormatter = getDataTypeDefaultFormatter(scope,activeLanguage,getDataTypeName(value))
|
|
||||||
// 默认数据类型的格式化器仅在没有指定其他格式化器时生效
|
|
||||||
if(defaultFormatter && formatterFuncs.length==0){
|
|
||||||
formatterFuncs.splice(0,0,defaultFormatter)
|
|
||||||
}
|
|
||||||
// 3. 执行格式化器
|
// 3. 执行格式化器
|
||||||
|
if(formatterFuncs.length==0){
|
||||||
|
// 当没有格式化器时,查询是否指定了默认数据类型的格式化器,如果有则执行
|
||||||
|
const defaultFormatter = getDataTypeDefaultFormatter(scope,activeLanguage,getDataTypeName(value))
|
||||||
|
if(defaultFormatter){
|
||||||
|
return executeFormatter(value,[defaultFormatter],scope)
|
||||||
|
}
|
||||||
|
}
|
||||||
value = executeFormatter(value,formatterFuncs,scope)
|
value = executeFormatter(value,formatterFuncs,scope)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
@ -57,49 +57,29 @@ module.exports = class i18nScope {
|
|||||||
this.register(callback);
|
this.register(callback);
|
||||||
}
|
}
|
||||||
// 作用域
|
// 作用域
|
||||||
get id() {
|
get id() {return this._id;}
|
||||||
return this._id;
|
|
||||||
}
|
|
||||||
// 调试开关
|
// 调试开关
|
||||||
get debug() {
|
get debug() {return this._debug;}
|
||||||
return this._debug;
|
|
||||||
}
|
|
||||||
// 默认语言名称
|
// 默认语言名称
|
||||||
get defaultLanguage() {
|
get defaultLanguage() {return this._defaultLanguage;}
|
||||||
return this._defaultLanguage;
|
|
||||||
}
|
|
||||||
// 默认语言名称
|
// 默认语言名称
|
||||||
get activeLanguage() {
|
get activeLanguage() {return this._activeLanguage;}
|
||||||
return this._activeLanguage;
|
|
||||||
}
|
|
||||||
// 默认语言包
|
// 默认语言包
|
||||||
get default() {
|
get default() {return this._default;}
|
||||||
return this._default;
|
|
||||||
}
|
|
||||||
// 当前语言包
|
// 当前语言包
|
||||||
get messages() {
|
get messages() {return this._messages; }
|
||||||
return this._messages;
|
|
||||||
}
|
|
||||||
// 消息id映射列表
|
// 消息id映射列表
|
||||||
get idMap() {
|
get idMap() {return this._idMap;}
|
||||||
return this._idMap;
|
|
||||||
}
|
|
||||||
// 当前作用域的格式化器 {<lang>:{$types,$options,[格式化器名称]:()=>{},[格式化器名称]:()=>{}}}
|
// 当前作用域的格式化器 {<lang>:{$types,$options,[格式化器名称]:()=>{},[格式化器名称]:()=>{}}}
|
||||||
get formatters() {
|
get formatters() { return this._formatters;}
|
||||||
return this._formatters;
|
|
||||||
}
|
|
||||||
// 当前作用域支持的语言列表[{name,title,fallback}]
|
// 当前作用域支持的语言列表[{name,title,fallback}]
|
||||||
get languages() {
|
get languages() {return this._languages;}
|
||||||
return this._languages;
|
|
||||||
}
|
|
||||||
// 异步加载语言文件的函数列表
|
// 异步加载语言文件的函数列表
|
||||||
get loaders() {
|
get loaders() { return this._loaders;}
|
||||||
return this._loaders;
|
|
||||||
}
|
|
||||||
// 引用全局VoerkaI18n配置,注册后自动引用
|
// 引用全局VoerkaI18n配置,注册后自动引用
|
||||||
get global() {
|
get global() { return this._global;}
|
||||||
return this._global;
|
// 当前格式化器配置参数
|
||||||
}
|
get activeFormatterOptions(){return this._activeFormatterOptions}
|
||||||
/**
|
/**
|
||||||
* 在全局注册作用域
|
* 在全局注册作用域
|
||||||
* @param {*} callback 注册成功后的回调
|
* @param {*} callback 注册成功后的回调
|
||||||
|
@ -197,16 +197,77 @@ function getByPath(obj,path,defaultValue){
|
|||||||
return cur
|
return cur
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回value相对rel的相对时间
|
|
||||||
*
|
|
||||||
* 如:12分钟前, 6秒前, 1小时
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
function relativeTime(value, rel){
|
|
||||||
|
|
||||||
|
// YY 18 年,两位数
|
||||||
|
// YYYY 2018 年,四位数
|
||||||
|
// M 1-12 月,从1开始
|
||||||
|
// MM 01-12 月,两位数字
|
||||||
|
// MMM Jan-Dec 月,英文缩写
|
||||||
|
// D 1-31 日
|
||||||
|
// DD 01-31 日,两位数
|
||||||
|
// H 0-23 24小时
|
||||||
|
// HH 00-23 24小时,两位数
|
||||||
|
// h 1-12 12小时
|
||||||
|
// hh 01-12 12小时,两位数
|
||||||
|
// m 0-59 分钟
|
||||||
|
// mm 00-59 分钟,两位数
|
||||||
|
// s 0-59 秒
|
||||||
|
// ss 00-59 秒,两位数
|
||||||
|
// S 0-9 毫秒(百),一位数
|
||||||
|
// SS 00-99 毫秒(十),两位数
|
||||||
|
// SSS 000-999 毫秒,三位数
|
||||||
|
// Z -05:00 UTC偏移
|
||||||
|
// ZZ -0500 UTC偏移,两位数
|
||||||
|
// A AM / PM 上/下午,大写
|
||||||
|
// a am / pm 上/下午,小写
|
||||||
|
// Do 1st... 31st 月份的日期与序号
|
||||||
|
|
||||||
|
function formatDatetime(value,templ="YYYY/MM/DD HH:mm:ss"){
|
||||||
|
const v = toDate(value)
|
||||||
|
const year =String(v.getFullYear()),month = String(v.getMonth()+1),weekday=String(v.getDay()),day=String(v.getDate())
|
||||||
|
const minute = String(v.getMinutes()),second = String(v.getSeconds()),millisecond=String(v.getMilliseconds()),hour = String(v.getHours())
|
||||||
|
const time = String(v.getTime())
|
||||||
|
let result = templ
|
||||||
|
const vars = [
|
||||||
|
["YYYY", year], // 2018 年,四位数
|
||||||
|
["YY", year.substring(year.length - 2, year.length)], // 18 年,两位数
|
||||||
|
["MMM", ""], // Jan-Dec 月,英文缩写
|
||||||
|
["MM", month.padStart(2, "0")], // 01-12 月,两位数字
|
||||||
|
["M", month], // 1-12 月,从1开始
|
||||||
|
["DD", day.padStart(2, "0")], // 01-31 日,两位数
|
||||||
|
["D", day], // 1-31 日
|
||||||
|
["HH", String(hour).padStart(2, "0")], // 00-23 24小时,两位数
|
||||||
|
["H", String(hour)], // 0-23 24小时
|
||||||
|
["hh", String(hour > 12 ? hour - 12 : hour).padStart(2, "0")], // 01-12 12小时,两位数
|
||||||
|
["h", hour > 12 ? hour - 12 : hour], // 1-12 12小时
|
||||||
|
["mm", minute.padStart(2, "0")], // 00-59 分钟,两位数
|
||||||
|
["m", minute], // 0-59 分钟
|
||||||
|
["ss", second.padStart(2, "0")], // 00-59 秒,两位数
|
||||||
|
["s", second], // 0-59 秒
|
||||||
|
["SSS", millisecond], // 000-999 毫秒,三位数
|
||||||
|
["SS", millisecond.substring(year.length - 2, year.length)], // 00-99 毫秒(十),两位数
|
||||||
|
["S",millisecond[millisecond.length - 1]], // 0-9 毫秒(百),一位数
|
||||||
|
["A", hour > 12 ? "PM" : "AM"], // AM / PM 上/下午,大写
|
||||||
|
["a", hour > 12 ? "pm" : "am"] // am / pm 上/下午,小写
|
||||||
|
]
|
||||||
|
vars.forEach(([key,value])=>result = result.replace(key,value))
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建格式化器
|
||||||
|
*/
|
||||||
|
function createFormatter(fn,meta={}){
|
||||||
|
let opts = Object.assign({
|
||||||
|
checker : false, // true时代表该格式化器是作为校验器存在,会在执行每一次格式化器函数后调用进行检查
|
||||||
|
paramCount : 0, // 声明该该格式化器具有几个参数,0代表未知
|
||||||
|
error : 0, // 当执行格式化化器函数出错时的行为,取值0-break,1-skip,2-default
|
||||||
|
empty : false, // 当输入为空时的输出
|
||||||
|
default : null // 当出错默认输出
|
||||||
|
},meta)
|
||||||
|
Object.entries(opts).forEach(([key,value])=>fn[key] = value)
|
||||||
|
return fn
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports ={
|
module.exports ={
|
||||||
|
Loading…
x
Reference in New Issue
Block a user