修复单元测试和增加文档
This commit is contained in:
parent
525cb15f80
commit
8e9ee9ac35
@ -15,7 +15,12 @@ export default defineConfig({
|
||||
locales: [['zh-CN', '中文']],
|
||||
theme:{
|
||||
"@c-heading": "#4569d4"
|
||||
},
|
||||
},
|
||||
styles: [`
|
||||
ul.__dumi-default-layout-toc > li[data-depth=2] {
|
||||
font-weight: bold;
|
||||
}
|
||||
`],
|
||||
scripts:[`
|
||||
var _hmt = _hmt || [];
|
||||
(function() {
|
||||
|
@ -188,6 +188,11 @@ myapp> voerkai18n compile
|
||||
|-- en.js
|
||||
|-- jp.js
|
||||
|-- de.js
|
||||
|-- formatters // 自定义扩展格式化器
|
||||
|-- zh.js
|
||||
|-- en.js
|
||||
|-- jp.js
|
||||
|-- de.js
|
||||
|-- translates // 此文件夹包含了所有需要翻译的内容
|
||||
|-- default.json
|
||||
|-- package.json
|
||||
|
@ -2,26 +2,11 @@
|
||||
|
||||
## 概述
|
||||
|
||||
得益于`voerkai18n`强大的格式化机制,`@voerkai18n/runtime`内置了对强大灵活的日期时间处理机制,可以很轻松实现多语言场景下的灵活多变的日期时间显示。
|
||||
`voerkai18n`支持丰富的格式化器用来支持本地化日期时间显示:
|
||||
- `date`
|
||||
- `time`
|
||||
- `year`
|
||||
- `quarter`
|
||||
- `month`
|
||||
- `day`
|
||||
- `weekday`
|
||||
- `hour`
|
||||
- `hour12`
|
||||
- `minute`
|
||||
- `second`
|
||||
- `millisecond`
|
||||
- `timestamp`
|
||||
得益于`voerkai18n`强大的格式化机制,`@voerkai18n/runtime`内置了对强大灵活的日期时间处理机制,可以很轻松实现多语言场景下的灵活多变的日期时间显示。
|
||||
|
||||
关于格式化器的更完整说明请[参阅](../advanced/customformatter)
|
||||
关于格式化器的工作原理和配置说明请[参阅](../advanced/customformatter)
|
||||
|
||||
## 指南
|
||||
### 基本用法
|
||||
## 基本用法
|
||||
|
||||
当需要对日期和时间进行本地化显示时,请使用相对应的日期时间格式化器,可以在`t`函数中使用来对日期型变量进行本地化格式输出。
|
||||
|
||||
@ -52,116 +37,6 @@
|
||||
```
|
||||
根据指定的模板字符串进行插值后输出。模板字符串中可以使用如`YYYY`、`MM`、`DD`等`占位符`来表示日期时间中的年月日等,可用的模板占位符见本文最后。
|
||||
|
||||
|
||||
### 配置方法
|
||||
`voerkai18n`运行时已经内置了`zh`、`en`两种语言的日期时间相关的的格式化器。为了满足复杂的应用需要求,可以根据需要对日期时间格式化进行配置定制。
|
||||
|
||||
配置定制日期时间格式化非常简单,当使用`voerkai18n compile`后,项目结构中会生成`formatters`如下:
|
||||
```javascript | pure
|
||||
<myapp>
|
||||
|--src
|
||||
| |-- languages
|
||||
| | |--
|
||||
| | |-- formatters
|
||||
| | | |-- zh.js
|
||||
| | | |-- en.js
|
||||
| | | |-- de.js
|
||||
|
||||
....
|
||||
```
|
||||
`formatters`文件夹中的`zh.js`、`en.js`、`de.js`文件中包括了您自定义的格式化器。
|
||||
现在一般您可以选择:
|
||||
- 修改内置的日期时间格式化
|
||||
- 配置指定语言的日期时间格式化
|
||||
#### **修改内置的日期时间格式**
|
||||
由于`@voerkai18n/runtime`中已经内置了`zh`和`en`两种语言的日期时间格式化器,大多数情况下,我们会定时更新确保其有效工作,一般情况下,您是不需要修改`zh.js`、`en.js`这两个文件了。
|
||||
但是如果内置的`zh`和`en`两种语言的日期时间格式化器不能满足要求,您可以选择性地修改`zh.js`、`en.js`这两个文件,这些文件会覆盖合并到内置的日期和时间格式化规则。
|
||||
|
||||
当您第一次打开`languages/formatters/<语言名称>.js`时会发现里面是空的,除了一些注释外。如下:
|
||||
```javscript | pure
|
||||
export default {
|
||||
$config:{
|
||||
}
|
||||
}
|
||||
```
|
||||
现在假设我们需要将`zh`语言的日期时间`long`格式的输出从默认的`YYYY年MM月DD日 HH点mm分ss秒`调整为`北京时间: YYYY年MM月DD日 HH点mm分ss秒`,那么只需要修改 `languages/formatters/zh.js`,如下:
|
||||
```javscript | pure
|
||||
export default {
|
||||
$config:{
|
||||
datetime:{
|
||||
date:{
|
||||
long:"北京时间: YYYY年MM月DD日 HH点mm分ss秒"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
`languages/formatters/zh.js`中的配置优先级最高,会合并覆盖内置的配置。
|
||||
|
||||
**为什么可以通过修改`$config.datetime.date`来修改默认的日期时间格式化?**
|
||||
|
||||
因为`date`格式化器是可配置的,当该格式化器会从`$config.datetime.date`读取模板字符串来进行格式化输出。因此,只需要覆盖`$config.datetime.date`参数即可实现自定义格式化。
|
||||
|
||||
事实上,`date`/`quarter`/`month`/`weekday`/`time`等格式化器均是可配置的,对应的配置位置是:
|
||||
```javscript | pure
|
||||
export default {
|
||||
$config:{
|
||||
datetime:{
|
||||
date:{ ... },
|
||||
quarter:{ ... },
|
||||
month:{ ... },
|
||||
weekday:{ ... },
|
||||
time:{ ... },
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
按照这样的机制,我们就可分别配置在不种语言下,对日期时间等显示方式。
|
||||
#### **配置指定语言的日期时间格式化**
|
||||
默认情况下,`en`语言的日期时间格式化器被注册到全局,当任何一种语言的指定格式化器没有定义时,会在全局格式化器中查找,因此`en`语言的日期时间格式化器是适用于所有语言。
|
||||
|
||||
如果`en`语言的日期时间格式化不符合`de`语言的要求,修改`languages/formatters/de.js`文件。
|
||||
|
||||
```javscript | pure
|
||||
export default {
|
||||
$config:{
|
||||
datetime:{
|
||||
date:{
|
||||
long:"<de语言的长日期时间格式模板>"
|
||||
short:"<de语言的长日期时间格式模板>"
|
||||
format:"long"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
这样,当切换到`de`语言时,date格式化器就会读取`languages/formatters/de.js`文件中的配置,从而实现符合要求的`de`语言的日期时间格式化。
|
||||
|
||||
|
||||
### 格式模板占位符
|
||||
|
||||
|
||||
| 占位符 | 说明 |
|
||||
| --- | --- |
|
||||
|YYYY | 2018 年,四位数|
|
||||
|YY | 18 年,两位数 |
|
||||
|MMM | Jan-Dec 月,英文缩写|
|
||||
|MM | 01-12 月,两位数字|
|
||||
|M | 1-12 月,从1开始|
|
||||
|DD | 01-31 日,两位数|
|
||||
|D | 1-31 日|
|
||||
|HH | 00-23 24小时,两位数|
|
||||
|H | 0-23 24小时|
|
||||
|hh | 01-12 12小时,两位数|
|
||||
|h | 1-12 12小时|
|
||||
|mm | 00-59 分钟,两位数|
|
||||
|m | 0-59 分钟|
|
||||
|ss | 00-59 秒,两位数|
|
||||
|s | 0-59 秒|
|
||||
|SSS | 000-999 毫秒,三位数|
|
||||
|A | AM / PM 上/下午,大写|
|
||||
|a | am / pm 上/下午,小写|
|
||||
|
||||
## 格式化器
|
||||
|
||||
### 日期 - `date`
|
||||
@ -209,12 +84,12 @@ t("{ value | date('YYYY-MM-DD') }",1661084229790)
|
||||
| --- | --- |
|
||||
| `t("现在是{ value }",NOW)` | `现在是2022/8/12 10:12:36`|
|
||||
| `t("现在是{ value \| date }",NOW)` | `现在是2022/8/12 10:12:36`|
|
||||
| `t("现在是{ value \| date('local') }",NOW)` | `` |
|
||||
| `t("现在是{ value \| date('local') }",NOW)` | `现在是2022/8/12 10:12:36` |
|
||||
| `t("现在是{ value \| date('long') }",NOW)` | `现在是2022年08月12日 10点12分36秒` |
|
||||
| `t("现在是{ value \| date('short') }",NOW)` | `现在是2022/08/12` |
|
||||
| `t("现在是{ value \| date('iso') }",NOW)` | `` |
|
||||
| `t("现在是{ value \| date('gmt') }",NOW)` | `` |
|
||||
| `t("现在是{ value \| date('utc') }",NOW)` | `` |
|
||||
| `t("现在是{ value \| date('iso') }",NOW)` | `现在是2022-08-12T02:12:36.000Z` |
|
||||
| `t("现在是{ value \| date('gmt') }",NOW)` | `现在是Fri, 12 Aug 2022 02:12:36 GMT` |
|
||||
| `t("现在是{ value \| date('utc') }",NOW)` | `现在是Fri, 12 Aug 2022 02:12:36 GMT` |
|
||||
| **自定义格式** | |
|
||||
| `t("现在是{ value \| date('YYYY-MM-DD HH:mm:ss')}",NOW)`| `现在是2022-08-12 10:12:36`|
|
||||
| `t("现在是{ value \| date('YYYY/MM/DD') }",NOW)",NOW)` | `现在是2022-08-12`|
|
||||
@ -225,12 +100,12 @@ t("{ value | date('YYYY-MM-DD') }",1661084229790)
|
||||
| --- | --- |
|
||||
| `t("现在是 { value }",NOW)` | `Now is 2022/8/12 10:12:36`|
|
||||
| `t("现在是 { value \| date }",NOW)` | `Now is 2022/8/12 10:12:36`|
|
||||
| `t("现在是 { value \| date('local') }",NOW)` | `Now is ` |
|
||||
| `t("现在是 { value \| date('local') }",NOW)` | `Now is 2022/8/12 10:12:36` |
|
||||
| `t("现在是 { value \| date('long') }",NOW)` | `Now is 2022/08/12 10:12:36` |
|
||||
| `t("现在是 { value \| date('short') }",NOW)` | `Now is 2022/08/12` |
|
||||
| `t("现在是 { value \| date('iso') }",NOW)` | `Now is ` |
|
||||
| `t("现在是 { value \| date('gmt') }",NOW)` | `Now is ` |
|
||||
| `t("现在是 { value \| date('utc') }",NOW)` | `Now is ` |
|
||||
| `t("现在是 { value \| date('iso') }",NOW)` | `Now is 2022-08-12T02:12:36.000Z` |
|
||||
| `t("现在是 { value \| date('gmt') }",NOW)` | `Now is Fri, 12 Aug 2022 02:12:36 GMT` |
|
||||
| `t("现在是 { value \| date('utc') }",NOW)` | `Now is Fri, 12 Aug 2022 02:12:36 GMT` |
|
||||
| **自定义格式** | |
|
||||
| `t("现在是 { value \| date('YYYY-MM-DD HH:mm:ss') }",NOW`| `Now is 2022-08-12 10:12:36`|
|
||||
| `t("现在是 { value \| date('YYYY/MM/DD')}",NOW"),` | `Now is 2022-08-12`|
|
||||
@ -238,16 +113,40 @@ t("{ value | date('YYYY-MM-DD') }",1661084229790)
|
||||
|
||||
#### **配置**
|
||||
|
||||
除了`local`,`iso`,`gmt`,`utc`是调用`Date原型方法`外,`long`,`short`两种预设的格式是采用可配置的模板字符串来定义的。默认情况下其预设格式是:
|
||||
除了`local`,`iso`,`gmt`,`utc`是调用`Date原型方法`外,`date`格式化器的支持以下配置:
|
||||
|
||||
| 格式名称 | 中文(zh) | 英文(en) |
|
||||
| --- | --- | --- |
|
||||
| `long` | `YYYY年MM月DD日 HH点mm分ss秒` | `YYYY/MM/DD HH:mm:ss` |
|
||||
| `short` | `YYYY/MM/DD` | `YYYY/MM/DD` |
|
||||
- **配置文件**:`languages/formatters/<语言名称>.js`
|
||||
- **配置位置**: `$config.datetime.date`
|
||||
- **配置参数**:
|
||||
```javascript
|
||||
export default {
|
||||
$config:{
|
||||
datetime:{
|
||||
date:{
|
||||
long:"<模板字符串>",
|
||||
short:"<模板字符串>",
|
||||
format:"<local | iso | gmt | utc | long | short | [模板字符串]>"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
### 时间 - `time`
|
||||
`date`格式化器用来对日期类型的变量进行格式化。`date`格式化器支持参数:
|
||||
#### 用法
|
||||
|
||||
```javascript | pure
|
||||
t("{ value | time }",new Date())
|
||||
t("{ value | time('local') }","2022/12/9 09:12:36")
|
||||
t("{ value | timetime('long') }",new Date())
|
||||
t("{ value | time('short') }","2022/12/9 09:12:36")
|
||||
t("{ value | time('timestamp')}",1661084229790)
|
||||
t("{ value | time('HH点mm分ss秒') }",1661084229790)
|
||||
t("{ value | time('HH:mms:ss') }",1661084229790)
|
||||
```
|
||||
#### 参数
|
||||
| 参数 | 类型 | 默认值 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
@ -263,11 +162,12 @@ t("{ value | date('YYYY-MM-DD') }",1661084229790)
|
||||
**当`activeLanguage == "zh"`时:**
|
||||
| 翻译 | 输出 |
|
||||
| --- | --- |
|
||||
| `t("现在时间 - { value \| time }",NOW)` | `现在时间 - ` |
|
||||
| `t("现在时间 - { value \| time('local') }",NOW)` | `现在时间 - ` |
|
||||
| `t("现在时间 - { value \| time }",NOW)` | `现在时间 - 10:12:36` |
|
||||
| `t("现在时间 - { value \| time('local') }",NOW)` | `现在时间 - 10:12:36` |
|
||||
| `t("现在时间 - { value \| time('long') }",NOW)` | `现在时间 - 10点12分36秒` |
|
||||
| `t("现在时间 - { value \| time('short') }",NOW)` | `现在时间 - 10:12:36` |
|
||||
| `t("现在时间 - { value \| time('timestamp') }", ",NOW)` | `现在时间 - 1660270356000` |
|
||||
|
||||
| **自定义格式**
|
||||
| `t("现在时间 - { value \| time('HH:mm:ss') }",NOW)` | `现在时间 - 10:12:36` |
|
||||
| `t("现在时间 - { value \| time('mm:ss') }",NOW)` | `现在时间 - 12:36` |
|
||||
@ -276,8 +176,8 @@ t("{ value | date('YYYY-MM-DD') }",1661084229790)
|
||||
**当`activeLanguage == "en"`时:**
|
||||
| 翻译 | 输出 |
|
||||
| --- | --- |
|
||||
| `t("现在时间 - { value \| time }",NOW)` | `Now is - ` |
|
||||
| `t("现在时间 - { value \| time('local') }",NOW)` | `Now is - ` |
|
||||
| `t("现在时间 - { value \| time }",NOW)` | `Now is - 10:12:36` |
|
||||
| `t("现在时间 - { value \| time('local') }",NOW)` | `Now is - 10:12:36` |
|
||||
| `t("现在时间 - { value \| time('long') }",NOW)` | `Now is - 10点12分36秒` |
|
||||
| `t("现在时间 - { value \| time('short') }",NOW)` | `Now is - 10:12:36` |
|
||||
| `t("现在时间 - { value \| time('timestamp') }",NOW)` | `Now is - 1660270356000` |
|
||||
@ -288,12 +188,33 @@ t("{ value | date('YYYY-MM-DD') }",1661084229790)
|
||||
|
||||
#### 配置
|
||||
|
||||
`time`格式化器的配置方式同`date`格式化器。
|
||||
- **配置文件**:`languages/formatters/<语言名称>.js`
|
||||
- **配置位置**: `$config.datetime.time`
|
||||
- **配置参数**:
|
||||
```javascript
|
||||
export default {
|
||||
$config:{
|
||||
datetime:{
|
||||
time:{
|
||||
long:"<模板字符串>",
|
||||
short:"<模板字符串>",
|
||||
format:"<local | long | short | [模板字符串]>"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 年份 - `year`
|
||||
简单输出年份数值,如`t("现在是{ value | year}",new Date())`输出`现在是2022`
|
||||
### 季度 - `quarter`
|
||||
输出一年中第几个季度。
|
||||
#### 用法
|
||||
```javascript | pure
|
||||
t("{ value | quarter }",new Date())
|
||||
t("{ value | quarter('long') }",new Date())
|
||||
t("{ value | quarter('short') }","2022/12/9 09:12:36")
|
||||
t("{ value | quarter('number') }","2022/12/9 09:12:36")
|
||||
```
|
||||
|
||||
#### 参数
|
||||
| 参数 | 类型 | 默认值 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
@ -311,32 +232,43 @@ t("{ value | date('YYYY-MM-DD') }",1661084229790)
|
||||
**当`activeLanguage == "en"`时:**
|
||||
| 文本 | 输出 |
|
||||
| --- | --- |
|
||||
| `t("今年{ value \| quarter }",NOW)` | `First Quarter of this year` |
|
||||
| `t("今年{ value \| quarter }",NOW)` | `Q1 of this year` |
|
||||
| `t("今年{ value \| quarter("long") }",NOW)` | `First Quarter of this year` |
|
||||
| `t("今年{ value \| quarter("short") }",NOW)` | `Q1 of this year` |
|
||||
| `t("今年{ value \| quarter("number") }",NOW)` | `1 of this year` |
|
||||
|
||||
#### 配置
|
||||
配置方式同`date`格式化器。可以选择性地修改`languages/formatters/<语言名称>.js`
|
||||
```javascript | pure
|
||||
export default {
|
||||
$config:{
|
||||
datetime:{
|
||||
quarter:{
|
||||
long:["Q1","Q2","Q3","Q4"],
|
||||
short:["Q1","Q2","Q3","Q4"],
|
||||
format : "short",
|
||||
|
||||
- **配置文件**:`languages/formatters/<语言名称>.js`
|
||||
- **配置位置**: `$config.datetime.quarter`
|
||||
- **配置参数**:
|
||||
```javascript
|
||||
export default {
|
||||
$config:{
|
||||
datetime:{
|
||||
quarter:{
|
||||
long:"<模板字符串>",
|
||||
short:"<模板字符串>",
|
||||
format:"< 0:long | 1:short | 2:number>"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### 月份 - `month`
|
||||
输出月份
|
||||
|
||||
`month`格式化器用来输出月份。
|
||||
#### 用法
|
||||
|
||||
```javascript | pure
|
||||
t("{ value | month }",new Date())
|
||||
t("{ value | month('long') }",new Date())
|
||||
t("{ value | month('short') }","2022/12/9 09:12:36")
|
||||
t("{ value | month('number') }","2022/12/9 09:12:36")
|
||||
```
|
||||
|
||||
#### 参数
|
||||
| 参数 | 类型 | 默认值 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
@ -368,26 +300,33 @@ export default {
|
||||
|
||||
#### 配置
|
||||
|
||||
`month`格式化器的配置方式同`date`格式化器。
|
||||
可以选择性地修改`languages/formatters/<语言名称>.js`
|
||||
```javascript | pure
|
||||
export default {
|
||||
$config:{
|
||||
datetime:{
|
||||
month:{
|
||||
long : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
|
||||
short : ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"],
|
||||
format : "short",
|
||||
- **配置文件**:`languages/formatters/<语言名称>.js`
|
||||
- **配置位置**: `$config.datetime.month`
|
||||
- **配置参数**:
|
||||
```javascript
|
||||
export default {
|
||||
$config:{
|
||||
datetime:{
|
||||
month:{
|
||||
long:["一月",...,"十二月"],
|
||||
short:["1月",...,"12月"],
|
||||
format:"< 0:long | 1:short | 2:number>"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
}
|
||||
```
|
||||
|
||||
### 天 - `day`
|
||||
输出每个月的几号。如`t("现在是{ value | day }号",new Date())`输出`现在是28号`。
|
||||
### 星期 - `weekday`
|
||||
输出一星期中的第几天,如星期一、星期二、...星期日。
|
||||
#### 用法
|
||||
```javascript | pure
|
||||
t("{ value | weekday }",new Date())
|
||||
t("{ value | weekday('long') }",new Date())
|
||||
t("{ value | weekday('short') }","2022/12/9 09:12:36")
|
||||
t("{ value | weekday('number') }","2022/12/9 09:12:36")
|
||||
```
|
||||
|
||||
#### 参数
|
||||
| 参数 | 类型 | 默认值 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
@ -400,7 +339,7 @@ export default {
|
||||
| --- | --- |
|
||||
| `t("今天是{ value \| weekday }",NOW)` | `今天是星期一 ` |
|
||||
| `t("今天是{ value \| weekday("long") }",NOW)` | `今天是星期一 ` |
|
||||
| `t("今天是{ value \| weekday("short") }",NOW)` | `今天是一 ` |
|
||||
| `t("今天是{ value \| weekday("short") }",NOW)` | `今天是周一 ` |
|
||||
| `t("今天是{ value \| weekday("number") }",NOW)` | `今天是1` |
|
||||
|
||||
**当`activeLanguage == "en"`时:**
|
||||
@ -413,24 +352,170 @@ export default {
|
||||
| `t("今天是{ value \| weekday("number") }",NOW)` | `Today is 1` |
|
||||
|
||||
#### 配置
|
||||
配置方式同`date`格式化器。可以选择性地修改`languages/formatters/<语言名称>.js`
|
||||
- **配置文件**:`languages/formatters/<语言名称>.js`
|
||||
- **配置位置**: `$config.datetime.weekday`
|
||||
- **配置参数**:
|
||||
```javascript
|
||||
export default {
|
||||
$config:{
|
||||
datetime:{
|
||||
weekday:{
|
||||
long:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],
|
||||
short:["周日","周一","周二","周三","周四","周五","周六"],
|
||||
format:"< 0:long | 1:short | 2:number>"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```javascript | pure
|
||||
|
||||
|
||||
## 扩展配置
|
||||
`voerkai18n`运行时已经内置了`zh`、`en`两种语言的日期时间相关的的格式化器。
|
||||
为了满足复杂的应用需要求,日期时间格式化器被设计为可以进行配置。当以上格式化器不能满足要求,或者缺少某种语言的日期时间格式化时,可以非常容易地进行扩展。
|
||||
|
||||
扩展支持不同语言言的日期时间格式化非常简单,当使用`voerkai18n compile`后,项目结构中会生成`formatters`如下:
|
||||
|
||||
```javascript | pure
|
||||
<myapp>
|
||||
|--src
|
||||
| |-- languages
|
||||
| | |--
|
||||
| | |-- formatters
|
||||
| | | |-- zh.js
|
||||
| | | |-- en.js
|
||||
| | | |-- de.js
|
||||
|
||||
....
|
||||
```
|
||||
`formatters`文件夹中的`zh.js`、`en.js`、`de.js`文件中包括了您自定义的格式化器。
|
||||
|
||||
当您第一次打开这些文件时,会发现里面除了一些注释来引导您如何编写扩展格式化器外,并没有其他有效的内容。
|
||||
|
||||
如果您对现有的日期格式化器的输出不满意,或者缺少某种语言的日期时间格式化,您可以按下面介绍的方式来进行扩展。
|
||||
|
||||
**放心**,整个扩展过程非常简单,大部分情况下,只需要配置一些模板字符串即可。
|
||||
|
||||
以下开始介绍内容:
|
||||
|
||||
- **通过简单的配置修改内置的日期时间格式化规则**
|
||||
- **为运行时没有支持的语言增加日期时间格式化规则**
|
||||
- **自定义预设的规则**
|
||||
- **编写日期时间格式化模板**
|
||||
|
||||
### **修改内置规则**
|
||||
由于`@voerkai18n/runtime`中已经内置了`zh`和`en`两种语言的日期时间格式化器,大多数情况下,我们会定时更新确保其有效工作,一般情况下,您是不需要修改`zh.js`、`en.js`这两个文件了。
|
||||
但是如果内置的`zh`和`en`两种语言的日期时间格式化器不能满足要求,您可以选择性地修改`zh.js`、`en.js`这两个文件,这些文件会覆盖合并到内置的日期和时间格式化规则。
|
||||
|
||||
当您第一次打开`languages/formatters/<语言名称>.js`时会发现里面是空的(除了一些注释外)。内容大概如下:
|
||||
```javascript | pure
|
||||
export default {
|
||||
$config:{
|
||||
}
|
||||
}
|
||||
```
|
||||
现在假设我们需要将`zh`语言的日期时间`long`格式的输出从默认的`YYYY年MM月DD日 HH点mm分ss秒`调整为`北京时间: YYYY年MM月DD日 HH点mm分ss秒`,那么只需要修改 `languages/formatters/zh.js`,如下:
|
||||
```javascript | pure
|
||||
export default {
|
||||
$config:{
|
||||
datetime:{
|
||||
long :["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
|
||||
short : ["Sun", "Mon", "Tues", "Wed", "Thur", "Fri", "Sat"],
|
||||
format : 0, // 默认格式: 0:long-长名称,1:short-短名称,2:number-数字
|
||||
date:{
|
||||
long:"北京时间: YYYY年MM月DD日 HH点mm分ss秒"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
`languages/formatters/zh.js`中的配置优先级最高,会覆盖内置的格式化规则。
|
||||
|
||||
**为什么可以通过修改`$config.datetime.date`来修改默认的日期时间格式化?**
|
||||
|
||||
因为`date`格式化器是可配置的,该格式化器函数会从`$config.datetime.date`读取模板字符串来进行格式化输出。因此,只需要修改`$config.datetime.date`中的配置参数即可实现自定义格式化。
|
||||
|
||||
事实上,`date`/`quarter`/`month`/`weekday`/`time`等格式化器均是可配置的,对应的配置位置是:
|
||||
```javascript | pure
|
||||
export default {
|
||||
$config:{
|
||||
datetime:{
|
||||
date:{ ... },
|
||||
quarter:{ ... },
|
||||
month:{ ... },
|
||||
weekday:{ ... },
|
||||
time:{ ... },
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
按照这样的机制,我们就可以很容易分别配置在不种语言下对日期时间等显示方式。并且在多包模下,这种修改只会对当前应用或库生效。
|
||||
|
||||
### **增加格式化规则**
|
||||
由于开发者对各语种日期时间格式化知识的缺失。目前,`voerkai18n`只内置了`zh`,`en`两种语言的日期时间规则支持。
|
||||
其中,`en`语言的日期时间格式化器被注册到全局。当切换到`zh`,`en`两种语言之外的其他语言时,会使用`en`语言的日期时间格式化规则。
|
||||
|
||||
很明显,`en`语言的日期时间格式化规则并不能适应所有语言的要求,在官方提供该语言支持前,您可以自行配置语言支持。
|
||||
|
||||
方法很简单,以`de`语言为例,打开`languages/formatters/de.js`文件。
|
||||
|
||||
```javascript | pure
|
||||
export default {
|
||||
$config:{
|
||||
datetime:{
|
||||
date:{
|
||||
long:"<de语言的长日期时间格式模板>"
|
||||
short:"<de语言的长日期时间格式模板>"
|
||||
format:"long"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
这样,当切换到`de`语言时,date格式化器就会读取`languages/formatters/de.js`文件中的配置,从而实现符合要求的`de`语言的日期时间格式化。
|
||||
|
||||
最后,欢迎大家贡献其他语种的日期时间格式化规则,贡献方法可以直接提交在[issues](https://gitee.com/zhangfisher/voerka-i18n/issues),也可以通过[源码方式](https://gitee.com/zhangfisher/voerka-i18n)提交PR。
|
||||
|
||||
### **扩展预设规则**
|
||||
|
||||
除了预设的`long`、`short`、`number`等规则外,您可以通过模板字符串来自定义更加灵活的格式化规则。
|
||||
您也可以自己定义一个预设格式化规则。
|
||||
|
||||
比如可以为`date`格式化器定义一个`full`的规则来显示更加完整的日期时间:
|
||||
```javascript | pure
|
||||
t("现在是{ value | date('full') }") // 北京时间:2022年08月12日 10点12分36秒 上午
|
||||
```
|
||||
|
||||
### 小时 - `hour`
|
||||
方法如下:
|
||||
在`languages/formatters/zh.json`中,增加一个`full`配置项即可。
|
||||
```javascript | pure
|
||||
export default {
|
||||
$config: {
|
||||
full: "北京时间:YYYY年MM月DD日 HH点mm分ss秒 a"
|
||||
}
|
||||
}
|
||||
```
|
||||
有了自定义的`full`预设规则,应用中就可以直接使用`t("现在是{ value | date('full') }") `进行格式化,而不需要使用自定义模板字符串的形式。
|
||||
|
||||
### 自定义模板
|
||||
|
||||
### 分钟 - `minute`
|
||||
### 秒 - `second`
|
||||
### 毫秒 - `millisecond`
|
||||
### 时间戳 - `timestamp`
|
||||
日期时间格式化时可以自定义显示格式模板,模板字符串中可以使用以下占位符:
|
||||
|
||||
| 占位符 | 说明 |
|
||||
| --- | --- |
|
||||
|YYYY | 2018 年,四位数|
|
||||
|YY | 18 年,两位数 |
|
||||
|MMM | Jan-Dec 月,英文缩写|
|
||||
|MM | 01-12 月,两位数字|
|
||||
|M | 1-12 月,从1开始|
|
||||
|DD | 01-31 日,两位数|
|
||||
|D | 1-31 日|
|
||||
|HH | 00-23 24小时,两位数|
|
||||
|H | 0-23 24小时|
|
||||
|hh | 01-12 12小时,两位数|
|
||||
|h | 1-12 12小时|
|
||||
|mm | 00-59 分钟,两位数|
|
||||
|m | 0-59 分钟|
|
||||
|ss | 00-59 秒,两位数|
|
||||
|s | 0-59 秒|
|
||||
|SSS | 000-999 毫秒,三位数|
|
||||
|A | AM / PM 上/下午,大写|
|
||||
|a | am / pm 上/下午,小写|
|
@ -17,10 +17,15 @@ module.exports = {
|
||||
// clearMocks: false,
|
||||
|
||||
// Indicates whether the coverage information should be collected while executing the test
|
||||
// collectCoverage: false,
|
||||
// collectCoverage: true,
|
||||
|
||||
// An array of glob patterns indicating a set of files for which coverage information should be collected
|
||||
// collectCoverageFrom: undefined,
|
||||
// collectCoverageFrom: [
|
||||
// "./packages/runtime/dist/runtime.cjs",
|
||||
// "./packages/runtime/**/*.js",
|
||||
//"!./packages/runtime/dist/**",
|
||||
//"!./packages/runtime/node_modules/**",
|
||||
//],
|
||||
|
||||
// The directory where Jest should output its coverage files
|
||||
// coverageDirectory: undefined,
|
||||
@ -34,12 +39,12 @@ module.exports = {
|
||||
coverageProvider: "v8",
|
||||
|
||||
// A list of reporter names that Jest uses when writing coverage reports
|
||||
// coverageReporters: [
|
||||
// "json",
|
||||
// "text",
|
||||
// "lcov",
|
||||
// "clover"
|
||||
// ],
|
||||
coverageReporters: [
|
||||
//"json",
|
||||
// "text",
|
||||
"lcov",
|
||||
// "clover"
|
||||
],
|
||||
|
||||
// An object that configures minimum threshold enforcement for coverage results
|
||||
// coverageThreshold: undefined,
|
||||
|
@ -6,10 +6,11 @@
|
||||
"scripts": {
|
||||
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules node node_modules/jest/bin/jest.js ",
|
||||
"test:app": "cross-env NODE_OPTIONS=--experimental-vm-modules node node_modules/jest/bin/jest.js -- app",
|
||||
"test:runtime": "cross-env NODE_OPTIONS=--experimental-vm-modules jest translate --coverage --collectCoverageFrom packages/runtime/dist/runtime.cjs",
|
||||
"list:package": "node ./packages/autopublish/index.js list",
|
||||
"autopublish": "node ./packages/autopublish/index.js -a --no-ask",
|
||||
"docs:build": "cross-env NODE_OPTIONS=--openssl-legacy-provider && dumi build",
|
||||
"docs:dev": "cross-env NODE_OPTIONS=--openssl-legacy-provider && dumi dev "
|
||||
"docs:build": "cross-env NODE_OPTIONS=--openssl-legacy-provider dumi build",
|
||||
"docs:dev": "cross-env NODE_OPTIONS=--openssl-legacy-provider dumi dev "
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
@ -23,7 +24,7 @@
|
||||
"cross-env": "^7.0.3",
|
||||
"dayjs": "^1.11.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
"dumi": "^1.0.13",
|
||||
"dumi": "^1.1.47",
|
||||
"fs-extra": "^10.0.1",
|
||||
"gulp": "^4.0.2",
|
||||
"jest": "^27.5.1",
|
||||
|
@ -1,547 +0,0 @@
|
||||
const {i18nScope, translate, getInterpolatedVars } = require('../dist/runtime.cjs.js')
|
||||
const dayjs = require('dayjs');
|
||||
|
||||
function toLanguageDict(values,startIndex=0){
|
||||
return values.reduce((result,curValue,i)=>{
|
||||
result[i+startIndex] = curValue;
|
||||
return result
|
||||
},{})
|
||||
}
|
||||
function toLanguageIdMap(values,startIndex=0){
|
||||
return values.reduce((result,curValue,i)=>{
|
||||
result[curValue] = i+startIndex
|
||||
return result
|
||||
},{})
|
||||
}
|
||||
// 显示两个数组哪一行不同
|
||||
function diffArray(arr1,arr2){
|
||||
let diffs = []
|
||||
arr1.forEach((v,i)=>{
|
||||
if(v!=arr2[i]) diffs.push([i,[v,arr2[i]]])
|
||||
})
|
||||
return diffs
|
||||
}
|
||||
|
||||
|
||||
const NOW = new Date("2022/08/12 10:12:36")
|
||||
|
||||
const zhDatetimes =[
|
||||
"现在是{ value }",
|
||||
"现在是{ value | date }",
|
||||
"现在是{ value | date('local') }",
|
||||
"现在是{ value | date('long') }",
|
||||
"现在是{ value | date('short') }",
|
||||
"现在是{ value | date('iso') }",
|
||||
"现在是{ value | date('gmt') }",
|
||||
"现在是{ value | date('utc') }",
|
||||
"现在是{ value | date(0) }", // local
|
||||
"现在是{ value | date(1) }", // long
|
||||
"现在是{ value | date(2) }", // short
|
||||
"现在是{ value | date(3) }", // iso
|
||||
"现在是{ value | date(4) }", // gmt
|
||||
"现在是{ value | date(5) }", // utc
|
||||
"现在是{ value | date('YYYY-MM-DD HH:mm:ss')}",
|
||||
"现在是{ value | date('YYYY-MM-DD')}",
|
||||
"现在是{ value | date('HH:mm:ss')}",
|
||||
"现在是{ value | month }",
|
||||
"现在是{ value | month('long')}",
|
||||
"现在是{ value | month('short')}",
|
||||
"现在是{ value | month('number')}",
|
||||
"现在是{ value | month(0)}",
|
||||
"现在是{ value | month(1)}",
|
||||
"现在是{ value | month(2)}",
|
||||
"现在是{ value | weekday }",
|
||||
"现在是{ value | weekday('long')}",
|
||||
"现在是{ value | weekday('short')}",
|
||||
"现在是{ value | weekday('number')}",
|
||||
"现在是{ value | weekday(0)}",
|
||||
"现在是{ value | weekday(1)}",
|
||||
"现在是{ value | weekday(2)}",
|
||||
// 时间
|
||||
"现在时间 - { value | time }",
|
||||
"现在时间 - { value | time('local') }",
|
||||
"现在时间 - { value | time('long') }",
|
||||
"现在时间 - { value | time('short') }",
|
||||
"现在时间 - { value | time('timestamp') }",
|
||||
"现在时间 - { value | time(0) }",
|
||||
"现在时间 - { value | time(1) }",
|
||||
"现在时间 - { value | time(2) }",
|
||||
"现在时间 - { value | time(3) }",
|
||||
"现在时间 - { value | time('HH:mm:ss') }",
|
||||
"现在时间 - { value | time('mm:ss') }",
|
||||
"现在时间 - { value | time('ss') }"
|
||||
]
|
||||
//
|
||||
|
||||
const expectZhDatetimes =[
|
||||
"现在是2022/8/12 10:12:36", // { value }
|
||||
"现在是2022/8/12 10:12:36", // { value | date }
|
||||
`现在是${NOW.toLocaleString()}`, // { value | date('local') }
|
||||
"现在是2022年08月12日 10点12分36秒", // { value | date('long') }
|
||||
"现在是2022/08/12", // { value | date('short') }
|
||||
`现在是${NOW.toISOString()}`, // { value | date('iso') }
|
||||
`现在是${NOW.toGMTString()}`, // { value | date('gmt') }
|
||||
`现在是${NOW.toUTCString()}`, // { value | date('utc') }
|
||||
`现在是${NOW.toLocaleString()}`, // { value | date(0) } // local
|
||||
"现在是2022年08月12日 10点12分36秒", // { value | date(1) } // long
|
||||
"现在是2022/08/12", // { value | date(2) } // short
|
||||
`现在是${NOW.toISOString()}`, // { value | date(3) } // iso
|
||||
`现在是${NOW.toGMTString()}`, // { value | date(4) } // gmt
|
||||
`现在是${NOW.toUTCString()}`, // { value | date(5) } // utc
|
||||
"现在是2022-08-12 10:12:36", // { value | date('YYYY-MM-DD HH:mm:ss')}
|
||||
"现在是2022-08-12", // { value | date('YYYY-MM-DD')}
|
||||
"现在是10:12:36", // { value | date('HH:mm:ss')}
|
||||
"现在是八月", // { value | month }
|
||||
"现在是八月", // { value | month('long')}
|
||||
"现在是八", // { value | month('short')}
|
||||
"现在是8", // { value | month('number')}
|
||||
"现在是八月", // { value | month(0)}
|
||||
"现在是八", // { value | month(1)}
|
||||
"现在是8", // { value | month(2)}
|
||||
"现在是星期五", // { value | weekday }
|
||||
"现在是星期五", // { value | weekday('long')}
|
||||
"现在是五", // { value | weekday('short')}
|
||||
"现在是5", // { value | weekday('number')}
|
||||
"现在是星期五", // { value | weekday(0)}
|
||||
"现在是五", // { value | weekday(1)}
|
||||
"现在是5", // { value | weekday(2)}
|
||||
// 时间
|
||||
`现在时间 - ${NOW.toLocaleTimeString()}`, // { value | time }
|
||||
`现在时间 - ${NOW.toLocaleTimeString()}`, // { value | time('local') }
|
||||
"现在时间 - 10点12分36秒", // { value | time('long') }
|
||||
"现在时间 - 10:12:36", // { value | time('short') }
|
||||
"现在时间 - 1660270356000", // { value | time('timestamp') }
|
||||
`现在时间 - ${NOW.toLocaleTimeString()}`, // { value | time(0) }
|
||||
"现在时间 - 10点12分36秒", // { value | time(1) }
|
||||
"现在时间 - 10:12:36", // { value | time(2) }
|
||||
"现在时间 - 1660270356000", // { value | time(3) }
|
||||
"现在时间 - 10:12:36", // { value | time('HH:mm:ss') }
|
||||
"现在时间 - 12:36", // { value | time('mm:ss') }
|
||||
"现在时间 - 36", // { value | time('ss') }"
|
||||
]
|
||||
|
||||
|
||||
const enDatetimes =[
|
||||
"Now is { value }",
|
||||
"Now is { value | date }",
|
||||
"Now is { value | date('local') }",
|
||||
"Now is { value | date('long') }",
|
||||
"Now is { value | date('short') }",
|
||||
"Now is { value | date('iso') }",
|
||||
"Now is { value | date('gmt') }",
|
||||
"Now is { value | date('utc') }",
|
||||
"Now is { value | date(0) }", // local
|
||||
"Now is { value | date(1) }", // long
|
||||
"Now is { value | date(2) }", // short
|
||||
"Now is { value | date(3) }", // iso
|
||||
"Now is { value | date(4) }", // gmt
|
||||
"Now is { value | date(5) }", // utc
|
||||
"Now is { value | date('YYYY-MM-DD HH:mm:ss')}",
|
||||
"Now is { value | date('YYYY-MM-DD')}",
|
||||
"Now is { value | date('HH:mm:ss')}",
|
||||
"Now is { value | month }",
|
||||
"Now is { value | month('long')}",
|
||||
"Now is { value | month('short')}",
|
||||
"Now is { value | month('number')}",
|
||||
"Now is { value | month(0)}",
|
||||
"Now is { value | month(1)}",
|
||||
"Now is { value | month(2)}",
|
||||
"Now is { value | weekday }",
|
||||
"Now is { value | weekday('long')}",
|
||||
"Now is { value | weekday('short')}",
|
||||
"Now is { value | weekday('number')}",
|
||||
"Now is { value | weekday(0)}",
|
||||
"Now is { value | weekday(1)}",
|
||||
"Now is { value | weekday(2)}",
|
||||
// 时间
|
||||
"Now time: { value | time }",
|
||||
"Now time: { value | time('local') }",
|
||||
"Now time: { value | time('long') }",
|
||||
"Now time: { value | time('short') }",
|
||||
"Now time: { value | time('timestamp') }",
|
||||
"Now time: { value | time(0) }",
|
||||
"Now time: { value | time(1) }",
|
||||
"Now time: { value | time(2) }",
|
||||
"Now time: { value | time(3) }",
|
||||
"Now time: { value | time('HH:mm:ss') }",
|
||||
"Now time: { value | time('mm:ss') }",
|
||||
"Now time: { value | time('ss') }"
|
||||
]
|
||||
|
||||
const expectEnDatetimes =[
|
||||
"Now is 2022/8/12 10:12:36", // { value }
|
||||
"Now is 2022/8/12 10:12:36", // { value | date }
|
||||
`Now is ${NOW.toLocaleString()}`, // { value | date('local') }
|
||||
"Now is 2022/08/12 10:12:36", // { value | date('long') }
|
||||
"Now is 2022/08/12", // { value | date('short') }
|
||||
`Now is ${NOW.toISOString()}`, // { value | date('iso') }
|
||||
`Now is ${NOW.toGMTString()}`, // { value | date('gmt') }
|
||||
`Now is ${NOW.toUTCString()}`, // { value | date('utc') }
|
||||
`Now is ${NOW.toLocaleString()}`, // { value | date(0) } // local
|
||||
"Now is 2022/08/12 10:12:36", // { value | date(1) } // long
|
||||
"Now is 2022/08/12", // { value | date(2) } // short
|
||||
`Now is ${NOW.toISOString()}`, // { value | date(3) } // iso
|
||||
`Now is ${NOW.toGMTString()}`, // { value | date(4) } // gmt
|
||||
`Now is ${NOW.toUTCString()}`, // { value | date(5) } // utc
|
||||
"Now is 2022-08-12 10:12:36", // { value | date('YYYY-MM-DD HH:mm:ss')}
|
||||
"Now is 2022-08-12", // { value | date('YYYY-MM-DD')}
|
||||
"Now is 10:12:36", // { value | date('HH:mm:ss')}
|
||||
"Now is August", // { value | month }
|
||||
"Now is August", // { value | month('long')}
|
||||
"Now is Aug", // { value | month('short')}
|
||||
"Now is 8", // { value | month('number')}
|
||||
"Now is August", // { value | month(0)}
|
||||
"Now is Aug", // { value | month(1)}
|
||||
"Now is 8", // { value | month(2)}
|
||||
"Now is Friday", // { value | weekday }
|
||||
"Now is Friday", // { value | weekday('long')}
|
||||
"Now is Fri", // { value | weekday('short')}
|
||||
"Now is 5", // { value | weekday('number')}
|
||||
"Now is Friday", // { value | weekday(0)}
|
||||
"Now is Fri", // { value | weekday(1)}
|
||||
"Now is 5", // { value | weekday(2)}
|
||||
// 时间
|
||||
`Now time: ${NOW.toLocaleTimeString()}`, // { value | time }
|
||||
`Now time: ${NOW.toLocaleTimeString()}`, // { value | time('local') }
|
||||
"Now time: 10:12:36", // { value | time('long') }
|
||||
"Now time: 10:12:36", // { value | time('short') }
|
||||
"Now time: 1660270356000", // { value | time('timestamp') }
|
||||
`Now time: ${NOW.toLocaleTimeString()}`, // { value | time(0) }
|
||||
"Now time: 10:12:36", // { value | time(1) }
|
||||
"Now time: 10:12:36", // { value | time(2) }
|
||||
"Now time: 1660270356000", // { value | time(3) }
|
||||
"Now time: 10:12:36", // { value | time('HH:mm:ss') }
|
||||
"Now time: 12:36", // { value | time('mm:ss') }
|
||||
"Now time: 36", // { value | time('ss') }"
|
||||
]
|
||||
|
||||
const MONEY = 123456789.88
|
||||
const zhMoneys = [
|
||||
"商品价格: { value | currency}", // 默认格式
|
||||
// long
|
||||
"商品价格: { value | currency('long')}", // 长格式
|
||||
"商品价格: { value | currency('long',1)}", // 长格式: 万元
|
||||
"商品价格: { value | currency('long',2)}", // 长格式: 亿
|
||||
"商品价格: { value | currency('long',3)}", // 长格式: 万亿
|
||||
"商品价格: { value | currency('long',4)}", // 长格式: 万万亿
|
||||
// short
|
||||
"商品价格: { value | currency('short')}", // 短格式
|
||||
"商品价格: { value | currency('short',1)}", // 短格式 Thousands
|
||||
"商品价格: { value | currency('short',2)}", // 短格式 Millions
|
||||
"商品价格: { value | currency('short',3)}", // 短格式 Billions
|
||||
"商品价格: { value | currency('short',4)}", // 短格式 Trillions
|
||||
|
||||
// 自定义货币格式
|
||||
"商品价格: { value | currency({symbol:'¥¥'})}",
|
||||
"商品价格: { value | currency({symbol:'¥¥',prefix:'人民币:'})}",
|
||||
"商品价格: { value | currency({symbol:'¥¥',prefix:'人民币:',suffix:'元整'})}",
|
||||
"商品价格: { value | currency({symbol:'¥¥',prefix:'人民币:',suffix:'元整',unit:2})}",
|
||||
"商品价格: { value | currency({symbol:'¥¥',prefix:'人民币:',suffix:'元整',unit:2,precision:4})}",
|
||||
"商品价格: { value | currency({symbol:'¥¥',prefix:'人民币:',suffix:'元整',unit:2,precision:4,format:'{prefix}*{symbol}*{value}*{unit}*{suffix}'})}"
|
||||
|
||||
]
|
||||
|
||||
const expectZhMoneys =[
|
||||
"商品价格: ¥1,2345,6789.88", // { value | currency }
|
||||
// long
|
||||
"商品价格: RMB ¥1,2345,6789.88元", // { value | currency('long')}
|
||||
"商品价格: RMB ¥1,2345.678988万元", // { value | currency('long',1)}
|
||||
"商品价格: RMB ¥1.2345678988亿元", // { value | currency('long',2)}
|
||||
"商品价格: RMB ¥0.00012345678988万亿元", // { value | currency('long',3)}
|
||||
"商品价格: RMB ¥0.000000012345678988万万亿元", // { value | currency('long',4)}
|
||||
// short
|
||||
"商品价格: ¥1,2345,6789.88", // { value | currency('short')}
|
||||
"商品价格: ¥1,2345.678988万", // { value | currency('short',1)}
|
||||
"商品价格: ¥1.2345678988亿", // { value | currency('short',2)}
|
||||
"商品价格: ¥0.00012345678988万亿", // { value | currency('short',3)}
|
||||
"商品价格: ¥0.000000012345678988万万亿", // { value | currency('short',4)}
|
||||
// 自定义货币格式
|
||||
"商品价格: RMB ¥¥1,2345,6789.88元",
|
||||
"商品价格: 人民币: ¥¥1,2345,6789.88元",
|
||||
"商品价格: 人民币: ¥¥1,2345,6789.88元整",
|
||||
"商品价格: 人民币: ¥¥1.2345678988亿元整",
|
||||
"商品价格: 人民币: ¥¥1.2346+亿元整",
|
||||
"商品价格: 人民币:*¥¥*1.2346+*亿*元整"
|
||||
]
|
||||
|
||||
|
||||
|
||||
const enMoneys = [
|
||||
"Price: { value | currency }", // 默认格式
|
||||
// long
|
||||
"Price: { value | currency('long') }", // 长格式
|
||||
"Price: { value | currency('long',1) }", // 长格式: 万元
|
||||
"Price: { value | currency('long',2) }", // 长格式: 亿
|
||||
"Price: { value | currency('long',3) }", // 长格式: 万亿
|
||||
"Price: { value | currency('long',4) }", // 长格式: 万万亿
|
||||
// short
|
||||
"Price: { value | currency('short') }", // 短格式
|
||||
"Price: { value | currency('short',1) }", // 短格式 Thousands
|
||||
"Price: { value | currency('short',2) }", // 短格式 Millions
|
||||
"Price: { value | currency('short',3) }", // 短格式 Billions
|
||||
"Price: { value | currency('short',4) }", // 短格式 Trillions
|
||||
]
|
||||
const expectEnMoneys =[
|
||||
"Price: $123,456,789.88", // { value | currency }
|
||||
// long
|
||||
"Price: USD $123,456,789.88", // { value | currency('long')}
|
||||
"Price: USD $123,456.78988 thousands", // { value | currency('long',1)}
|
||||
"Price: USD $123.45678988 millions", // { value | currency('long',2)}
|
||||
"Price: USD $0.12345678988 billions", // { value | currency('long',3)}
|
||||
"Price: USD $0.00012345678988 trillions", // { value | currency('long',4)}
|
||||
// short
|
||||
"Price: $123,456,789.88", // { value | currency('short')}
|
||||
"Price: $123,456.78988 thousands", // { value | currency('short',1)}
|
||||
"Price: $123.45678988 millions", // { value | currency('short',2)}
|
||||
"Price: $0.12345678988 billions", // { value | currency('short',3)}
|
||||
"Price: $0.00012345678988 trillions", // { value | currency('short',4)}
|
||||
]
|
||||
|
||||
|
||||
|
||||
const loaders = {
|
||||
zh:{
|
||||
1:"你好",
|
||||
2:"现在是{ value | }",
|
||||
3:"我出生于{year}年,今年{age}岁",
|
||||
4:"我有{}个朋友",
|
||||
...toLanguageDict(zhDatetimes,5),
|
||||
},
|
||||
en :{
|
||||
1:"hello",
|
||||
2:"Now is {}",
|
||||
3:"I was born in {year}, now is {age} years old",
|
||||
4:["I have no friends","I have one friends","I have two friends","I have {} friends"],
|
||||
...toLanguageDict(enDatetimes,5),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const formatters = {
|
||||
zh:{
|
||||
$config:{},
|
||||
$types:{},
|
||||
book:(v)=>`《${v}》`,
|
||||
},
|
||||
en:{
|
||||
$config:{},
|
||||
$types:{ },
|
||||
book:(v)=>`<${v}>`,
|
||||
},
|
||||
}
|
||||
|
||||
const idMap = {
|
||||
"你好":1,
|
||||
"现在是{ value | }":2,
|
||||
"我出生于{year}年,今年{age}岁":3,
|
||||
"我有{}个朋友":4,
|
||||
...toLanguageIdMap(zhDatetimes,5)
|
||||
}
|
||||
const languages = [
|
||||
{ name: "zh", title: "中文" },
|
||||
{ name: "en", title: "英文" },
|
||||
{ name: "de", title: "德语" },
|
||||
{ name: "jp", title: "日语" }
|
||||
]
|
||||
|
||||
|
||||
const scope = new i18nScope({
|
||||
id : "test",
|
||||
defaultLanguage: "zh",
|
||||
activeLanguage : "zh",
|
||||
namespaces : {},
|
||||
default : loaders.zh, // 默认语言包
|
||||
messages : loaders.zh, // 当前语言包
|
||||
languages, // 语言配置
|
||||
idMap, // 消息id映射列表
|
||||
formatters, // 扩展自定义格式化器
|
||||
loaders // 语言包加载器
|
||||
})
|
||||
|
||||
|
||||
const t = translate.bind(scope)
|
||||
|
||||
// 适用于所有语言的格式化器,并且注册到全局
|
||||
scope.registerFormatters({
|
||||
"*":{
|
||||
sum : (v,n=1)=>v+n,
|
||||
double: (v)=>v*2,
|
||||
upper : (v)=>v.toUpperCase()
|
||||
}
|
||||
},true)
|
||||
|
||||
|
||||
|
||||
|
||||
describe("翻译函数",()=>{
|
||||
beforeEach(() => {
|
||||
scope.change("zh")
|
||||
});
|
||||
test("获取翻译内容中的插值变量",done=>{
|
||||
const results = getInterpolatedVars("中华人民共和国成立于{date | year(1,2) | time('a','b') | rel }年,首都是{city}市");
|
||||
expect(results.length).toEqual(2);
|
||||
//
|
||||
expect(results[0].name).toEqual("date");
|
||||
expect(results[0].formatters.length).toEqual(3);
|
||||
// year(1,2)
|
||||
expect(results[0].formatters[0].name).toEqual("year");
|
||||
expect(results[0].formatters[0].args).toEqual([1,2]);
|
||||
// time('a','b')
|
||||
expect(results[0].formatters[1].name).toEqual("time");
|
||||
expect(results[0].formatters[1].args).toEqual(["a","b"]);
|
||||
// rel
|
||||
expect(results[0].formatters[2].name).toEqual("rel");
|
||||
expect(results[0].formatters[2].args).toEqual([]);
|
||||
|
||||
|
||||
expect(results[1].name).toEqual("city");
|
||||
expect(results[1].formatters.length).toEqual(0);
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
test("获取翻译内容中定义了重复的插值变量",done=>{
|
||||
const results = getInterpolatedVars("{a}{a}{a|x}{a|x}{a|x|y}{a|x|y}");
|
||||
expect(results.length).toEqual(3);
|
||||
expect(results[0].name).toEqual("a");
|
||||
expect(results[0].formatters.length).toEqual(0);
|
||||
|
||||
expect(results[1].name).toEqual("a");
|
||||
expect(results[1].formatters.length).toEqual(1);
|
||||
expect(results[1].formatters[0].name).toEqual("x");
|
||||
expect(results[1].formatters[0].args).toEqual([]);
|
||||
|
||||
expect(results[2].name).toEqual("a");
|
||||
expect(results[2].formatters.length).toEqual(2);
|
||||
expect(results[2].formatters[0].name).toEqual("x");
|
||||
expect(results[2].formatters[0].args).toEqual([]);
|
||||
expect(results[2].formatters[1].name).toEqual("y");
|
||||
expect(results[2].formatters[1].args).toEqual([]);
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
test("替换翻译内容的位置插值变量",done=>{
|
||||
expect(t("{}{}{}",1,2,3)).toBe("123");
|
||||
expect(t("{a}{b}{c}",1,2,3)).toBe("123");
|
||||
// 定义了一些无效的格式化器,直接忽略
|
||||
expect(t("{a|xxx}{b|dd}{c|}",1,2,3)).toBe("123");
|
||||
expect(t("{a|xxx}{b|dd}{c|}",1,2,3,4,5,6)).toBe("123");
|
||||
expect(t("{ a|}{b|dd}{c|}{}",1,2,3)).toBe("123{}");
|
||||
// 中文状态下true和false被转换成中文的"是"和"否"
|
||||
expect(t("{}{}{}",1,"2",true)).toBe("12是");
|
||||
expect(t("{|double}{}{}",1,"2",true)).toBe("22是");
|
||||
done()
|
||||
})
|
||||
|
||||
test("替换翻译内容的命名插值变量",done=>{
|
||||
expect(t("{a}{b}{c}",{a:11,b:22,c:33})).toBe("112233");
|
||||
expect(t("{a}{b}{c}{a}{b}{c}",{a:1,b:"2",c:3})).toBe("123123");
|
||||
done()
|
||||
})
|
||||
|
||||
test("命名插值变量使用格式化器",done=>{
|
||||
// 提供无效的格式化器,直接忽略
|
||||
expect(t("{a|x}{b|x|y}{c|}",{a:1,b:2,c:3})).toBe("123");
|
||||
expect(t("{a|x}{b|x|y}{c|double}",{a:1,b:2,c:3})).toBe("126");
|
||||
// padStart和trim格式化器只是字符串的原型方法,不需要额外定义可以直接使用
|
||||
expect(t("{a|padStart(10)}",{a:"123"})).toBe(" 123");
|
||||
expect(t("{a|padStart(10)|trim}",{a:"123"})).toBe("123");
|
||||
done()
|
||||
})
|
||||
|
||||
|
||||
test("命名插值变量使用格式化器",done=>{
|
||||
// 提供无效的格式化器,直接忽略
|
||||
expect(t("{a|x}{b|x|y}{c|}",{a:1,b:2,c:3})).toBe("123");
|
||||
expect(t("{a|x}{b|x|y}{c|double}",{a:1,b:2,c:3})).toBe("126");
|
||||
// 默认的字符串格式化器,不需要定义使用字符串方法
|
||||
expect(t("{a|x}{b|x|y}{c|double}",{a:1,b:2,c:3})).toBe("126");
|
||||
expect(t("{a|padStart(10)}",{a:"123"})).toBe(" 123");
|
||||
expect(t("{a|padStart(10)|trim}",{a:"123"})).toBe("123");
|
||||
done()
|
||||
})
|
||||
|
||||
|
||||
|
||||
test("切换到其他语言时的自动匹配同名格式化器",async ()=>{
|
||||
expect(t("{a}",{a:true})).toBe("是");
|
||||
expect(t("{name|book}是毛泽东思想的重要载体","毛泽东选集")).toBe("《毛泽东选集》是毛泽东思想的重要载体");
|
||||
await scope.change("en")
|
||||
expect(t("{a}",{a:false})).toBe("False");
|
||||
expect(t("{name|book}是毛泽东思想的重要载体","毛泽东选集")).toBe("<毛泽东选集>是毛泽东思想的重要载体");
|
||||
})
|
||||
|
||||
|
||||
test("位置插值翻译文本内容",async ()=>{
|
||||
const now = new Date()
|
||||
expect(t("你好")).toBe("你好");
|
||||
expect(t("现在是{ value | }",now)).toBe(`现在是${dayjs(now).format('YYYY/M/D HH:mm:ss')}`);
|
||||
|
||||
// 经babel自动码换后,文本内容会根据idMap自动转为id
|
||||
expect(t("1")).toBe("你好");
|
||||
expect(t("2",now)).toBe(`现在是${dayjs(now).format('YYYY/M/D HH:mm:ss')}`);
|
||||
|
||||
await scope.change("en")
|
||||
|
||||
expect(t("你好")).toBe("hello");
|
||||
expect(t("现在是{ value | }",now)).toBe(`Now is ${dayjs(now).format('YYYY/M/D HH:mm:ss')}`);
|
||||
expect(t("1")).toBe("hello");
|
||||
expect(t("2",now)).toBe(`Now is ${dayjs(now).format('YYYY/M/D HH:mm:ss')}`);
|
||||
})
|
||||
|
||||
test("命名插值翻译文本内容",async ()=>{
|
||||
const now = new Date()
|
||||
expect(t("你好")).toBe("你好");
|
||||
expect(t("现在是{ value | }",now)).toBe(`现在是${dayjs(now).format('YYYY/M/D HH:mm:ss')}`);
|
||||
|
||||
await scope.change("en")
|
||||
expect(t("你好")).toBe("hello");
|
||||
expect(t("现在是{ value | }",now)).toBe(`Now is ${dayjs(now).format('YYYY/M/D HH:mm:ss')}`);
|
||||
// 使用idMap
|
||||
expect(t("1")).toBe("hello");
|
||||
expect(t("2",now)).toBe(`Now is ${dayjs(now).format('YYYY/M/D HH:mm:ss')}`);
|
||||
})
|
||||
|
||||
|
||||
test("当没有对应的语言翻译时,保持原始输出",async ()=>{
|
||||
expect(t("我是中国人")).toBe("我是中国人");
|
||||
await scope.change("en")
|
||||
expect(t("我是中国人")).toBe("我是中国人");
|
||||
})
|
||||
|
||||
|
||||
test("切换到未知语言时回退到默认语言",async ()=>{
|
||||
expect(t("我是中国人")).toBe("我是中国人");
|
||||
expect(async ()=>await scope.change("xn")).rejects.toThrow(Error);
|
||||
expect(t("我是中国人")).toBe("我是中国人");
|
||||
})
|
||||
|
||||
|
||||
test("翻译复数支持",async ()=>{
|
||||
await scope.change("en")
|
||||
expect(t("我有{}个朋友",0)).toBe("I have no friends");
|
||||
expect(t("我有{}个朋友",1)).toBe("I have one friends");
|
||||
expect(t("我有{}个朋友",2)).toBe("I have two friends");
|
||||
expect(t("我有{}个朋友",3)).toBe("I have 3 friends");
|
||||
expect(t("我有{}个朋友",4)).toBe("I have 4 friends");
|
||||
})
|
||||
test("日期时间格式化器",async ()=>{
|
||||
|
||||
let zhTranslatedResults = zhDatetimes.map(v=>t(v,NOW))
|
||||
expect(zhTranslatedResults).toStrictEqual(expectZhDatetimes)
|
||||
await scope.change("en")
|
||||
let enTranslatedResults = zhDatetimes.map(v=>t(v,NOW))
|
||||
expect(enTranslatedResults).toStrictEqual(expectEnDatetimes)
|
||||
})
|
||||
|
||||
|
||||
test("货币格式化器",async ()=>{
|
||||
let zhMoneysResults = zhMoneys.map(v=>t(v,MONEY))
|
||||
expect(zhMoneysResults).toStrictEqual(expectZhMoneys)
|
||||
await scope.change("en")
|
||||
let enMoneysResults = enMoneys.map(v=>t(v,MONEY))
|
||||
expect(enMoneysResults).toStrictEqual(expectEnMoneys)
|
||||
})
|
||||
|
||||
})
|
@ -7,9 +7,9 @@ const { isNumber } = require('./utils')
|
||||
|
||||
const CN_DATETIME_UNITS = ["年","季度","月","周","日","小时","分钟","秒","毫秒","微秒"]
|
||||
const CN_WEEK_DAYS = ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"]
|
||||
const CN_SHORT_WEEK_DAYS =["日","一","二","三","四","五","六"]
|
||||
const CN_SHORT_WEEK_DAYS =["周日","周一","周二","周三","周四","周五","周六"]
|
||||
const CN_MONTH_NAMES= ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"]
|
||||
const CN_SHORT_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 = ['', '十', '百', '千', '万', '十', '百', '千', '亿', '十', '百', '千', '兆', '十', '百', '千', '京', '十', '百', '千', '垓']
|
||||
|
@ -83,6 +83,8 @@ empty.paramCount = 2
|
||||
{ value | error('ERROR:{ error}',) } == 显示error.constructor.name
|
||||
|
||||
|
||||
|
||||
|
||||
* @param {*} value
|
||||
* @param {*} escapeValue
|
||||
* @param {*} next 下一步的行为,取值,break,ignore
|
||||
|
@ -3,118 +3,221 @@
|
||||
*
|
||||
*/
|
||||
|
||||
const { toDate,toCurrency,toNumber,isPlainObject,formatDatetime,formatTime } = require("../utils")
|
||||
const { toDate,toCurrency,toNumber,isFunction,isPlainObject,formatDatetime,formatTime } = require("../utils")
|
||||
const { Formatter } = require("../formatter")
|
||||
|
||||
|
||||
/**
|
||||
* 该类型的格式化器具有以下特点:
|
||||
*
|
||||
* 1. 接受一个format参数,
|
||||
* 2. format参数取值可以是若干预设的值,如long,short等,也可能是一个模板字符串
|
||||
* 3. 当format值时,如果定义在$config[configKey]里面,代表了$config[configKey][format]是一个模板字符串
|
||||
* 4. 如果!(format in $config[configKey]),则代表format值是一个模板字符串
|
||||
* 5. 如果format in presets, 则要求presets[format ]是一个(value)=>{....},直接返回
|
||||
*
|
||||
**/
|
||||
function createDateTimeFormatter(options={},transformer){
|
||||
let opts = Object.assign({presets:{}},options)
|
||||
return Formatter((value,format,$config)=>{
|
||||
if((format in opts.presets) && isFunction(opts.presets[format])){
|
||||
return opts.presets[format](value)
|
||||
}else if((format in $config)){
|
||||
format = $config[format]
|
||||
}else if(format == "number"){
|
||||
return value
|
||||
}
|
||||
try{
|
||||
return format==null ? value : transformer(value,format)
|
||||
}catch(e){
|
||||
return value
|
||||
}
|
||||
},opts)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 日期格式化器
|
||||
* format取值:
|
||||
* 0-local,1-long,2-short,3-iso,4-gmt,5-UTC
|
||||
* 或者日期模板字符串
|
||||
* 默认值是local
|
||||
* - format取值:local,long,short,iso,gmt,utc,<模板字符串>
|
||||
* - 默认值由$config.datetime.date.format指定
|
||||
*/
|
||||
const dateFormatter = Formatter((value,format,$config)=>{
|
||||
const optionals = ["local","long","short","iso","gmt","utc"]
|
||||
// 处理参数:同时支持大小写名称和数字
|
||||
const optionIndex = optionals.findIndex((v,i)=>{
|
||||
if(typeof(format)=="string"){
|
||||
return v==format || v== format.toUpperCase()
|
||||
}else if(typeof(format)=="number"){
|
||||
return format === i
|
||||
}
|
||||
})
|
||||
switch(optionIndex){
|
||||
case 0: // local
|
||||
return value.toLocaleString()
|
||||
case 1: // long
|
||||
return formatDatetime(value,$config.long)
|
||||
case 2: // short
|
||||
return formatDatetime(value,$config.short)
|
||||
case 3: // ISO
|
||||
return value.toISOString()
|
||||
case 4: // GMT
|
||||
return value.toGMTString()
|
||||
case 5: // UTC
|
||||
return value.toUTCString()
|
||||
default:
|
||||
return formatDatetime(value,format)
|
||||
}
|
||||
},{
|
||||
normalize: toDate, // 转换输入为Date类型
|
||||
params : ['format'],
|
||||
configKey: "datetime.date"
|
||||
})
|
||||
// 季度格式化器 format= 0=短格式 1=长格式 1=数字
|
||||
const quarterFormatter = Formatter((value,format,$config)=>{
|
||||
const month = value.getMonth() + 1
|
||||
const quarter = Math.floor( ( month % 3 == 0 ? ( month / 3 ) : (month / 3 + 1 ) ))
|
||||
if(typeof(format)==='string'){
|
||||
format = ['short','long','number'].indexOf(format)
|
||||
const dateFormatter = createDateTimeFormatter({
|
||||
normalize: toDate,
|
||||
params : ["format"],
|
||||
configKey: "datetime.date",
|
||||
presets : {
|
||||
local: value=>value.toLocaleString(),
|
||||
iso : value=>value.toISOString(),
|
||||
utc : value=>value.toUTCString(),
|
||||
gmt : value=>value.toGMTString()
|
||||
}
|
||||
if(format<0 && format>2) format = 0
|
||||
return format==0 ? $config.short[quarter] : (format==1 ? $config.long[quarter] : quarter)
|
||||
},{
|
||||
normalize: toDate,
|
||||
params : ['format'],
|
||||
},formatDatetime)
|
||||
|
||||
|
||||
/**
|
||||
* 季度格式化器
|
||||
* - format: long,short,number
|
||||
* - 默认值是 short
|
||||
*/
|
||||
const quarterFormatter = createDateTimeFormatter({
|
||||
normalize : value=>{
|
||||
const month = value.getMonth() + 1
|
||||
return Math.floor( ( month % 3 == 0 ? ( month / 3 ) : (month / 3 + 1 ) ))
|
||||
},
|
||||
params : ["format"],
|
||||
configKey: "datetime.quarter"
|
||||
})
|
||||
},(quarter,format)=>format[quarter-1])
|
||||
|
||||
// 月份格式化器 format可以取值0,1,2,也可以取字符串long,short,number
|
||||
const monthFormatter = Formatter((value,format,$config)=>{
|
||||
const month = value.getMonth()
|
||||
if(typeof(format)==='string'){
|
||||
format = ['long','short','number'].indexOf(format)
|
||||
}
|
||||
if(format<0 && format>2) format = 0
|
||||
return format==0 ? $config.long[month] : (format==1 ? $config.short[month] : month+1)
|
||||
},{
|
||||
normalize: toDate,
|
||||
params : ['format'],
|
||||
/**
|
||||
* 月份格式化器
|
||||
* - format: long,short,number
|
||||
* - 默认值是 short
|
||||
*/
|
||||
const monthFormatter = createDateTimeFormatter({
|
||||
normalize: value=> value.getMonth() + 1,
|
||||
params : ["format"],
|
||||
configKey: "datetime.month"
|
||||
})
|
||||
},(month,format)=>format[month-1])
|
||||
|
||||
// 星期x格式化器 format可以取值0,1,2,也可以取字符串long,short,number
|
||||
const weekdayFormatter = Formatter((value,format,$config)=>{
|
||||
const day = value.getDay()
|
||||
if(typeof(format)==='string'){
|
||||
format = ['long','short','number'].indexOf(format)
|
||||
}
|
||||
if(format<0 && format>2) format = 0
|
||||
return format==0 ? $config.long[day] : (format==1 ? $config.short[day] : day)
|
||||
},{
|
||||
normalize: toDate,
|
||||
params : ['format'],
|
||||
/**
|
||||
* 周格式化器
|
||||
* - format: long,short,number
|
||||
* - 默认值是 long
|
||||
*/
|
||||
const weekdayFormatter = createDateTimeFormatter({
|
||||
normalize: value=> value.getDay(),
|
||||
params : ["format"],
|
||||
configKey: "datetime.weekday"
|
||||
})
|
||||
},(day,format)=>format[day])
|
||||
|
||||
/**
|
||||
* 时间格式化器
|
||||
* - format取值:local,long,short,timestamp,<模板字符串>
|
||||
* - 默认值由$config.datetime.time.format指定
|
||||
*/
|
||||
const timeFormatter = createDateTimeFormatter({
|
||||
normalize : toDate,
|
||||
params : ["format"],
|
||||
configKey : "datetime.time",
|
||||
presets : {
|
||||
local : value=>value.toLocaleTimeString(),
|
||||
timestamp: value=>value.getTime()
|
||||
}
|
||||
},formatTime)
|
||||
|
||||
|
||||
// 时间格式化器 format可以取值0-local(默认),1-long,2-short,3-timestamp,也可以是一个插值表达式
|
||||
const timeFormatter = Formatter((value,format,$config)=>{
|
||||
const optionals = ['local','long','short','timestamp']
|
||||
const optionIndex = optionals.findIndex((v,i)=>{
|
||||
if(typeof(format)=="string"){
|
||||
return v==format || v== format.toUpperCase()
|
||||
}else if(typeof(format)=="number"){
|
||||
return format === i
|
||||
}
|
||||
})
|
||||
switch(optionIndex){
|
||||
case 0: // local : toLocaleTimeString
|
||||
return value.toLocaleTimeString()
|
||||
case 1: // long
|
||||
return formatTime(value,$config.long)
|
||||
case 2: // short
|
||||
return formatTime(value,$config.short)
|
||||
case 3: // timestamp
|
||||
return value.getTime()
|
||||
default:
|
||||
return formatTime(value,format)
|
||||
}
|
||||
},{
|
||||
normalize: toDate,
|
||||
params : ['format'],
|
||||
configKey: "datetime.time"
|
||||
})
|
||||
// const dateFormatter = Formatter((value,format,$config)=>{
|
||||
// const optionals = ["local","long","short","iso","gmt","utc"]
|
||||
// // 处理参数:同时支持大小写名称和数字
|
||||
// const optionIndex = optionals.findIndex((v,i)=>{
|
||||
// if(typeof(format)=="string"){
|
||||
// return v==format || v== format.toUpperCase()
|
||||
// }else if(typeof(format)=="number"){
|
||||
// return format === i
|
||||
// }
|
||||
// })
|
||||
// // format名称不是optionals中的一个,并且被配置在$config,则视为扩展预设值
|
||||
// if(optionIndex==-1 && typeof(format)=="string" && (format in $config)){
|
||||
// format = $config[format]
|
||||
// }
|
||||
|
||||
// switch(optionIndex){
|
||||
// case 0: // local
|
||||
// return value.toLocaleString()
|
||||
// case 1: // long
|
||||
// return formatDatetime(value,$config.long)
|
||||
// case 2: // short
|
||||
// return formatDatetime(value,$config.short)
|
||||
// case 3: // ISO
|
||||
// return value.toISOString()
|
||||
// case 4: // GMT
|
||||
// return value.toGMTString()
|
||||
// case 5: // UTC
|
||||
// return value.toUTCString()
|
||||
// default:
|
||||
// return formatDatetime(value,format)
|
||||
// }
|
||||
// },{
|
||||
// normalize: toDate, // 转换输入为Date类型
|
||||
// params : ['format'],
|
||||
// configKey: "datetime.date"
|
||||
// })
|
||||
// // 季度格式化器 format= 0=短格式 1=长格式 1=数字
|
||||
// const quarterFormatter = Formatter((value,format,$config)=>{
|
||||
// const month = value.getMonth() + 1
|
||||
// const quarter = Math.floor( ( month % 3 == 0 ? ( month / 3 ) : (month / 3 + 1 ) ))
|
||||
// if(typeof(format)==='string'){
|
||||
// format = ['short','long','number'].indexOf(format)
|
||||
// }
|
||||
// if(format<0 && format>2) format = 0
|
||||
// return format==0 ? $config.short[quarter] : (format==1 ? $config.long[quarter] : quarter)
|
||||
// },{
|
||||
// normalize: toDate,
|
||||
// params : ['format'],
|
||||
// configKey: "datetime.quarter"
|
||||
// })
|
||||
|
||||
// // 月份格式化器 format可以取值0,1,2,也可以取字符串long,short,number
|
||||
// const monthFormatter = Formatter((value,format,$config)=>{
|
||||
// const month = value.getMonth()
|
||||
// if(typeof(format)==='string'){
|
||||
// format = ['long','short','number'].indexOf(format)
|
||||
// }
|
||||
// if(format<0 && format>2) format = 0
|
||||
// return format==0 ? $config.long[month] : (format==1 ? $config.short[month] : month+1)
|
||||
// },{
|
||||
// normalize: toDate,
|
||||
// params : ['format'],
|
||||
// configKey: "datetime.month"
|
||||
// })
|
||||
|
||||
// // 星期x格式化器 format可以取值0,1,2,也可以取字符串long,short,number
|
||||
// const weekdayFormatter = Formatter((value,format,$config)=>{
|
||||
// const day = value.getDay()
|
||||
// if(typeof(format)==='string'){
|
||||
// format = ['long','short','number'].indexOf(format)
|
||||
// }
|
||||
// if(format<0 && format>2) format = 0
|
||||
// return format==0 ? $config.long[day] : (format==1 ? $config.short[day] : day)
|
||||
// },{
|
||||
// normalize: toDate,
|
||||
// params : ['format'],
|
||||
// configKey: "datetime.weekday"
|
||||
// })
|
||||
|
||||
|
||||
// // 时间格式化器 format可以取值0-local(默认),1-long,2-short,3-timestamp,也可以是一个插值表达式
|
||||
// const timeFormatter = Formatter((value,format,$config)=>{
|
||||
// const optionals = ['local','long','short','timestamp']
|
||||
// const optionIndex = optionals.findIndex((v,i)=>{
|
||||
// if(typeof(format)=="string"){
|
||||
// return v==format || v== format.toUpperCase()
|
||||
// }else if(typeof(format)=="number"){
|
||||
// return format === i
|
||||
// }
|
||||
// })
|
||||
// // format名称不是optionals中的一个,并且被配置在$config,则视为扩展预设值
|
||||
// if(optionIndex==-1 && typeof(format)=="string" && (format in $config)){
|
||||
// format = $config[format]
|
||||
// }
|
||||
|
||||
// switch(optionIndex){
|
||||
// case 0: // local : toLocaleTimeString
|
||||
// return value.toLocaleTimeString()
|
||||
// case 1: // long
|
||||
// return formatTime(value,$config.long)
|
||||
// case 2: // short
|
||||
// return formatTime(value,$config.short)
|
||||
// case 3: // timestamp
|
||||
// return value.getTime()
|
||||
// default:
|
||||
// return formatTime(value,format)
|
||||
// }
|
||||
// },{
|
||||
// normalize: toDate,
|
||||
// params : ['format'],
|
||||
// configKey: "datetime.time"
|
||||
// })
|
||||
|
||||
// 货币格式化器, CNY $13,456.00
|
||||
/**
|
||||
@ -175,7 +278,6 @@ const currencyFormatter = Formatter((value,...args) =>{
|
||||
})
|
||||
|
||||
|
||||
|
||||
module.exports = {
|
||||
// 配置参数
|
||||
$config:{
|
||||
@ -194,18 +296,23 @@ module.exports = {
|
||||
month:{
|
||||
long : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
|
||||
short : ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"],
|
||||
format : 0 // 0-长名称,1-短名称,2-数字
|
||||
format : "long" // 0-长名称,1-短名称,2-数字
|
||||
},
|
||||
weekday:{
|
||||
long : ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
|
||||
short : ["Sun", "Mon", "Tues", "Wed", "Thur", "Fri", "Sat"],
|
||||
format : 0, // 0-长名称,1-短名称,2-数字
|
||||
format : "long", // 0-长名称,1-短名称,2-数字
|
||||
},
|
||||
time : {
|
||||
long : "HH:mm:ss",
|
||||
short : "HH:mm:ss",
|
||||
format : 'local'
|
||||
},
|
||||
},
|
||||
timeslots : {
|
||||
slots : [12],
|
||||
lowercase : ["AM","PM"]
|
||||
uppercase : ["AM","PM"]
|
||||
}
|
||||
},
|
||||
currency : {
|
||||
default : "{symbol}{value}{unit}",
|
||||
@ -254,19 +361,12 @@ module.exports = {
|
||||
// 以下是格式化定义
|
||||
// ******************* 日期 *******************
|
||||
date : dateFormatter,
|
||||
time : timeFormatter,
|
||||
year : value => toDate(value).getFullYear(),
|
||||
quarter : quarterFormatter,
|
||||
month : monthFormatter,
|
||||
weekday : weekdayFormatter,
|
||||
day : value => toDate(value).getDate(),
|
||||
// ******************* 时间 *******************
|
||||
hour : value => toDate(value).getHours(),
|
||||
hour12 : value => {const hour = toDate(value).getHours(); return hour > 12 ? hour - 12 : thour},
|
||||
minute : value => toDate(value).getMinutes(),
|
||||
second : value => toDate(value).getSeconds(),
|
||||
millisecond : value => toDate(value).getMilliseconds(),
|
||||
timestamp : value => toDate(value).getTime(),
|
||||
time : timeFormatter,
|
||||
// ******************* 货币 *******************
|
||||
currency : currencyFormatter,
|
||||
// 数字,如,使用分割符
|
||||
|
@ -22,19 +22,23 @@ module.exports = {
|
||||
format : "short" // 0-短格式,1-长格式,2-数字
|
||||
},
|
||||
month:{
|
||||
long : CN_MONTH_NAMES,
|
||||
long : CN_MONTH_NAMES,
|
||||
short : CN_SHORT_MONTH_NAMES,
|
||||
format : 0, // 0-长名称,1-短名称,2-数字
|
||||
format : "long", // 0-长名称,1-短名称,2-数字
|
||||
},
|
||||
weekday:{
|
||||
short : CN_WEEK_DAYS,
|
||||
long : CN_SHORT_WEEK_DAYS,
|
||||
format : 0, // 0-长名称,1-短名称,2-数字
|
||||
long : CN_WEEK_DAYS,
|
||||
short : CN_SHORT_WEEK_DAYS,
|
||||
format : "long", // 0-长名称,1-短名称,2-数字
|
||||
},
|
||||
time:{
|
||||
long : "HH点mm分ss秒",
|
||||
short : "HH:mm:ss",
|
||||
format : 'local'
|
||||
},
|
||||
timeslots : {
|
||||
slots : [6,9,11,13,18],
|
||||
long : ["凌晨","早上","上午","中午","下午","晚上"]
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
const {getDataTypeName,isNumber,isPlainObject,isFunction,isNothing,deepMerge,deepMixin} = require("./utils")
|
||||
const {DataTypes,getDataTypeName,isNumber,isPlainObject,isFunction,isNothing,deepMerge,deepMixin} = require("./utils")
|
||||
const {getInterpolatedVars,replaceInterpolatedVars} = require("./interpolate")
|
||||
const {createFormatter,Formatter} = require("./formatter")
|
||||
const EventEmitter = require("./eventemitter")
|
||||
@ -7,8 +7,6 @@ const i18nScope = require("./scope")
|
||||
const { translate } = require("./translate")
|
||||
|
||||
|
||||
const DataTypes = ["String","Number","Boolean","Object","Array","Function","Error","Symbol","RegExp","Date","Null","Undefined","Set","Map","WeakSet","WeakMap"]
|
||||
|
||||
// 默认语言配置
|
||||
const defaultLanguageSettings = {
|
||||
debug : true,
|
||||
|
@ -1,19 +1,4 @@
|
||||
const { isPlainObject, isFunction, getByPath, deepMixin,deepClone } = require("./utils");
|
||||
|
||||
const DataTypes = [
|
||||
"String",
|
||||
"Number",
|
||||
"Boolean",
|
||||
"Object",
|
||||
"Array",
|
||||
"Function",
|
||||
"Null",
|
||||
"Undefined",
|
||||
"Symbol",
|
||||
"Date",
|
||||
"RegExp",
|
||||
"Error",
|
||||
];
|
||||
const { DataTypes,isPlainObject, isFunction, getByPath, deepMixin,deepClone } = require("./utils");
|
||||
|
||||
module.exports = class i18nScope {
|
||||
constructor(options = {}, callback) {
|
||||
|
@ -128,7 +128,7 @@ function toDate(value) {
|
||||
try {
|
||||
return value instanceof Date ? value : new Date(value)
|
||||
} catch {
|
||||
return value
|
||||
return parseInt(value)
|
||||
}
|
||||
}
|
||||
/**
|
||||
@ -281,10 +281,10 @@ function formatDatetime(value,templ="YYYY/MM/DD HH:mm:ss"){
|
||||
["M", month], // 1-12 月,从1开始
|
||||
["DD", day.padStart(2, "0")], // 01-31 日,两位数
|
||||
["D", day], // 1-31 日
|
||||
["HH", hour.padStart(2, "0")], // 00-23 24小时,两位数
|
||||
["H", hour], // 0-23 24小时
|
||||
["HH", hour.padStart(2, "0")], // 00-23 24小时,两位数
|
||||
["H", hour], // 0-23 24小时
|
||||
["hh", String(hourNum > 12 ? hourNum - 12 : hourNum).padStart(2, "0")], // 01-12 12小时,两位数
|
||||
["h", String(hourNum > 12 ? hourNum - 12 : hourNum)], // 1-12 12小时
|
||||
["h", String(hourNum > 12 ? hourNum - 12 : hourNum)], // 1-12 12小时
|
||||
["mm", minute.padStart(2, "0")], // 00-59 分钟,两位数
|
||||
["m", minute], // 0-59 分钟
|
||||
["ss", second.padStart(2, "0")], // 00-59 秒,两位数
|
||||
@ -304,8 +304,8 @@ function formatTime(value,templ="HH:mm:ss"){
|
||||
const hour = String(hourNum),minute = String(v.getMinutes()),second = String(v.getSeconds()),millisecond=String(v.getMilliseconds())
|
||||
let result = templ
|
||||
const vars = [
|
||||
["HH", hour.padStart(2, "0")], // 00-23 24小时,两位数
|
||||
["H", hour], // 0-23 24小时
|
||||
["HH", hour.padStart(2, "0")], // 00-23 24小时,两位数
|
||||
["H", hour], // 0-23 24小时
|
||||
["hh", String(hour > 12 ? hour - 12 : hour).padStart(2, "0")], // 01-12 12小时,两位数
|
||||
["h", String(hour > 12 ? hour - 12 : hour)], // 1-12 12小时
|
||||
["mm", minute.padStart(2, "0")], // 00-59 分钟,两位数
|
||||
@ -322,21 +322,16 @@ function formatTime(value,templ="HH:mm:ss"){
|
||||
/**
|
||||
* 替换所有字符串
|
||||
* 低版本ES未提供replaceAll,此函数用来替代
|
||||
*
|
||||
*
|
||||
* @param {*} str
|
||||
* @param {*} findValue
|
||||
* @param {*} replaceValue
|
||||
*/
|
||||
function replaceAll(str,findValue,replaceValue){
|
||||
if(typeof(str)!=="string" || findValue=="" || findValue==replaceValue) return str
|
||||
let result = str
|
||||
try{
|
||||
while(result.includes(findValue)){
|
||||
result = result.replace(findValue,replaceValue)
|
||||
}
|
||||
return str.replace(new RegExp(escapeRegexpStr(findValue),"g"),replaceValue)
|
||||
}catch{}
|
||||
return result
|
||||
return str
|
||||
}
|
||||
/**
|
||||
* 使用正则表达式解析非标JOSN
|
||||
@ -387,8 +382,10 @@ function safeParseJson(str){
|
||||
}
|
||||
return JSON.parse(str)
|
||||
}
|
||||
const DataTypes = ["String","Number","Boolean","Object","Array","Function","Error","Symbol","RegExp","Date","Null","Undefined","Set","Map","WeakSet","WeakMap"]
|
||||
|
||||
module.exports ={
|
||||
DataTypes,
|
||||
isPlainObject,
|
||||
isFunction,
|
||||
isNumber,
|
||||
|
2
pnpm-lock.yaml
generated
2
pnpm-lock.yaml
generated
@ -13,7 +13,7 @@ importers:
|
||||
cross-env: ^7.0.3
|
||||
dayjs: ^1.11.0
|
||||
deepmerge: ^4.2.2
|
||||
dumi: ^1.0.13
|
||||
dumi: ^1.1.47
|
||||
fs-extra: ^10.0.1
|
||||
gulp: ^4.0.2
|
||||
inquirer: ^8.2.2
|
||||
|
@ -34,12 +34,6 @@ const zhDatetimes =[
|
||||
"现在是{ value | date('iso') }",
|
||||
"现在是{ value | date('gmt') }",
|
||||
"现在是{ value | date('utc') }",
|
||||
"现在是{ value | date(0) }", // local
|
||||
"现在是{ value | date(1) }", // long
|
||||
"现在是{ value | date(2) }", // short
|
||||
"现在是{ value | date(3) }", // iso
|
||||
"现在是{ value | date(4) }", // gmt
|
||||
"现在是{ value | date(5) }", // utc
|
||||
"现在是{ value | date('YYYY-MM-DD HH:mm:ss')}",
|
||||
"现在是{ value | date('YYYY-MM-DD')}",
|
||||
"现在是{ value | date('HH:mm:ss')}",
|
||||
@ -47,26 +41,21 @@ const zhDatetimes =[
|
||||
"现在是{ value | month('long')}",
|
||||
"现在是{ value | month('short')}",
|
||||
"现在是{ value | month('number')}",
|
||||
"现在是{ value | month(0)}",
|
||||
"现在是{ value | month(1)}",
|
||||
"现在是{ value | month(2)}",
|
||||
"现在是{ value | weekday }",
|
||||
"现在是{ value | weekday('long')}",
|
||||
"现在是{ value | weekday('short')}",
|
||||
"现在是{ value | weekday('number')}",
|
||||
"现在是{ value | weekday(0)}",
|
||||
"现在是{ value | weekday(1)}",
|
||||
"现在是{ value | weekday(2)}",
|
||||
"现在是{ value | quarter }",
|
||||
"现在是{ value | quarter('long')}",
|
||||
"现在是{ value | quarter('short')}",
|
||||
"现在是{ value | quarter('number')}",
|
||||
|
||||
// 时间
|
||||
"现在时间 - { value | time }",
|
||||
"现在时间 - { value | time('local') }",
|
||||
"现在时间 - { value | time('long') }",
|
||||
"现在时间 - { value | time('short') }",
|
||||
"现在时间 - { value | time('timestamp') }",
|
||||
"现在时间 - { value | time(0) }",
|
||||
"现在时间 - { value | time(1) }",
|
||||
"现在时间 - { value | time(2) }",
|
||||
"现在时间 - { value | time(3) }",
|
||||
"现在时间 - { value | time('HH:mm:ss') }",
|
||||
"现在时间 - { value | time('mm:ss') }",
|
||||
"现在时间 - { value | time('ss') }"
|
||||
@ -82,39 +71,28 @@ const expectZhDatetimes =[
|
||||
`现在是${NOW.toISOString()}`, // { value | date('iso') }
|
||||
`现在是${NOW.toGMTString()}`, // { value | date('gmt') }
|
||||
`现在是${NOW.toUTCString()}`, // { value | date('utc') }
|
||||
`现在是${NOW.toLocaleString()}`, // { value | date(0) } // local
|
||||
"现在是2022年08月12日 10点12分36秒", // { value | date(1) } // long
|
||||
"现在是2022/08/12", // { value | date(2) } // short
|
||||
`现在是${NOW.toISOString()}`, // { value | date(3) } // iso
|
||||
`现在是${NOW.toGMTString()}`, // { value | date(4) } // gmt
|
||||
`现在是${NOW.toUTCString()}`, // { value | date(5) } // utc
|
||||
"现在是2022-08-12 10:12:36", // { value | date('YYYY-MM-DD HH:mm:ss')}
|
||||
"现在是2022-08-12", // { value | date('YYYY-MM-DD')}
|
||||
"现在是10:12:36", // { value | date('HH:mm:ss')}
|
||||
"现在是八月", // { value | month }
|
||||
"现在是八月", // { value | month('long')}
|
||||
"现在是八", // { value | month('short')}
|
||||
"现在是8月", // { value | month('short')}
|
||||
"现在是8", // { value | month('number')}
|
||||
"现在是八月", // { value | month(0)}
|
||||
"现在是八", // { value | month(1)}
|
||||
"现在是8", // { value | month(2)}
|
||||
"现在是星期五", // { value | weekday }
|
||||
"现在是星期五", // { value | weekday('long')}
|
||||
"现在是五", // { value | weekday('short')}
|
||||
"现在是周五", // { value | weekday('short')}
|
||||
"现在是5", // { value | weekday('number')}
|
||||
"现在是星期五", // { value | weekday(0)}
|
||||
"现在是五", // { value | weekday(1)}
|
||||
"现在是5", // { value | weekday(2)}
|
||||
"现在是Q3", // { value | quarter }
|
||||
"现在是三季度", // { value | quarter('long')}
|
||||
"现在是Q3", // { value | quarter('short')}
|
||||
"现在是3", // { value | quarter('number')}
|
||||
|
||||
// 时间
|
||||
`现在时间 - ${NOW.toLocaleTimeString()}`, // { value | time }
|
||||
`现在时间 - ${NOW.toLocaleTimeString()}`, // { value | time('local') }
|
||||
"现在时间 - 10点12分36秒", // { value | time('long') }
|
||||
"现在时间 - 10:12:36", // { value | time('short') }
|
||||
"现在时间 - 1660270356000", // { value | time('timestamp') }
|
||||
`现在时间 - ${NOW.toLocaleTimeString()}`, // { value | time(0) }
|
||||
"现在时间 - 10点12分36秒", // { value | time(1) }
|
||||
"现在时间 - 10:12:36", // { value | time(2) }
|
||||
"现在时间 - 1660270356000", // { value | time(3) }
|
||||
"现在时间 - 10:12:36", // { value | time('HH:mm:ss') }
|
||||
"现在时间 - 12:36", // { value | time('mm:ss') }
|
||||
"现在时间 - 36", // { value | time('ss') }"
|
||||
@ -130,12 +108,6 @@ const enDatetimes =[
|
||||
"Now is { value | date('iso') }",
|
||||
"Now is { value | date('gmt') }",
|
||||
"Now is { value | date('utc') }",
|
||||
"Now is { value | date(0) }", // local
|
||||
"Now is { value | date(1) }", // long
|
||||
"Now is { value | date(2) }", // short
|
||||
"Now is { value | date(3) }", // iso
|
||||
"Now is { value | date(4) }", // gmt
|
||||
"Now is { value | date(5) }", // utc
|
||||
"Now is { value | date('YYYY-MM-DD HH:mm:ss')}",
|
||||
"Now is { value | date('YYYY-MM-DD')}",
|
||||
"Now is { value | date('HH:mm:ss')}",
|
||||
@ -143,26 +115,20 @@ const enDatetimes =[
|
||||
"Now is { value | month('long')}",
|
||||
"Now is { value | month('short')}",
|
||||
"Now is { value | month('number')}",
|
||||
"Now is { value | month(0)}",
|
||||
"Now is { value | month(1)}",
|
||||
"Now is { value | month(2)}",
|
||||
"Now is { value | weekday }",
|
||||
"Now is { value | weekday('long')}",
|
||||
"Now is { value | weekday('short')}",
|
||||
"Now is { value | weekday('number')}",
|
||||
"Now is { value | weekday(0)}",
|
||||
"Now is { value | weekday(1)}",
|
||||
"Now is { value | weekday(2)}",
|
||||
"Now is { value | quarter }",
|
||||
"Now is { value | quarter('long')}",
|
||||
"Now is { value | quarter('short')}",
|
||||
"Now is { value | quarter('number')}",
|
||||
// 时间
|
||||
"Now time: { value | time }",
|
||||
"Now time: { value | time('local') }",
|
||||
"Now time: { value | time('long') }",
|
||||
"Now time: { value | time('short') }",
|
||||
"Now time: { value | time('timestamp') }",
|
||||
"Now time: { value | time(0) }",
|
||||
"Now time: { value | time(1) }",
|
||||
"Now time: { value | time(2) }",
|
||||
"Now time: { value | time(3) }",
|
||||
"Now time: { value | time('HH:mm:ss') }",
|
||||
"Now time: { value | time('mm:ss') }",
|
||||
"Now time: { value | time('ss') }"
|
||||
@ -177,12 +143,6 @@ const expectEnDatetimes =[
|
||||
`Now is ${NOW.toISOString()}`, // { value | date('iso') }
|
||||
`Now is ${NOW.toGMTString()}`, // { value | date('gmt') }
|
||||
`Now is ${NOW.toUTCString()}`, // { value | date('utc') }
|
||||
`Now is ${NOW.toLocaleString()}`, // { value | date(0) } // local
|
||||
"Now is 2022/08/12 10:12:36", // { value | date(1) } // long
|
||||
"Now is 2022/08/12", // { value | date(2) } // short
|
||||
`Now is ${NOW.toISOString()}`, // { value | date(3) } // iso
|
||||
`Now is ${NOW.toGMTString()}`, // { value | date(4) } // gmt
|
||||
`Now is ${NOW.toUTCString()}`, // { value | date(5) } // utc
|
||||
"Now is 2022-08-12 10:12:36", // { value | date('YYYY-MM-DD HH:mm:ss')}
|
||||
"Now is 2022-08-12", // { value | date('YYYY-MM-DD')}
|
||||
"Now is 10:12:36", // { value | date('HH:mm:ss')}
|
||||
@ -190,26 +150,22 @@ const expectEnDatetimes =[
|
||||
"Now is August", // { value | month('long')}
|
||||
"Now is Aug", // { value | month('short')}
|
||||
"Now is 8", // { value | month('number')}
|
||||
"Now is August", // { value | month(0)}
|
||||
"Now is Aug", // { value | month(1)}
|
||||
"Now is 8", // { value | month(2)}
|
||||
"Now is Friday", // { value | weekday }
|
||||
"Now is Friday", // { value | weekday('long')}
|
||||
"Now is Fri", // { value | weekday('short')}
|
||||
"Now is 5", // { value | weekday('number')}
|
||||
"Now is Friday", // { value | weekday(0)}
|
||||
"Now is Fri", // { value | weekday(1)}
|
||||
"Now is 5", // { value | weekday(2)}
|
||||
"Now is Q3", // { value | quarter }
|
||||
"Now is Third Quarter", // { value | quarter('long')}
|
||||
"Now is Q3", // { value | quarter('short')}
|
||||
"Now is 3", // { value | quarter('number')}
|
||||
|
||||
|
||||
// 时间
|
||||
`Now time: ${NOW.toLocaleTimeString()}`, // { value | time }
|
||||
`Now time: ${NOW.toLocaleTimeString()}`, // { value | time('local') }
|
||||
"Now time: 10:12:36", // { value | time('long') }
|
||||
"Now time: 10:12:36", // { value | time('short') }
|
||||
"Now time: 1660270356000", // { value | time('timestamp') }
|
||||
`Now time: ${NOW.toLocaleTimeString()}`, // { value | time(0) }
|
||||
"Now time: 10:12:36", // { value | time(1) }
|
||||
"Now time: 10:12:36", // { value | time(2) }
|
||||
"Now time: 1660270356000", // { value | time(3) }
|
||||
"Now time: 10:12:36", // { value | time('HH:mm:ss') }
|
||||
"Now time: 12:36", // { value | time('mm:ss') }
|
||||
"Now time: 36", // { value | time('ss') }"
|
||||
@ -393,7 +349,6 @@ test("获取翻译内容中的插值变量",done=>{
|
||||
expect(results[0].formatters[2].name).toEqual("rel");
|
||||
expect(results[0].formatters[2].args).toEqual([]);
|
||||
|
||||
|
||||
expect(results[1].name).toEqual("city");
|
||||
expect(results[1].formatters.length).toEqual(0);
|
||||
|
||||
@ -526,8 +481,7 @@ test("翻译复数支持",async ()=>{
|
||||
expect(t("我有{}个朋友",3)).toBe("I have 3 friends");
|
||||
expect(t("我有{}个朋友",4)).toBe("I have 4 friends");
|
||||
})
|
||||
test("日期时间格式化器",async ()=>{
|
||||
|
||||
test("日期时间格式化器",async ()=>{
|
||||
let zhTranslatedResults = zhDatetimes.map(v=>t(v,NOW))
|
||||
expect(zhTranslatedResults).toStrictEqual(expectZhDatetimes)
|
||||
await scope.change("en")
|
||||
|
Loading…
x
Reference in New Issue
Block a user