mirror of
https://github.com/ceph/ceph
synced 2025-02-24 19:47:44 +00:00
mgr/dashboard: Time diff service
The time diff service can easily calculate the difference between two dates and print it out in a human readable duration format. It also can calculate a end or start date based on a date and a duration string. Fixes: https://tracker.ceph.com/issues/36722 Signed-off-by: Stephan Müller <smueller@suse.com>
This commit is contained in:
parent
b20e9c8db8
commit
3fb21de8fd
@ -0,0 +1,66 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { configureTestBed } from '../../../testing/unit-test-helper';
|
||||
import { TimeDiffService } from './time-diff.service';
|
||||
|
||||
describe('TimeDiffService', () => {
|
||||
let service: TimeDiffService;
|
||||
const baseTime = new Date('2022-02-22T00:00:00');
|
||||
|
||||
configureTestBed({
|
||||
providers: [TimeDiffService]
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
service = TestBed.get(TimeDiffService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
|
||||
it('calculates a new date that happens after the given date', () => {
|
||||
expect(service.calculateDate(new Date('2022-02-28T04:05:00'), '2h')).toEqual(
|
||||
new Date('2022-02-28T06:05:00')
|
||||
);
|
||||
expect(service.calculateDate(baseTime, '15m')).toEqual(new Date('2022-02-22T00:15'));
|
||||
expect(service.calculateDate(baseTime, '5d 23h')).toEqual(new Date('2022-02-27T23:00'));
|
||||
});
|
||||
|
||||
it('calculates a new date that happens before the given date', () => {
|
||||
expect(service.calculateDate(new Date('2022-02-22T02:00:00'), '2h', true)).toEqual(baseTime);
|
||||
});
|
||||
|
||||
it('calculates the difference of two dates', () => {
|
||||
expect(
|
||||
service.calculateDuration(new Date('2022-02-22T00:45:00'), new Date('2022-02-22T02:00:00'))
|
||||
).toBe('1h 15m');
|
||||
expect(service.calculateDuration(baseTime, new Date('2022-02-28T04:05:00'))).toBe('6d 4h 5m');
|
||||
});
|
||||
|
||||
describe('testing duration calculation in detail', () => {
|
||||
const minutes = 60 * 1000;
|
||||
const hours = 60 * minutes;
|
||||
const days = 24 * hours;
|
||||
|
||||
it('should allow different writings', () => {
|
||||
const expectDurationToBeMs = (duration, ms) =>
|
||||
expect(service['getDurationMs'](duration)).toBe(ms);
|
||||
expectDurationToBeMs('2h', 2 * hours);
|
||||
expectDurationToBeMs('4 Days', 4 * days);
|
||||
expectDurationToBeMs('3 minutes', 3 * minutes);
|
||||
expectDurationToBeMs('4 Days 2h 3 minutes', 4 * days + 2 * hours + 3 * minutes);
|
||||
expectDurationToBeMs('5d3h120m', 5 * days + 5 * hours);
|
||||
});
|
||||
|
||||
it('should create duration string from ms', () => {
|
||||
const expectMsToBeDuration = (ms, duration) =>
|
||||
expect(service['getDuration'](ms)).toBe(duration);
|
||||
expectMsToBeDuration(2 * hours, '2h');
|
||||
expectMsToBeDuration(4 * days, '4d');
|
||||
expectMsToBeDuration(3 * minutes, '3m');
|
||||
expectMsToBeDuration(4 * days + 2 * hours + 3 * minutes, '4d 2h 3m');
|
||||
expectMsToBeDuration(service['getDurationMs']('5d3h120m'), '5d 5h');
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,51 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import * as _ from 'lodash';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class TimeDiffService {
|
||||
constructor() {}
|
||||
|
||||
calculateDuration(startDate: Date, endDate: Date): string {
|
||||
const startTime = +startDate;
|
||||
const endTime = +endDate;
|
||||
const duration = this.getDuration(Math.abs(startTime - endTime));
|
||||
if (startTime > endTime) {
|
||||
return '-' + duration;
|
||||
}
|
||||
return duration;
|
||||
}
|
||||
|
||||
private getDuration(ms: number): string {
|
||||
const date = new Date(ms);
|
||||
const h = date.getUTCHours();
|
||||
const m = date.getUTCMinutes();
|
||||
const d = Math.floor(ms / (24 * 3600 * 1000));
|
||||
|
||||
const format = (n, s) => (n ? n + s : n);
|
||||
return [format(d, 'd'), format(h, 'h'), format(m, 'm')].filter((x) => x).join(' ');
|
||||
}
|
||||
|
||||
calculateDate(date: Date, duration: string, reverse?: boolean): Date {
|
||||
const time = +date;
|
||||
if (_.isNaN(time)) {
|
||||
return;
|
||||
}
|
||||
const diff = this.getDurationMs(duration) * (reverse ? -1 : 1);
|
||||
return new Date(time + diff);
|
||||
}
|
||||
|
||||
private getDurationMs(duration: string): number {
|
||||
const d = this.getNumbersFromString(duration, 'd');
|
||||
const h = this.getNumbersFromString(duration, 'h');
|
||||
const m = this.getNumbersFromString(duration, 'm');
|
||||
return ((d * 24 + h) * 60 + m) * 60000;
|
||||
}
|
||||
|
||||
private getNumbersFromString(duration, prefix): number {
|
||||
const match = duration.match(new RegExp(`[0-9 ]+${prefix}`, 'i'));
|
||||
return match ? parseInt(match, 10) : 0;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user