国际化相对时间格式化API:Intl.RelativeTimeFormat
原文:The Intl.RelativeTimeFormat API
作者:Mathias Bynens(@mathias)
现代 Web 应用程序通常使用“昨天”,“42秒前”或“3个月”之类的短语,而不是完整的日期和时间戳。这种相对时间格式已经变得非常普遍,以至于几个流行的库都实现了本地化格式化的函数。(例如 Moment.js,Globalize 和 date-fns。)
实现本地化相对时间格式化的一个问题是,您需要为每种语言提供习惯词或短语列表(例如“昨天”或“上一季度”)。Unicode CLDR 提供了此数据,但要在 JavaScript 中使用它,必须将其嵌入到库代码中一起提供。遗憾的是,这无疑会增加这些库的包大小,这会影响到脚本的加载时间、解析/编译成本和内存消耗。
全新的 Intl.RelativeTimeFormat
API 将此负担转移到了 JavaScript 引擎,JavaScript 引擎可以提供语言环境数据并使其直接供 JavaScript 开发人员使用。 Intl.RelativeTimeFormat
在不牺牲性能的情况下实现相对时间的本地化格式化。
用法与示例
以下示例展示了如何使用英语创建相对时间格式化程序。
const rtf = new Intl.RelativeTimeFormat('en');
rtf.format(3.14, 'second');
// → 'in 3.14 seconds'
rtf.format(-15, 'minute');
// → '15 minutes ago'
rtf.format(8, 'hour');
// → 'in 8 hours'
rtf.format(-2, 'day');
// → '2 days ago'
rtf.format(3, 'week');
// → 'in 3 weeks'
rtf.format(-5, 'month');
// → '5 months ago'
rtf.format(2, 'quarter');
// → 'in 2 quarters'
rtf.format(-42, 'year');
// → '42 years ago'
需要注意的是传递给 Intl.RelativeTimeFormat
构造函数的参数必须是一个 BCP 47 语言标记,或者是一个包括多个语言标记的数组。
以下是使用其他语言(汉语简体中文)的示例:(译注:原文是西班牙语)
const rtf = new Intl.RelativeTimeFormat('zh'); // 或 'zh-Hans-CN'
rtf.format(3.14, 'second');
// → '3.14秒钟后'
rtf.format(-15, 'minute');
// → '15分钟前'
rtf.format(8, 'hour');
// → '8小时后'
rtf.format(-2, 'day');
// → '2天前'
rtf.format(3, 'week');
// → '3周后'
rtf.format(-5, 'month');
// → '5个月前'
rtf.format(2, 'quarter');
// → '2个季度后'
rtf.format(-42, 'year');
// → '42年前'
此外,Intl.RelativeTimeFormat
构造函数还接受一个可选 options
参数,该参数可以对输出进行细粒度控制。为了说明灵活性,让我们根据默认设置查看更多输出:
// 创建一个简体中文相对时间格式化示例,使用默认设置。
// 在这个例子中,我们将默认参数显式的传进去
const rtf = new Intl.RelativeTimeFormat('zh', {
localeMatcher: 'best fit', // 其他值: 'lookup'
style: 'long', // 其他值: 'short' 或 'narrow'
numeric: 'always', // 其他值: 'auto'
});
rtf.format(-1, 'day');
// → '1天前'
rtf.format(0, 'day');
// → '0天后'
rtf.format(1, 'day');
// → '1天后'
rtf.format(-1, 'week');
// → '1周前'
rtf.format(0, 'week');
// → '0周后'
rtf.format(1, 'week');
// → '1周后'
您可能已经注意到上面的格式化程序生成了字符串 '1天前'
而不是 '昨天'
,还有显得比较弱智的 '0周后'
而不是 '本周'
。发生这种情况是因为默认情况下,格式化程序使用数值进行输出。
要更改此行为,请将 numeric
选项设置为 'auto'
(默认值是 'always'
):
const rtf = new Intl.RelativeTimeFormat('zh', { numeric: 'auto' });
rtf.format(-1, 'day');
// → '昨天'
rtf.format(-2, 'day');
// → '前天'
rtf.format(0, 'day');
// → '今天'
rtf.format(1, 'day');
// → '明天'
rtf.format(2, 'day');
// → '后天'
rtf.format(-1, 'week');
// → '上周'
rtf.format(0, 'week');
// → '本周'
rtf.format(1, 'week');
// → '下周'
Analogous to other Intl
classes, Intl.RelativeTimeFormat
has a formatToParts
method in addition to the format method. Although format covers the most common use case, formatToParts
can be helpful if you need access to the individual parts of the generated output:
与其他 Intl
类一样,Intl.RelativeTimeFormat
除了 format
方法之外,还有一个 formatToParts
方法。虽然 format
涵盖了最常见的用例,但如果您需要访问生成的输出的各个部分,formatToParts
会很有帮助:
const rtf = new Intl.RelativeTimeFormat('zh', { numeric: 'auto' });
rtf.format(-1, 'day');
// → '昨天'
rtf.formatToParts(-1, 'day');
// → [{ type: 'literal', value: '昨天' }]
rtf.format(3, 'week');
// → '3周后'
rtf.formatToParts(3, 'week');
// → [
// { type: 'integer', value: '3', unit: 'week' },
// { type: 'literal', value: '周后' }
// ]
有关其余选项及其行为的详细信息,请参阅 API docs in the proposal repository.
结论
Intl.RelativeTimeFormat
默认情况下在 V8 v7.1.179 和 Chrome 71 中可用。随着此 API 变得更加广泛可用,您将发现诸如 Moment.js、Globalize、date-fns 之类的库,会从代码库中移除对硬编码 CLDR 数据库的依赖性,而使用本机相对时间格式化功能,从而提高加载时性能、分析和编译时性能、运行时性能和内存使用。
相关链接
国际化相对时间格式化API:Intl.RelativeTimeFormat的更多相关文章
- 【JAVA8新的时间与日期 API】- 传统时间格式化的线程安全问题
Java8之前的日期和时间API,存在一些问题,最重要的就是线程安全的问题.这些问题都在Java8中的日期和时间API中得到了解决,而且Java8中的日期和时间API更加强大. 传统时间格式化的线程安 ...
- java8新特性——时间日期API
传统的时间 API 存在线程安全的问题,在多线程开发中必须要上锁,所以 java8 现在为我们提供了一套全新的时间日期 API ,今天进来学习一下java8 的时间日期 API. 一.使用 Local ...
- Java 8 的时间日期 API
上一篇文章『Java 的时间日期 API』中,我们学习了由 Date.Calendar,DateFormat 等组成的「传统时间日期 API」,但是传统的处理接口设计并不是很友好,不易使用.终于,Ja ...
- @JsonFormat时间格式化注解使用
@JsonFormat注解是一个时间格式化注解,比如我们存储在mysql中的数据是date类型的,当我们读取出来封装在实体类中的时候,就会变成英文时间格式,而不是yyyy-MM-dd HH:mm:ss ...
- 日期 日历 时区 地区 格式化 API 案例 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- Java8新特性(三)——Optional类、接口方法与新时间日期API
一.Optional容器类 这是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. 查看结构图可以看到有如下常用方法: of(T)—— ...
- Java 8 新的时间日期 API
1. 概述 1.1 简介 Java 8 引入了一套全新的时间日期API,操作起来更简便.简单介绍下,LocalDate和LocalTime和LocalDateTime的使用: java.util.Da ...
- 【记录】Mybatis Generator生成数据对象Date/TimeStamp 查询时间格式化
Mybatis Generator是很好的工具帮助我们生成表映射关联代码,最近博主遇到一个问题,找了很久才解决, 就是用Mybatis Generator生成实体类的时候,Date 时间无法格式化输出 ...
- 《React后台管理系统实战 :三》header组件:页面排版、天气请求接口及页面调用、时间格式化及使用定时器、退出函数
一.布局及排版 1.布局src/pages/admin/header/index.jsx import React,{Component} from 'react' import './header. ...
随机推荐
- springboot----一、SpringBoot简介
一.SpringBoot简介 1.1.回顾什么是Spring Spring是一个开源框架,2003 年兴起的一个轻量级的Java 开发框架,作者:Rod Johnson . Spring是为了解决企业 ...
- AutoResetEvent 与 ManualResetEvent
实际上这两个东西是同一种东西,可以把他们理解为线程锁,两个不同的线程可以共享. 这两个类的构造函数参数都是传入一个 bool 值,这个 bool 值可以理解为一开始的时候,这个需要访问的资源是处于可用 ...
- 最详尽教程完整介绍-Windows 的 Linux 子系统-WSL1&WSL2
安装 WSL 1. 开启WSL 必须启用"适用于 Linux 的 Windows 子系统"可选功能并重启,然后才能在 Windows 上运行 Linux 发行版. 以管理员运行Po ...
- 所有整数型包装类对象值的比较,使用equals方法进行比较
一.整数型包装类对象值的比较,使用equals方法进行比较 题眼:整型包装类.值的比较 注:== :对于基本类型,比较的是值:对于引用类型,比较的是地址值. // 组一Integer i1=new I ...
- 内网渗透----Linux下信息收集
基础信息 1.系统类型 cat /etc/issue查看系统名称 Lsb-release查看系统名称.版本号 2. 内核版本 uname –a 查看所有信息 ls /root |grep vmlinu ...
- STM32芯片去除读写保护 | 使用ST-Link Utility去除STM32芯片读写保护
1.使用ST-LINK V2下载器连接到STM32芯片, 点击Connect: 2.存在读保护: 3.修改选项字节(Option Bytes... ): 4.将读保护修改为Disabled. 5.打钩 ...
- mysql innodb事务的ACID及其实现的保证机制
MySQL事务的ACID,一致性是最终目的.保证一致性的措施有:A原子性:靠undo log来保证(异常或执行失败后进行回滚).D持久性:靠redo log来保证(保证当MySQL宕机或停电后,可以通 ...
- Spring Boot 增加删除修改 批量
1.批量删除 a.自定义Repositoy中写 前台处理https://blog.csdn.net/yhflyl/article/details/81557670首先前台先要获取所有的要删除数据的I ...
- 一台 Linux 系统初始化环境后需要做一些什么安全工作?
1.添加普通用户登陆,禁止 root 用户登陆,更改 SSH 端口号. 修改 SSH 端口不一定绝对哈.当然,如果要暴露在外网,建议改下.l 2.服务器使用密钥登陆,禁止密码登陆. ...
- notify()和 notifyAll()有什么区别?
当一个线程进入 wait 之后,就必须等其他线程 notify/notifyall,使用 notifyall,可 以唤醒所有处于 wait 状态的线程,使其重新进入锁的争夺队列中,而 notify 只 ...