diff --git a/npm/ng-packs/packages/core/src/lib/core.module.ts b/npm/ng-packs/packages/core/src/lib/core.module.ts index 83881a5246..e6e8c3355a 100644 --- a/npm/ng-packs/packages/core/src/lib/core.module.ts +++ b/npm/ng-packs/packages/core/src/lib/core.module.ts @@ -30,6 +30,7 @@ import { ShortTimePipe } from './pipes/short-time.pipe'; import { ShortDatePipe } from './pipes/short-date.pipe'; import { SafeHtmlPipe } from './pipes/safe-html.pipe'; import { provideAbpCoreChild, provideAbpCore, withOptions } from './providers'; +import { UtcToLocalPipe } from './pipes'; const standaloneDirectives = [ AutofocusDirective, @@ -64,6 +65,7 @@ const standaloneDirectives = [ ShortDateTimePipe, ShortTimePipe, ShortDatePipe, + UtcToLocalPipe, ...standaloneDirectives, ], imports: [ @@ -85,6 +87,7 @@ const standaloneDirectives = [ ShortDateTimePipe, ShortTimePipe, ShortDatePipe, + UtcToLocalPipe, ], providers: [LocalizationPipe, provideHttpClient(withInterceptorsFromDi())], }) diff --git a/npm/ng-packs/packages/core/src/lib/pipes/index.ts b/npm/ng-packs/packages/core/src/lib/pipes/index.ts index 1a981ca041..f0c7b4ff60 100644 --- a/npm/ng-packs/packages/core/src/lib/pipes/index.ts +++ b/npm/ng-packs/packages/core/src/lib/pipes/index.ts @@ -5,3 +5,4 @@ export * from './to-injector.pipe'; export * from './short-date.pipe'; export * from './short-time.pipe'; export * from './short-date-time.pipe'; +export * from './utc-to-local.pipe'; diff --git a/npm/ng-packs/packages/core/src/lib/pipes/utc-to-local.pipe.ts b/npm/ng-packs/packages/core/src/lib/pipes/utc-to-local.pipe.ts new file mode 100644 index 0000000000..6e5245fc6e --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/pipes/utc-to-local.pipe.ts @@ -0,0 +1,45 @@ +import { Pipe, PipeTransform, Injectable, inject } from '@angular/core'; +import { TimezoneService } from '../services'; + +@Injectable() +@Pipe({ + name: 'utcToLocal', + standalone: false, +}) +export class UtcToLocalPipe implements PipeTransform { + protected readonly timezoneService = inject(TimezoneService); + private readonly timezone: string; + + constructor() { + this.timezone = this.timezoneService.getTimezone(); + } + + transform( + value: string | Date | null | undefined, + locale: string = navigator.language, + options?: Intl.DateTimeFormatOptions, + ): string { + if (!value) return ''; + + try { + const utcDate = new Date(value + 'Z'); // Ensure it's treated as UTC + + const formatOptions: Intl.DateTimeFormatOptions = options || { + year: 'numeric', + month: 'short', + day: 'numeric', + hour: '2-digit', + minute: '2-digit', + }; + + const formatter = new Intl.DateTimeFormat(locale, { + ...formatOptions, + timeZone: this.timezone, + }); + + return formatter.format(utcDate); + } catch (err) { + return ''; + } + } +}