LoginSignup
0
0

More than 3 years have passed since last update.

【javascript】まだよくわかってないClassを使って日付操作【勉強】

Last updated at Posted at 2021-05-02

前回の記事で日付の続きでもあります。

日付処理は有用なライブラリがありますが、経験値積むためなのでお許しを。

目的

Dateを継承して以下のようなメソッドチェーンにしたかった。

const time = new Time(1999,7,7,16,30,30,500);
const f = 'YYYY/MM/DD H:mm:ss.fff(DDD)';

console.log( time.term(1990, 2, 3) );   // -297621030500
console.log( time.getWeekday() );       // Sat
console.log( time.getWeekday('ja') );   // 土
console.log( time.format(f) );                      // 1999/08/07 16:30:30.500(Sat)
console.log( time.advance(1).format(f) );           // 2000/08/07 16:30:30.500(Mon)
console.log( time.advanceDays(-3,5).format(f) );    // 2000/08/04 21:30:30.500(Fri)
console.log( time.reset().format(f) );              // 1999/08/07 16:30:30.500(Sat)

コード

  • 追記1:time.term()のミリ秒以外で出力するメソッドを追加。
  • 追記2:time.reset()関連の修正。引数nowを追加。
  • 追記3:time.termDays()系の結果を四捨五入から切り上げに変更。time.splitTerm()を追加
class Time extends Date {
    constructor(...args) {
        super(...args);
        this.default = super.toISOString();
    }
    reset(now) {
        const d = now===true ? new Date() : new Date(this.default);
        super.setFullYear(d.getFullYear());
        super.setMonth(d.getMonth());
        super.setDate(d.getDate());
        super.setHours(d.getHours());
        super.setMinutes(d.getMinutes());
        super.setSeconds(d.getSeconds());
        super.setMilliseconds(d.getMilliseconds());
        return this
    }
    advance() {
        if (arguments[0]) super.setFullYear(super.getFullYear() + arguments[0]);
        if (arguments[1]) super.setMonth(super.getMonth() + arguments[1]);
        if (arguments[2]) super.setDate(super.getDate() + arguments[2]);
        if (arguments[3]) super.setHours(super.getHours() + arguments[3]);
        if (arguments[4]) super.setMinutes(super.getMinutes() + arguments[4]);
        if (arguments[5]) super.setSeconds(super.getSeconds() + arguments[5]);
        if (arguments[6]) super.setMilliseconds(super.getMilliseconds() + arguments[6]);
        return this
    }
    advanceDays() {
        if (arguments[0]) super.setDate(super.getDate() + arguments[0]);
        if (arguments[1]) super.setHours(super.getHours() + arguments[1]);
        if (arguments[2]) super.setMinutes(super.getMinutes() + arguments[2]);
        if (arguments[3]) super.setSeconds(super.getSeconds() + arguments[3]);
        if (arguments[4]) super.setMilliseconds(super.getMilliseconds() + arguments[4]);
        return this
    }
    term() {
        return new Date(...arguments) - this;
    }
    termSeconds() {
        return Math.ceil((new Date(...arguments) - this) / 1000);
    }
    termMinuts() {
        return Math.ceil((new Date(...arguments) - this) / 60000);
    }
    termHours() {
        return Math.ceil((new Date(...arguments) - this) / 3600000);
    }
    termDays() {
        return Math.ceil((new Date(...arguments) - this) / 86400000);
    }
    splitTerm() {
        const term = new Date(...arguments) - this;
        const res = term < 0 ? [-term, '-'] : [term, '+'];

        for (const div of [86400000, 3600000, 60000, 1000]) {
            res.push( Math.floor(res[0]/div) );
            res[0] %= div;
        }
        res.push( res.shift() );
        return res
    }
    getWeekday(langStr) {
        const n = super.getDay();
        switch (langStr){
            case 'ja': return '日月火水木金土'.charAt(n);
            default: return ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'][n];
        }
    }
    format(formatStr) {
        const weekdays = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
        const pad = (num, dig) => ('000' + num).slice(-dig);
        return formatStr.replace(/([YMDHhmsf])\1*/g, match => {
            switch (match) {
                case 'YYYY':return super.getFullYear();
                case 'YY':  return pad(super.getFullYear(), 2);
                case 'M':   return super.getMonth()+1;
                case 'MM':  return pad(super.getMonth()+1, 2);
                case 'D':   return super.getDate();
                case 'DD':  return pad(super.getDate(), 2);
                case 'H':   return super.getHours();
                case 'HH':  return pad(super.getHours(), 2);
                case 'm':   return super.getMinutes();
                case 'mm':  return pad(super.getMinutes(), 2);
                case 's':   return super.getSeconds();
                case 'ss':  return pad(super.getSeconds(), 2);
                case 'fff': return pad(super.getMilliseconds(), 3);
                case 'DDD': return weekdays[super.getDay()];
                default: return match;
            }
        })
    }
}

メソッド解説

reset

time.reset( boolean now )
引数 true or other
返値 date date
説明 後述のadvance/advanceDayの処理で変化した日付をインスタンス生成時のものに戻す。引数をtrueにした場合のみ、このメソッドを実行した時間に上書きする。

advance

time.advance( number [y,[m,[d,[h,[mm,[s,[ms]]]]]]]] )
引数 number 第一引数を月,日,時,分,秒,ミリ秒と続く
返値 date date
説明 time.advance(0,1,1)で一月一日分加算され、time.advance(-1)で1年戻る

advanceDays

time.advanceDays( number [d,[mm,[s,[ms]]]] )
引数 number 第一引数を時,分,秒,ミリ秒と続く
返値 date date
説明 advance()の年月を省いたもの

term

time.term()
引数 new Date()に指定する引数と同じもの
返値 number milliseconds
説明 インスタンス生成した日付と、ここで指定した日付の差が何ミリ秒かを出力

termSeconds...

time.termSeconds() / time.termMinutes() / time.termHours() / time.termDays()
引数 new Date()に指定する引数と同じもの
返値 number seconds/minutes/hours/days
説明 各単位の対応版

splitTerm

time.splitTerm()
引数 new Date()に指定する引数と同じもの
返値 Array [string '+'|'-'、number days, number hr, mi, sc, ms]
説明 ミリ秒を日数を最大にした各単位で分割して配列に出力。['+', 7, 1, 0, 3, 555]7日と1時間3秒555ミリ秒 後+は基準より後、-は基準より前。

getWeekday

time.getWeekday( string lang )
引数 string 言語指定
返値 string weekday
説明 'ja'を指定すれば日本の曜日、それ以外は英語の曜日

format

time.format( string format )
引数 string 出力形式
返値 string date
説明 詳細は前回の記事。'YYYY/MM/DD'と指定すれば2000/08/04のように返す。

私感

superの使い方これでいいのかとか、他のメソッドでも使いたいweekdaysのような曜日の配列をconstructorに置いても良いのか(外から書き換えられそう)とか、他にも多分色々おかしいところがあるかもしれない。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0