什么是 spacetime?
spacetime 是一个日期计算器,非常小,而且非常方便。具有以下突出特点:
计算远程时区的时间 支持夏令时、闰年和半球 类似 Moment 的 API(但不可变) 按季度、季节、月份、周来定位时间 零依赖 -(无 Intl API) 体积约 40kb 非常丰富的插件生态目前 spacetime 在 Github 通过 MIT 协议开源,有超过 3.9k 的 star、3.4k 的项目依赖量,代码贡献者 50+,是一个值得关注的开源开源项目。
spacetime Github地址:https://github.com/spencermountain/spacetime
如何使用 spacetime?
日期解析
spacetime 可以解析所有正常的数据,甚至包括一些奇特的东西:
//epoch
s = spacetime(1489520157124)
//array [yyyy, m, d] (zero-based months, 1-based days)
s = spacetime([2017, 5, 2])
//iso
s = spacetime('July 2, 2017 5:01:00')
// All inputs accept a timezone, as 2nd param:
s = spacetime(1489520157124, 'Canada/Pacific')
s = spacetime('2019/05/15', 'Canada/Pacific')
// or set the offset right in the date-string (ISO-8601)
s = spacetime('2017-04-03T08:00:00-0700')
// 'Etc/GMT-7'
// Some helpers
s = spacetime.now()
s = spacetime.today() // This morning
s = spacetime.tomorrow() // Tomorrow morning
s = spacetime.min() // the earliest-possible date (271,821 bc)
s = spacetime.max() // the furthest-possible future date (27k years from now)
// To get the native Date object back
// NOTE: this returns the date in the local browsers timezone
jsDate = spacetimeDate.toNativeDate()
时间比较
let s = spacetime([2017, 5, 2])
let start = s.subtract(1, 'milliseconds')
let end = s.add(1, 'milliseconds')
// gt/lt/equals
s.isAfter(d) // True
s.isEqual(d) // False
s.isBefore(d) // False
s.isBetween(start, end, inclusive?) // True
// Comparison by unit
s.isSame(d, 'year') // True
s.isSame(d, 'date') // False
s.diff(d, 'day') // 5
s.diff(d, 'month') // 0
//make a human-readable diff
let before = spacetime([2018, 3, 28])
let now = spacetime([2017, 3, 28]) //one year later
now.since(before)
// {diff: { months: 11, days: 30, ...}, rounded: 'in 12 months' }
所有比较均根据时区的敏感性进行 - 东部标准时间上午 8 点 < 太平洋标准时间上午 8 点。
时区 Timezones
描述时区的最佳方式是 IANA 代码:
// Roll into a new timezone, at the same moment
s = s.goto('Australia/Brisbane')
如果想支持宽松的时区名称,例如 “EST”、东部时间,可以使用 timezone-soft:
spacetime.extend(require('timezone-soft'))
s = s.goto('milwaukee') // 'America/Chicago'
s = s.goto('-7h') // UTC-7
s = s.goto('GMT+8') // -8h!
// (these should be used with some caution)
下面尝试时区及其 DST 更改:
//list timezones by their current time
spacetime.whereIts('8:30pm', '9:30pm') // ['America/Winnipeg', 'America/Yellowknife'... ]
spacetime.whereIts('9am') //(within this hour)
// Timezone metadata
s.timezone().name // 'Canada/Eastern' (either inferred or explicit)
s.hemisphere() // North
s.timezone().current.offset // -4 (in hours)
s.hasDST() // True
s.isDST() // True
//list all timezones
spacetime.timezones()
默认情况下,spacetime 将使用本地的时区,即. goto(null) 将从浏览器或计算机中安全地获取当前的 tz。
spacetime().time('4:30pm').goto('Europe/Paris').goto(null).time()
// 4:30pm
spacetime 可行替代品
luxon
luxon 是一个强大、现代且友好的 JavaScript 日期和时间包装器。 用于日期时间、持续时间和间隔、具有不可变、可链接、明确的 API 等特性,支持本机时区和 Intl (无区域设置或 tz 文件)
DateTime.now().setZone('America/New_York').minus({weeks:1}).endOf('day').toISO();
date-fns
现代 JavaScript 日期实用程序库。date-fns 提供了最全面、最简单且一致的工具集,用于在浏览器和 Node.js 中操作 JavaScript 日期。
import {format, formatDistance, formatRelative, subDays} from 'date-fns'
format(new Date(), "'Today is a' eeee")
//=> "Today is a Wednesday"
formatDistance(subDays(new Date(), 3), new Date(), { addSuffix: true })
//=> "3 days ago"
formatRelative(subDays(new Date(), 3), new Date())
//=> "last Friday at 7:26 p.m."
其他
sugarjs/dates:Sugar 使处理日期变得容易,并且支持多种语言。
Intl.DateTimeFormat :Intl.DateTimeFormat 对象启用语言敏感的日期和时间格式设置。
参考资料
https://github.com/spencermountain/spacetime
https://moment.github.io/luxon/#/
https://date-fns.org/
https://sugarjs.com/dates/
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat