web-dev-qa-db-ja.com

TypeScriptでTimeSpanを使用する方法

Angular + TypeScriptを使用してWebアプリを作成しています。ASP.NETWeb APIがあります。エンドポイントの1つがタイムスパンプロパティを持つモデルを返します。表示するためだけに文字列型を使用しましたが、今はそのTimeSpan値を使用してキャンバスにオブジェクトを描画する必要がありますが、それに関する有用な情報が見つかりません。

文字列値は「00:01:05」のようになります。

そして、例えばTotalSecondsを知る必要があります。

11
Crossman

ここでは、日、時間、分、秒をサポートするタイムスパンクラスの.NET C#同様の実装です。この実装は、負のタイムスパンもサポートします。

const MILLIS_PER_SECOND = 1000;
const MILLIS_PER_MINUTE = MILLIS_PER_SECOND * 60;   //     60,000
const MILLIS_PER_HOUR = MILLIS_PER_MINUTE * 60;     //  3,600,000
const MILLIS_PER_DAY = MILLIS_PER_HOUR * 24;        // 86,400,000

export class TimeSpan {
    private _millis: number;

    private static interval(value: number, scale: number): TimeSpan {
        if (Number.isNaN(value)) {
            throw new Error("value can't be NaN");
        }

        const tmp = value * scale;
        const millis = TimeSpan.round(tmp + (value >= 0 ? 0.5 : -0.5));
        if ((millis > TimeSpan.maxValue.totalMilliseconds) || (millis < TimeSpan.minValue.totalMilliseconds)) {
            throw new TimeSpanOverflowError("TimeSpanTooLong");
        }

        return new TimeSpan(millis);
    }

    private static round(n: number): number {
        if (n < 0) {
            return Math.ceil(n);
        } else if (n > 0) {
            return Math.floor(n);
        }

        return 0;
    }

    private static timeToMilliseconds(hour: number, minute: number, second: number): number {
        const totalSeconds = (hour * 3600) + (minute * 60) + second;
        if (totalSeconds > TimeSpan.maxValue.totalSeconds || totalSeconds < TimeSpan.minValue.totalSeconds) {
            throw new TimeSpanOverflowError("TimeSpanTooLong");
        }

        return totalSeconds * MILLIS_PER_SECOND;
    }

    public static get zero(): TimeSpan {
        return new TimeSpan(0);
    }

    public static get maxValue(): TimeSpan {
        return new TimeSpan(Number.MAX_SAFE_INTEGER);
    }

    public static get minValue(): TimeSpan {
        return new TimeSpan(Number.MIN_SAFE_INTEGER);
    }

    public static fromDays(value: number): TimeSpan {
        return TimeSpan.interval(value, MILLIS_PER_DAY);
    }

    public static fromHours(value: number): TimeSpan {
        return TimeSpan.interval(value, MILLIS_PER_HOUR);
    }

    public static fromMilliseconds(value: number): TimeSpan {
        return TimeSpan.interval(value, 1);
    }

    public static fromMinutes(value: number): TimeSpan {
        return TimeSpan.interval(value, MILLIS_PER_MINUTE);
    }

    public static fromSeconds(value: number): TimeSpan {
        return TimeSpan.interval(value, MILLIS_PER_SECOND);
    }

    public static fromTime(hours: number, minutes: number, seconds: number): TimeSpan;
    public static fromTime(days: number, hours: number, minutes: number, seconds: number, milliseconds: number): TimeSpan;
    public static fromTime(daysOrHours: number, hoursOrMinutes: number, minutesOrSeconds: number, seconds?: number, milliseconds?: number): TimeSpan {
        if (milliseconds != undefined) {
            return this.fromTimeStartingFromDays(daysOrHours, hoursOrMinutes, minutesOrSeconds, seconds, milliseconds);
        } else {
            return this.fromTimeStartingFromHours(daysOrHours, hoursOrMinutes, minutesOrSeconds);
        }
    }

    private static fromTimeStartingFromHours(hours: number, minutes: number, seconds: number): TimeSpan {
        const millis = TimeSpan.timeToMilliseconds(hours, minutes, seconds);
        return new TimeSpan(millis);
    }

    private static fromTimeStartingFromDays(days: number, hours: number, minutes: number, seconds: number, milliseconds: number): TimeSpan {
        const totalMilliSeconds = (days * MILLIS_PER_DAY) +
            (hours * MILLIS_PER_HOUR) +
            (minutes * MILLIS_PER_MINUTE) +
            (seconds * MILLIS_PER_SECOND) +
            milliseconds;

        if (totalMilliSeconds > TimeSpan.maxValue.totalMilliseconds || totalMilliSeconds < TimeSpan.minValue.totalMilliseconds) {
            throw new TimeSpanOverflowError("TimeSpanTooLong");
        }
        return new TimeSpan(totalMilliSeconds);
    }

