Skip to content

fix: support anything coercer supports for date parsing #1078

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions projects/common/src/utilities/coercers/date-coercer.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { TimeDuration } from '../../time/time-duration';
import { TimeUnit } from '../../time/time-unit.type';
import { Coercer, CoercerOptions } from './coercer';

export class DateCoercer extends Coercer<Date, DateCoercerOptions> {
private static readonly DEFAULT_TIME_WINDOW: DateCoercerOptions = {
earliestDate: new Date(Date.now() - new TimeDuration(10, TimeUnit.Year).toMillis()),
latestDate: new Date(Date.now() + new TimeDuration(10, TimeUnit.Year).toMillis())
};

public constructor(options: DateCoercerOptions = {}) {
super(options);
}

protected assignDefaults(options: DateCoercerOptions): DateCoercerOptions {
const tenYearsInMillis = 10 * 365 * 24 * 60 * 60 * 1000;
const now = Date.now();
const tenYearsAgo = new Date(now - tenYearsInMillis);
const tenYearsFuture = new Date(now + tenYearsInMillis);

return {
earliestDate: tenYearsAgo,
latestDate: tenYearsFuture,
...DateCoercer.DEFAULT_TIME_WINDOW,
...super.assignDefaults(options)
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { DateFormatter } from './date-formatter';

describe('Date formatter', () => {
const dateString = '2021-08-19T23:35:45.861Z';

test('can format a date string', () => {
expect(new DateFormatter().format(dateString)).toEqual('19 Aug 2021 11:35 PM');
});
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { formatDate } from '@angular/common';
import { defaults } from 'lodash-es';
import { DateCoercer } from '../../coercers/date-coercer';

export const enum DateFormatMode {
TimeOnly,
Expand All @@ -16,13 +17,14 @@ export class DateFormatter {
};

protected readonly options: Readonly<Required<DateFormatOptions>>;
private readonly dateCoercer: DateCoercer = new DateCoercer();

// Temporary placeholder, need to flesh this out
public constructor(options: DateFormatOptions = {}) {
this.options = this.applyOptionDefaults(options);
}

public format(value: Date | number | undefined): string {
public format(value: Date | number | undefined | string): string {
return this.convertDateToString(value);
}

Expand All @@ -32,12 +34,13 @@ export class DateFormatter {
return newOptions;
}

protected convertDateToString(value: Date | number | undefined): string {
if (value === undefined) {
protected convertDateToString(value: Date | number | string | undefined): string {
const coercedValue = this.dateCoercer.coerce(value);
if (coercedValue === undefined) {
return '-';
}

return formatDate(value, this.getFormatString(), 'en_US');
return formatDate(coercedValue, this.getFormatString(), 'en_US');
}

private getFormatString(): string {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Pipe, PipeTransform } from '@angular/core';
import { isNil } from 'lodash-es';
import { DateFormatOptions, DateFormatter } from './date-formatter';

@Pipe({
name: 'htDisplayDate'
})
export class DisplayDatePipe implements PipeTransform {
public transform(value?: Date | number | null, options: DateFormatOptions = {}): string {
return value !== null ? new DateFormatter(options).format(value) : '-';
public transform(value?: string | Date | number | null, options: DateFormatOptions = {}): string {
return isNil(value) ? '-' : new DateFormatter(options).format(value);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Injector } from '@angular/core';
import { TableCellTimestampParser } from './table-cell-timestamp-parser';

describe('table cell timestamp parser', () => {
const dateString = '2021-08-19T23:35:45.861Z';
const date = new Date(dateString);
const dateMillis = date.getTime();

test('can parse date strings', () => {
// tslint:disable-next-line: no-object-literal-type-assertion
expect(new TableCellTimestampParser({} as Injector).parseValue(dateString)).toEqual(date);
});

test('can parse numbers', () => {
// tslint:disable-next-line: no-object-literal-type-assertion
expect(new TableCellTimestampParser({} as Injector).parseValue(dateMillis)).toEqual(dateMillis);
});

test('can parse date objects', () => {
// tslint:disable-next-line: no-object-literal-type-assertion
expect(new TableCellTimestampParser({} as Injector).parseValue(date)).toEqual(date);
});
});
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { DateCoercer } from '@hypertrace/common';
import { TableCellParser } from '../table-cell-parser';
import { TableCellParserBase } from '../table-cell-parser-base';
import { CoreTableCellParserType } from '../types/core-table-cell-parser-type';
Expand All @@ -6,14 +7,15 @@ import { CoreTableCellParserType } from '../types/core-table-cell-parser-type';
type: CoreTableCellParserType.Timestamp
})
export class TableCellTimestampParser extends TableCellParserBase<CellData, Value, Value> {
private readonly dateCoercer: DateCoercer = new DateCoercer();
public parseValue(cellData: CellData): Value {
switch (typeof cellData) {
case 'number':
return cellData;
case 'object':
return cellData instanceof Date ? cellData : cellData.value;
default:
return undefined;
return this.dateCoercer.coerce(cellData);
}
}

Expand All @@ -22,5 +24,5 @@ export class TableCellTimestampParser extends TableCellParserBase<CellData, Valu
}
}

type CellData = Date | number | { value: Date | number };
type CellData = Date | number | string | { value: Date | number };
type Value = Date | number | undefined;