Skip to content

Commit

Permalink
feat(theme:_httpclient): add timestampSecond (#1670)
Browse files Browse the repository at this point in the history
  • Loading branch information
cipchk committed Nov 9, 2023
1 parent 2803dc8 commit 051b087
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 35 deletions.
14 changes: 9 additions & 5 deletions packages/theme/src/services/http/http.client.ts
Expand Up @@ -54,15 +54,19 @@ export class _HttpClient {
return params;
}

const { nullValueHandling, dateValueHandling } = this.cog;
Object.keys(params).forEach(key => {
let _data = params[key];
let paramValue = params[key];
// 忽略空值
if (this.cog.nullValueHandling === 'ignore' && _data == null) return;
if (nullValueHandling === 'ignore' && paramValue == null) return;
// 将时间转化为:时间戳 (秒)
if (this.cog.dateValueHandling === 'timestamp' && _data instanceof Date) {
_data = _data.valueOf();
if (
paramValue instanceof Date &&
(dateValueHandling === 'timestamp' || dateValueHandling === 'timestampSecond')
) {
paramValue = dateValueHandling === 'timestamp' ? paramValue.valueOf() : Math.trunc(paramValue.valueOf() / 1000);
}
newParams[key] = _data;
newParams[key] = paramValue;
});
return new HttpParams({ fromObject: newParams });
}
Expand Down
8 changes: 8 additions & 0 deletions packages/theme/src/services/http/http.spec.ts
Expand Up @@ -688,6 +688,14 @@ describe('theme: http.client', () => {
const ret = backend.expectOne(() => true) as TestRequest;
expect(ret.request.urlWithParams.length).toBeGreaterThan(URL.length + 15);
}));
it('should be working second-level timestamps', fakeAsync(() => {
createModule({ dateValueHandling: 'timestampSecond' });
const now = new Date();
http.get(URL, { a: now }).subscribe();
tick();
const ret = backend.expectOne(() => true) as TestRequest;
expect(ret.request.urlWithParams).toContain(`${Math.trunc(+now / 1000)}`);
}));
it('should be ingore null values', fakeAsync(() => {
createModule({ nullValueHandling: 'ignore' });
http.get(URL, { a: 1, b: null, c: undefined }).subscribe();
Expand Down
5 changes: 3 additions & 2 deletions packages/util/config/theme/http.type.ts
Expand Up @@ -7,8 +7,9 @@ export interface AlainThemeHttpClientConfig {
nullValueHandling?: 'include' | 'ignore';
/**
* 时间值处理,默认:`timestamp`
* - timestamp:时间戳
* - timestamp:时间戳毫秒级
* - timestampSecond:时间戳秒级
* - ignore:忽略处理,保持原始状态
*/
dateValueHandling?: 'timestamp' | 'ignore';
dateValueHandling?: 'timestamp' | 'timestampSecond' | 'ignore';
}
22 changes: 15 additions & 7 deletions packages/util/date-time/index.en-US.md
Expand Up @@ -4,6 +4,21 @@ subtitle: Date Time Conversion
type: Tools
---

## toDate

Convert to `Date` format, support `Date, number, string` types, If the argument is a number, it is treated as a timestamp.

* `formatString` If parsing fails try to parse the date by pressing `formatString`
* `defaultValue` If parsing fails returned default value, default: `new Date(NaN)`
* `timestampSecond` Whether the incoming value is in seconds

## formatDate

Format date, supports `Date, number, string` types, If the argument is a number, it is treated as a timestamp.

* Please refer to [date-fnd format](https://date-fns.org/v2.30.0/docs/format) for string format
* `dateLocale` Recommended to be consistent with NG-ZORRO by using `inject(NZ_DATE_LOCALE)`

## dateTimePickerUtil

一组针对 [DatePicker](https://ng.ant.design/components/date-picker/en) 的工具类。
Expand Down Expand Up @@ -39,10 +54,3 @@ getTimeDistance('week')
- `month`, `-month` This month or last month
- `year`, `-year` This year or last year
- `time` Specify start time, default is `now`

## toDate

Return the date parsed from string using the given format string, If the argument is a number, it is treated as a timestamp.

* `formatString` If parsing fails try to parse the date by pressing `formatString`
* `defaultValue` If parsing fails returned default value, default: `new Date(NaN)`
22 changes: 15 additions & 7 deletions packages/util/date-time/index.zh-CN.md
Expand Up @@ -4,6 +4,21 @@ subtitle: 日期时间转换
type: Tools
---

## toDate

转换成 `Date` 格式,支持 `Date, number, string` 类型,如果是 `number` 表示 Unix timestamp。

* `formatString` 如果转换失败尝试根据 `formatString` 格式来转换
* `defaultValue` 无效日期应返回的默认值,默认:`new Date(NaN)`
* `timestampSecond` 传入值是否秒级

## formatDate

格式化日期,支持 `Date, number, string` 类型,如果是 `number` 表示 Unix timestamp)。

* 字符串格式请参考 [date-fnd format](https://date-fns.org/v2.30.0/docs/format)
* `dateLocale` 建议通过使用 `inject(NZ_DATE_LOCALE)` 与 NG-ZORRO 保持一致

## dateTimePickerUtil

一组针对 [DatePicker](https://ng.ant.design/components/date-picker/en) 的工具类。
Expand Down Expand Up @@ -39,10 +54,3 @@ getTimeDistance('week')
- `month``-month` 本月或上月
- `year``-year` 今年或去年
- `time` 指定开始时间,默认为:`now`

## toDate

转换成 `Date` 格式,支持 `Date, number, string` 类型,如果是 `number` 表示 Unix timestamp。

* `formatString` 如果转换失败尝试根据 `formatString` 格式来转换
* `defaultValue` 无效日期应返回的默认值,默认:`new Date(NaN)`
5 changes: 3 additions & 2 deletions packages/util/date-time/time.spec.ts
Expand Up @@ -68,12 +68,13 @@ describe('util: time', () => {
expect(toDate(null).toString()).toBe(`Invalid Date`);
expect(f(toDate(NOW))).toBe(`2000-01-01 00:00:00`);
expect(f(toDate(+NOW))).toBe(`2000-01-01 00:00:00`);
expect(f(toDate(Math.trunc(+NOW / 1000), { timestampSecond: true }))).toBe(`2000-01-01 00:00:00`);
expect(f(toDate(`${+NOW}`))).toBe(`2000-01-01 00:00:00`);
expect(f(toDate(f(NOW)))).toBe(`2000-01-01 00:00:00`);
expect(isNaN(toDate(new String('') as NzSafeAny) as NzSafeAny)).toBe(true);
});

function f(d: Date): string {
return format(d, `yyyy-MM-dd HH:mm:ss`, { locale: zhCN });
function f(d: Date, formatString = `yyyy-MM-dd HH:mm:ss`): string {
return format(d, formatString, { locale: zhCN });
}
});
36 changes: 24 additions & 12 deletions packages/util/date-time/time.ts
Expand Up @@ -18,7 +18,7 @@ import {
} from 'date-fns';

import type { NzSafeAny } from 'ng-zorro-antd/core/types';
import type { DateLocale } from 'ng-zorro-antd/i18n';
import { DateLocale } from 'ng-zorro-antd/i18n';

/**
* Get the time range, return `[ Date, Date]` for the start and end dates
Expand Down Expand Up @@ -84,30 +84,35 @@ export function fixEndTimeOfRange(dates: [Date, Date]): [Date, Date] {
return [startOfDay(dates[0]), endOfDay(dates[1])];
}

export type ToDateOptions = string | { formatString?: string; defaultValue?: NzSafeAny };
export interface ToDateOptions {
/** If parsing fails try to parse the date by pressing `formatString` */
formatString?: string;
/** If parsing fails returned default value, default: `new Date(NaN)` */
defaultValue?: NzSafeAny;
timestampSecond?: boolean;
}

/**
* Return the date parsed from string using the given format string
* - If the argument is a number, it is treated as a timestamp.
* Convert to `Date` format
*
* @param formatString If parsing fails try to parse the date by pressing `formatString`
* @param defaultValue If parsing fails returned default value, default: `new Date(NaN)`
* @param value When is a number, it's treated as a timestamp; If it's seconds, you need to provide the `options.timestampSecond` parameter.
*/
export function toDate(value?: Date | string | number | null, options?: ToDateOptions): Date {
if (typeof options === 'string') options = { formatString: options };
const { formatString, defaultValue } = {
export function toDate(value?: Date | string | number | null, options?: string | ToDateOptions): Date {
const { formatString, defaultValue, timestampSecond } = {
formatString: 'yyyy-MM-dd HH:mm:ss',
defaultValue: new Date(NaN),
...options
timestampSecond: false,
...(typeof options === 'string' ? { formatString: options } : options)
};
if (value == null) {
return defaultValue;
}
if (value instanceof Date) {
return value;
}
if (typeof value === 'number' || (typeof value === 'string' && /[0-9]{10,13}/.test(value))) {
return new Date(+value);
if (typeof value === 'number' || (typeof value === 'string' && /^[0-9]+$/.test(value))) {
const valueNumber = +value;
return new Date(timestampSecond ? valueNumber * 1000 : valueNumber);
}
let tryDate = parseISO(value);
if (isNaN(tryDate as NzSafeAny)) {
Expand All @@ -117,6 +122,13 @@ export function toDate(value?: Date | string | number | null, options?: ToDateOp
return isNaN(tryDate as NzSafeAny) ? defaultValue : tryDate;
}

/**
* Format date, supports `Date, number, string` types
*
* @param value When is a number, it is treated as a timestamp (Support seconds and milliseconds timestamp).
* @param formatString Please refer to [date-fnd format](https://date-fns.org/v2.30.0/docs/format) for string format
* @param dateLocale Recommended to be consistent with NG-ZORRO by using `inject(NZ_DATE_LOCALE)`
*/
export function formatDate(value: Date | string | number, formatString: string, dateLocale?: DateLocale): string {
value = toDate(value);
if (isNaN(value as NzSafeAny)) return '';
Expand Down
3 changes: 3 additions & 0 deletions src/app/app.module.ts
Expand Up @@ -7,6 +7,8 @@ import localeZh from '@angular/common/locales/zh';
import { APP_INITIALIZER, ErrorHandler, Inject, Injector, NgModule, PLATFORM_ID } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NZ_DATE_LOCALE } from 'ng-zorro-antd/i18n';
import { zhCN as dateLang } from 'date-fns/locale';

// angular i18n
registerLocaleData(localeZh);
Expand Down Expand Up @@ -82,6 +84,7 @@ function registerElements(injector: Injector, platformId: {}): void {
// deps: [ReuseTabService],
// },
{ provide: ALAIN_I18N_TOKEN, useClass: I18NService, multi: false },
{ provide: NZ_DATE_LOCALE, useValue: dateLang },
StartupService,
{
provide: APP_INITIALIZER,
Expand Down

0 comments on commit 051b087

Please sign in to comment.