    constructor(millis: number) {
        this._millis = millis;
    }

    public get days(): number {
        return TimeSpan.round(this._millis / MILLIS_PER_DAY);
    }

    public get hours(): number {
        return TimeSpan.round((this._millis / MILLIS_PER_HOUR) % 24);
    }

    public get minutes(): number {
        return TimeSpan.round((this._millis / MILLIS_PER_MINUTE) % 60);
    }

    public get seconds(): number {
        return TimeSpan.round((this._millis / MILLIS_PER_SECOND) % 60);
    }

    public get milliseconds(): number {
        return TimeSpan.round(this._millis % 1000);
    }

    public get totalDays(): number {
        return this._millis / MILLIS_PER_DAY;
    }

    public get totalHours(): number {
        return this._millis / MILLIS_PER_HOUR;
    }

    public get totalMinutes(): number {
        return this._millis / MILLIS_PER_MINUTE;
    }

    public get totalSeconds(): number {
        return this._millis / MILLIS_PER_SECOND;
    }

    public get totalMilliseconds(): number {
        return this._millis;
    }

    public add(ts: TimeSpan): TimeSpan {
        const result = this._millis + ts.totalMilliseconds;
        return new TimeSpan(result);
    }

    public subtract(ts: TimeSpan): TimeSpan {
        const result = this._millis - ts.totalMilliseconds;
        return new TimeSpan(result);
    }
}

使い方

新しいTimeSpanオブジェクトを作成する


    const ts = TimeSpan.zero;


    const milliseconds = 10000; // 1 second

    // by using the constructor
    const ts1 = new TimeSpan(milliseconds);

    // or as an alternative you can use the static factory method
    const ts2 = TimeSpan.fromMilliseconds(milliseconds);


    const seconds = 86400; // 1 day
    const ts = TimeSpan.fromSeconds(seconds);


    const minutes = 1440; // 1 day
    const ts = TimeSpan.fromMinutes(minutes);


    const hours = 24; // 1 day
    const ts = TimeSpan.fromHours(hours);


    const days = 1; // 1 day
    const ts = TimeSpan.fromDays(days);


    const hours = 1;
    const minutes = 1;
    const seconds = 1;
    const ts = TimeSpan.fromTime(hours, minutes, seconds);


    const days = 1;
    const hours = 1;
    const minutes = 1;
    const seconds = 1;
    const milliseconds = 1;
    const ts = TimeSpan.fromTime(days, hours, minutes, seconds, milliseconds);


    const ts = TimeSpan.maxValue;


    const ts = TimeSpan.minValue;


    const ts = TimeSpan.minValue;


    const ts1 = TimeSpan.fromDays(1);
    const ts2 = TimeSpan.fromHours(1);
    const ts = ts1.add(ts2);

    console.log(ts.days);               // 1
    console.log(ts.hours);              // 1
    console.log(ts.minutes);            // 0
    console.log(ts.seconds);            // 0
    console.log(ts.milliseconds);           // 0


    const ts1 = TimeSpan.fromDays(1);
    const ts2 = TimeSpan.fromHours(1);
    const ts = ts1.subtract(ts2);

    console.log(ts.days);               // 0
    console.log(ts.hours);              // 23
    console.log(ts.minutes);            // 0
    console.log(ts.seconds);            // 0
    console.log(ts.milliseconds);           // 0


    const days = 1;
    const hours = 1;
    const minutes = 1;
    const seconds = 1;
    const milliseconds = 1;
    const ts = TimeSpan.fromTime2(days, hours, minutes, seconds, milliseconds);

    console.log(ts.days);               // 1
    console.log(ts.hours);              // 1
    console.log(ts.minutes);            // 1
    console.log(ts.seconds);            // 1
    console.log(ts.milliseconds);           // 1

    console.log(ts.totalDays)           // 1.0423726967592593;
    console.log(ts.totalHours)          // 25.016944722222224;
    console.log(ts.totalMinutes)            // 1501.0166833333333;
    console.log(ts.totalSeconds)            // 90061.001;
    console.log(ts.totalMilliseconds);      // 90061001;

8
Pierre

TypeScriptには、すぐに使えるクラスTimeSpanがありません。

自分で実装できます。これは次のようになります: https://Gist.github.com/ranwahle/e78a8859ff78bdd68055017fc5875fcb

3