Skip to content

Dates and timezone ​

Decide whether a field represents a calendar date, a local wall time or an instant before choosing its model. A date picker display, a DTO value and the request's timezone header serve different purposes.

Choose a representation ​

Business valueRepresentationExample
Publication dateDate-only string2026-10-04
Daily opening timeTime-only string09:30
Local appointment to be resolved in a named zoneLocal date-time plus explicit zone2026-10-04T09:30, Asia/Shanghai
A completed event's instantOffset-bearing timestamp2026-10-04T01:30:00Z

AbpDatePicker uses string/null models and does not convert a local appointment to UTC. The backend DTO and your business rules determine conversion. An ambiguous daylight-saving time requires a policy; the control does not choose one automatically.

Format values for display ​

Create src/utils/date-display.ts:

ts
export function formatInstant(iso: string, culture: string, timeZone: string): string {
  const date = new Date(iso);
  if (Number.isNaN(date.getTime())) return '—';
  return new Intl.DateTimeFormat(culture, {
    dateStyle: 'medium',
    timeStyle: 'short',
    timeZone,
  }).format(date);
}

export function formatCalendarDate(value: string, culture: string): string {
  // UTC is used only to format a date-only value without shifting the calendar day.
  const [year, month, day] = value.split('-').map(Number);
  if (!year || !month || !day) return '—';
  return new Intl.DateTimeFormat(culture, { dateStyle: 'medium', timeZone: 'UTC' }).format(
    new Date(Date.UTC(year, month - 1, day)),
  );
}

Call formatInstant(record.createdAt, localization.currentLang.value, 'Asia/Shanghai') inside a computed or template-facing function. It expects a valid offset-bearing ISO timestamp. Call formatCalendarDate('2026-10-04', culture) for a valid date-only DTO string. This deliberately uses UTC for formatting to preserve the calendar day; it does not convert a birthday into an instant.

Never format a date-only field by parsing it as UTC and then rendering in an arbitrary local zone: that can show the previous day. Do not silently serialize a local date-time with toISOString() without establishing the user's intended timezone.

Framework request header ​

When application configuration has clock.kind === 'Utc', the timezone interceptor supplies __timezone. It uses setting.values['Abp.Timing.TimeZone'], falling back to the browser's Intl-resolved zone. An explicitly supplied header is preserved. skipAddingHeader skips framework header additions for that request.

This header gives the backend request context; it does not rewrite dates in your JSON body or choose the date picker's model format. Inspect effective application configuration when a tenant or user setting changes, and refresh it after changing an effective timezone.

Check date behavior ​

Test date-only values near midnight, an offset-bearing instant displayed in two zones, an empty optional field and the backend's DST rule. Keep invalid data feedback visible rather than saving a guessed timezone. See HTTP, settings and localization.

Unofficial community project. MIT licensed. Not affiliated with Volosoft.