使用Luxon自定义 kintone的日期及日期字段的格式

aki发表于:2021年01月19日 16:11:00更新于:2021年08月05日 16:59:54

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仅支持主要浏览器的最新两个主版本号。
不能保证在 Internet Explorer 11 下可以正常工作。详情请参考 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 版本中确认过。


    注意:贴代码时请注意格式并使用"代码语言",与本文无关的问题请至“讨论社区”提问。