Index
概要
Cybozu CDN中添加了可处理日期的库Luxon。
Luxon是同样可以对日期进行处理的Moment.js的后续版。
本篇介绍在进行kintone自定义时的Luxon导入方法以及常见的使用Luxon进行的日期处理。
什么是Luxon
Luxon是用于对数据进行格式设置、校验、计算、显示的 JavaScript 库。
代码公开在GitHub ,也有官方文档。
与Moment.js有什么不同
好处1:使用Luxon单体就可以处理时区
使用Moment.js对时区进行相关处理时,需要追加Moment Timezone这个库。
参考:使用Moment Timezone 简单管理时差(日文)
但是,仅使用Luxon就可以对时区进行操作。
luxon.DateTime.local().setZone("America/New_York").toISO(); // 2020-05-21T00:09:04.124-04:00
好处2:Luxon生成的对象为不可变对象
所谓不可变对象是指创建之后状态不会发生变化的对象。
Moment.js的对象是可变对象(非不可变对象),因此对日期等进行加法运算等时,进行操作的原对象会发生变化。
var date = moment(); var oneDayLater = date.add(1, 'days'); // 对原对象进行操作 console.log('date:' + date.format('YYYY-MM-DD')); console.log('oneDayLater:' + oneDayLater.format('YYYY-MM-DD')); // 原对象(date)也会变成1天后的日期 // date: 2020-05-22 // oneDayLater: 2020-05-22
使用Moment.js时,如果不想对原对象产生影响,需要复制对象,然后对复制后的对象进行操作。
var date = moment(); var oneDayLater = date.clone().add(1, 'days'); // 对复制后的对象进行操作 console.log('date:' + date.format('YYYY-MM-DD')); console.log('oneDayLater:' + oneDayLater.format('YYYY-MM-DD')); // 原对象(date)保持原来的日期 // date: 2020-05-21 // oneDayLater: 2020-05-22
Luxon的对象是不可变对象,因此对日期等进行加法运算时,原对象也不会发生变化。
var date = luxon.DateTime.local(); var oneDayLater = date.plus({days: 1}); console.log('date:' + date.toFormat('yyyy-MM-dd')); console.log('oneDayLater:' + oneDayLater.toFormat('yyyy-MM-dd')); // 原对象(date)保持原来的日期 // date: 2020-05-21 // oneDayLater: 2020-05-22
注意事项:根据浏览器不同,可能部分功能不能使用
Luxon仅支持主要浏览器的最新两个主版本号。
详情请参考 Official support 。
kintone自定义时的导入方法
请在kintone的“通过JavaScript / CSS自定义”页面中指定如下链接,之后再添加自定义文件。
https://js.cybozu.cn/luxon/1.24.1/luxon.min.js
以上URL在2020年6月11日时是Cybozu CDN上分发的最新版本的链接。
在导入Luxon时,请确认Cybozu CDN上分发的版本号,根据需要更改为最新的版本。
Luxon的使用方法
基本篇
导入CDN,luxon将添加为全局对象。
使用其生成Luxon对象。
使用其生成Luxon对象。 // 用当前日期生成 var currentDate = luxon.DateTime.local(); // 用kintone的日期字段的值生成(字段代码为“日期与时间”」) var dateFieldCode = '日期与时间'; var record = kintone.app.record.get().record; var dateFieldValue = record[dateFieldCode].value; var dateFieldDate= luxon.DateTime.fromISO(dateFieldValue);
您可以尝试获取各种格式的字符串。其他格式请参考Luxon - Formatting 。
// 生成Luxon对象 var date = luxon.DateTime.local(); // yyyy-MM-dd格式 // 例: 2020-06-02 date.toFormat('yyyy-MM-dd'); // 仅年月(不补0) // 例: 2020年6月 date.toFormat('yyyy年M月'); // 星期 // 例: 星期二 date.setLocale("zh").toFormat("EEEE"); // 时间字段格式 // 例: 09:00 date.toFormat('HH:mm'); // 日期和时间字段的格式 // 例: 2020-06-02T15:00:00.000+09:00 date.toISO();
试着对x天后或月初等日期进行操作。其他操作请参考Luxon - Math。
// 生成Luxon 对象 var date = luxon.DateTime.local(); // 3天后 var threeDaysLater = date.plus({days: 3}); // 月初 var startOfMonth = date.startOf('month'); // 月末 var endOfMonth = date.endOf('month'); // 其他周的星期一 var mondayOfTheWeek = date.set({ weekday: 1 });
kintone自定义时的使用范例
cybozu developer network上的Tips中介绍的日期计算换成Luxon计算看看。
计算年龄以及经过年数
显示经过了几年的Tips(日语)中介绍了如何根据出生年月日来计算年龄,以及根据入职日来计算在职多长时间等。我们试着用Luxon 来进行计算。
假设要自定义的应用中有如下字段。
字段名称 | 字段类型 | 字段代码 |
---|---|---|
出生年月日 | 日期 | BirthDay |
入职时间 | 日期 | JoiningDay |
以下范例代码要实现的功能是在打开应用的详细页面时,在开发者工具中显示年龄以及在职时间。
/* * Luxon sample program * Copyright (c) 2020 Cybozu * * Licensed under the MIT License * https://opensource.org/licenses/mit-license.php */ (function() { 'use strict'; kintone.events.on('app.record.detail.show', function(event) { var record = event.record; var birthDayFieldCode = 'BirthDay'; var joiningDayFieldCode = 'JoiningDay'; /** * 计算经过了多少年月日 * @param {string} dateStr 日期字符串 * @returns {object} 计算结果的对象 */ var calculateDuration = function(dateStr) { var currentDate = luxon.DateTime.local().startOf('day'); var date = luxon.DateTime.fromISO(dateStr).startOf('day'); // 计算经过期间 var duration = currentDate.diff(date, ['years', 'months', 'days']); return duration.toObject(); }; // 计算年龄 var birthDayValue = record[birthDayFieldCode].value; var birthDayDuration = calculateDuration(birthDayValue); console.log(birthDayDuration.years + '岁'); // 计算从入职日起经过了多长时间 var joiningDayValue = record[joiningDayFieldCode].value; var joiningDayDuration = calculateDuration(joiningDayValue); console.log(joiningDayDuration.years + '年' + joiningDayDuration.months + '个月'); return event; }); })();
计算是否过期
给登录用户负责的记录标示背景色的Tips(日语)中,使用期限字段的值来计算“到期”或“到期日前x天”。
换成用Luxon来计算看看。
假设要自定义的应用有如下字段。
字段名称 | 字段类型 | 字段代码 |
---|---|---|
期限 | 日期 | LimitDay |
以下范例代码要实现的功能是当打开应用的记录列表时,如有记录已经过期或者里离过期不足5天,则显示在开发者工具上。
/* * Luxon sample program * Copyright (c) 2020 Cybozu * * Licensed under the MIT License * https://opensource.org/licenses/mit-license.php */ (function() { 'use strict'; kintone.events.on('app.record.index.show', function(event) { var DAYS = 5; var records = event.records; var idFieldCode = '$id'; var limitDayFieldCode = 'LimitDay'; /** * 离期限还有x天 * @param {string} dateStr 日期字符串 * @param {number} days x天 * @returns {boolean} 如果是期限前x天 true */ var isBeforeDeadline = function(dateStr, days) { var date = luxon.DateTime.fromISO(dateStr).startOf('day'); // 从今天起x天后的日期的对象 var addedDate = luxon.DateTime.local().plus({days: days}).startOf('day'); return date<= addedDate; }; /** * 是否过期 * @param {string} dateStr 日期字符串 * @returns {boolean} 如果已经过期 true */ var isExpired = function(dateStr) { var date = luxon.DateTime.fromISO(dateStr).startOf('day'); var currentDate = luxon.DateTime.local().startOf('day'); return date < currentDate; }; records.forEach(function(record) { var limitDayValue = record[limitDayFieldCode].value; var idValue = record[idFieldCode].value; if (isExpired(limitDayValue)) { console.log('记录编号' + idValue + '已经过期'); } else if (isBeforeDeadline(limitDayValue, DAYS)) { console.log('记录编号' + idValue + '离期限还有' + DAYS + '天'); } }); return event; }); })();
最后
原本使用JavaScript的Date类型进行日期处理时特别的麻烦,有了Luxon 以及 Moment.js等日期处理库,可变得非常的轻松。
cybozu developer network 上也有使用Moment.js进行日期处理的Tips(日语)。kintone自定义时如果需要进行日期处理,可供参考。
还有,从 Moment.js换成Luxon时,请参考官网的与Moment.js有什么不同。
本Tips在2020年5月版的 kintone 和 Luxon v1.24.1 版本中确认过。