やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

JSで日時を扱うライブラリmoment.js

 フォーマットできる。素敵!

成果物

URL

属性
version 2.22.2
size 319KB (moment-with-locales.min.js)

使ってみた

const now = moment();
console.log(now.format("YYYY年MM月DD日(ddd) HH:mm:ss.SSS"));
2018年08月11日(土) 20:26:43.428

API一覧

 公式サイトにはAPI一覧がなかった。

 ブラウザのデバッガから一覧を取得した。全85関数。moment()で生成されたオブジェクトの__proto__オブジェクトが対象。

f:id:ytyaru:20180812081649p:plain

  • add(e,t)
  • calendar(e,t)
  • clone()
  • constructor(e)
  • creationData()
  • date(e)
  • dates()
  • day(e)
  • dayOfYear(e)
  • days(e)
  • daysInMonth()
  • diff(e,t,n)
  • endOf(e)
  • format(e)
  • from(e,t)
  • fromNow(e)
  • get(e)
  • hasAlignedHourOffset(e)
  • hour(e)
  • hours(e)
  • inspect()
  • invalidAt()
  • isAfter(e,t)
  • isBefore(e,t)
  • isBetween(e,t,n,s)
  • isDST()
  • isDSTShifted()
  • isLeapYear()
  • isLocal()
  • isSame(e,t)
  • isSameOrAfter(e,t)
  • isSameOrBefore(e,t)
  • isUTCVt()
  • isUtcVt()
  • isUtcOffset()
  • isValid()
  • isoWeek(e)
  • isoWeekYear(e)
  • isoWeekday(e)
  • isoWeeks(e)
  • isoWeeksInYear()
  • lang()
  • local(e)
  • localeQt(e)
  • localeDataKt()
  • max()
  • millisecond(e)
  • milliseconds(e)
  • min()
  • minute(e)
  • minutes(e)
  • monthFe(e)
  • months()
  • parseZone()
  • parsingFlags()
  • quarter(e)
  • quarters(e)
  • second(e)
  • seconds(e)
  • set(e,t)
  • startOf(e)
  • subtract(e,t)
  • to(e,t)
  • toArray()
  • toDate()
  • toISOString(e)
  • toJSON()
  • toNow(e)
  • toObject()
  • toString()
  • unix()
  • utc(e)
  • utcOffset(e,t,n)
  • valueOf()
  • week(e)
  • weekYear(e)
  • weekday(e)
  • weeks(e)
  • weeksInYear()
  • year(e)
  • years()
  • zone()
  • zoneAbbr()
  • zoneName()

ロケール

moment.locale(window.navigator.language); // 設定。"ja"を想定
moment.locale(); // 取得

書式

format

 日時から文字列に変換する。

const fmt = "YYYY-MM-DD(ddd) hh:mm:ss.SSS";
const m = moment(); // 現在日時
alert(m.format(fmt));

parse

 文字列から日時に変換する。

const fmt = "YYYY-MM-DD(ddd) hh:mm:ss.SSS";
const m = moment("2018-08-12(日) 12:34:56.789", fmt)

比較

関数 意味
m.isSame(e, t) m == e
m.isBefore(e, t) m < e
m.isAfter(e, t) m > e
m.isSameOrBefore(e, t) m <= e
m.isSameOrAfter(e, t) m >= e
const m = moment();
m.isSame("2000-01-01");
m.isSame("2000-01-01", "years");

truefalseを返す。

加減

関数 概要
add() 日付を加算する
subtract() 日付を減算する
const m = moment();
m.add(3, "days");
m.subtract(3, "days");

相対日時

 diff(), from(), fromNow()で相対日時が算出できる。「7年前」「10時間前」とか。

 コード抜粋。

+ "今: " + m.format(fmt) + "\n"
+ "2000年からの経過年(diff): " + m.diff(moment("2000-01-01"), "years") + "\n"
+ "2000年からの経過年(diff): " + m.diff(moment("2000-01-01"), "years", true) + "\n"
+ "2000年は今から(from): " + moment("2000-01-01").from(m) + "\n"
+ "2000年は今から(fromNow): " + moment("2000-01-01").fromNow() + "\n"

 結果。

今: 2018-08-12(日) 09:23:06.889
2000年からの経過年(diff): 18
2000年からの経過年(diff): 18.613954440741985
2000年は今から(from): 19年前
2000年は今から(fromNow): 19年前

fromNow()

 特にfromNow()は現在日時との差をすぐ得られて便利。

 ただ、四捨五入されてしまう。たとえば2000-01-012018-08-12の何年前であるかを算出すると19年前になってしまう。18年と8ヶ月なので四捨五入すれば19年になる。年単位で小数表示すると18.6である。四捨五入して19。

 「18年前」と表示して欲しいこともあるのにできない。切り捨てなど四捨五入以外の丸め方式を選択できないせいだ。あるいは「18年8ヶ月前」「18年8ヶ月12日前」のように月や日まで表示することもできない。

diff(e, t, true)

 汎用的なのはdiff()である。
 diff()の第三引数をtrueにすると少数も取得できる。あとは切り捨てるなり四捨五入なり好きに丸めればいい。

m.diff(moment("2000-01-01"), "years", true)

算出(年月)

 相対日時を算出してみた。「18年7ヶ月」のような表示ができる。

this.DiffShow(this.DiffOfMonths(m, "2000-01-01")); // Y年Mヶ月
// 日時の差分を返す(年月)
DiffOfMonths(e, t) {
    const d = e.diff(moment(t), "months");
    const year = Math.floor(d / 12);
    const month = d % 12;
    return {year: year, month: month};
}
// 差分オブジェクトの値に単位をつける
DiffShow(diff) {
    let msg = diff.year + "年" + diff.month + "ヶ月";
    if (Object.keys(diff).some(v=>v=="day")) {
        msg += diff.day + "日";
    }
    return msg;
}
算出(年月日)

 さらに日まで表示する。「18年7ヶ月18日」のような。

this.DiffShow(this.DiffOfDays(m, "2000-01-01")); // Y年Mヶ月D日
// 日時の差分を返す(年月日)
DiffOfDays(e, t) {
    const d = e.diff(moment(t), "days");
    const year = Math.floor(d / 365);
    const days = d % 365;
    const month = Math.floor(days / 30);
    const day = days - (month * 30);
    return {year: year, month: month, day: day};
}
  • 1年間を365日として数える(366日になる閏年は考慮せず)
  • 1ヶ月を30日として数える