Skip to content

Display, format, sort, and filter dates correctly by using the date cell type.

Overview

The date cell type lets you treat cell values as dates: format how they are displayed, validate input, and use an interactive date picker in the editor. Handsontable supports two configurations: the object-style configuration using the native Intl.DateTimeFormat API (recommended), and a string-style configuration using Moment.js (deprecated).

Date cell type demo

In the following demo, multiple columns use the date cell type with different formatting styles:

  • Product date: Date with short style formatting
  • Payment date: Customized date formatting
  • Registration date: Customized date formatting with weekday, month, day, year
TypeScript
/* file: app.component.ts */
import { Component, ViewChild, ViewEncapsulation, HostListener, ElementRef } from '@angular/core';
import { GridSettings, HotTableComponent } from '@handsontable/angular-wrapper';
interface CarData {
car: string;
product_date: string;
payment_date: string;
registration_date: string;
}
@Component({
selector: 'example1-date-cell-type',
standalone: false,
template: `
<div class="example-controls-container">
<div class="controls">
<div class="theme-dropdown" #dropdownRef>
<button
class="theme-dropdown-trigger"
type="button"
aria-haspopup="listbox"
[attr.aria-expanded]="isOpen"
(click)="toggleDropdown()"
>
<span>{{ selectedLabel }}</span>
<svg class="theme-dropdown-chevron" aria-hidden="true" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6l6 -6"/></svg>
</button>
<ul class="theme-dropdown-menu" role="listbox" *ngIf="isOpen">
<li
*ngFor="let opt of localeOptions"
role="option"
[attr.aria-selected]="locale === opt.value"
(click)="selectLocale(opt.value)"
>
{{ opt.label }}
</li>
</ul>
</div>
</div>
</div>
<div>
<hot-table [data]="data" [settings]="gridSettings"></hot-table>
</div>
`,
encapsulation: ViewEncapsulation.None
})
export class Example1DateCellTypeComponent {
@ViewChild(HotTableComponent, { static: false }) readonly hotTable!: HotTableComponent;
isOpen = false;
locale = 'en-US';
56 collapsed lines
readonly localeOptions = [
{ value: 'ar-AR', label: 'Arabic (Global)' },
{ value: 'cs-CZ', label: 'Czech (Czechia)' },
{ value: 'de-CH', label: 'German (Switzerland)' },
{ value: 'de-DE', label: 'German (Germany)' },
{ value: 'en-US', label: 'English (United States)' },
{ value: 'es-MX', label: 'Spanish (Mexico)' },
{ value: 'fa-IR', label: 'Persian (Iran)' },
{ value: 'fr-FR', label: 'French (France)' },
{ value: 'hr-HR', label: 'Croatian (Croatia)' },
{ value: 'it-IT', label: 'Italian (Italy)' },
{ value: 'ja-JP', label: 'Japanese (Japan)' },
{ value: 'ko-KR', label: 'Korean (Korea)' },
{ value: 'lv-LV', label: 'Latvian (Latvia)' },
{ value: 'nb-NO', label: 'Norwegian Bokmal (Norway)' },
{ value: 'nl-NL', label: 'Dutch (Netherlands)' },
{ value: 'pl-PL', label: 'Polish (Poland)' },
{ value: 'pt-BR', label: 'Portuguese (Brazil)' },
{ value: 'ru-RU', label: 'Russian (Russia)' },
{ value: 'sr-SP', label: 'Serbian Latin (Serbia)' },
{ value: 'zh-CN', label: 'Chinese (Simplified, China)' },
{ value: 'zh-TW', label: 'Chinese (Traditional, Taiwan)' },
];
readonly data: CarData[] = [
{
car: 'Mercedes A 160',
product_date: '2002-06-15',
payment_date: '2002-05-20',
registration_date: '2002-07-01',
},
{
car: 'Citroën C4 Coupe',
product_date: '2007-03-22',
payment_date: '2007-02-28',
registration_date: '2007-04-10',
},
{
car: 'Audi A4 Avant',
product_date: '2011-09-08',
payment_date: '2011-08-15',
registration_date: '2011-09-20',
},
{
car: 'Opel Astra',
product_date: '2012-01-30',
payment_date: '2012-01-10',
registration_date: '2012-02-14',
},
{
car: 'BMW 320i Coupe',
product_date: '2004-11-12',
payment_date: '2004-10-20',
registration_date: '2004-12-01',
},
];
readonly gridSettings: GridSettings = {
colHeaders: ['Car', 'Product date', 'Payment date', 'Registration date'],
locale: this.locale,
36 collapsed lines
columns: [
{
type: 'text',
data: 'car',
},
{
type: 'intl-date',
data: 'product_date',
dateFormat: { dateStyle: 'short' },
},
{
type: 'intl-date',
data: 'payment_date',
dateFormat: {
month: 'long',
day: 'numeric',
year: 'numeric',
},
},
{
type: 'intl-date',
data: 'registration_date',
dateFormat: {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
},
},
],
columnSorting: true,
filters: true,
dropdownMenu: true,
height: 'auto',
autoWrapRow: true,
autoWrapCol: true,
};
get selectedLabel(): string {
return this.localeOptions.find((o) => o.value === this.locale)?.label || '';
}
constructor(private elementRef: ElementRef) {}
toggleDropdown(): void {
this.isOpen = !this.isOpen;
}
selectLocale(value: string): void {
this.locale = value;
this.isOpen = false;
this.hotTable?.hotInstance?.updateSettings({ locale: this.locale });
}
@HostListener('document:click', ['$event'])
onDocumentClick(event: MouseEvent): void {
if (!this.elementRef.nativeElement.querySelector('.theme-dropdown')?.contains(event.target)) {
this.isOpen = false;
}
}
@HostListener('document:keydown', ['$event'])
onKeydown(event: KeyboardEvent): void {
if (event.key === 'Escape') {
this.isOpen = false;
}
}
}
/* end-file */
/* file: app.module.ts */
import { NgModule, ApplicationConfig } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { registerAllModules } from 'handsontable/registry';
import { HOT_GLOBAL_CONFIG, HotGlobalConfig, HotTableModule } from '@handsontable/angular-wrapper';
import { CommonModule } from '@angular/common';
import { NON_COMMERCIAL_LICENSE } from '@handsontable/angular-wrapper';
/* start:skip-in-compilation */
import { Example1DateCellTypeComponent } from './app.component';
/* end:skip-in-compilation */
// register Handsontable's modules
registerAllModules();
export const appConfig: ApplicationConfig = {
providers: [
{
provide: HOT_GLOBAL_CONFIG,
useValue: {
license: NON_COMMERCIAL_LICENSE,
} as HotGlobalConfig
}
],
};
@NgModule({
imports: [ BrowserModule, HotTableModule, CommonModule ],
declarations: [ Example1DateCellTypeComponent ],
providers: [...appConfig.providers],
bootstrap: [ Example1DateCellTypeComponent ]
})
export class AppModule { }
/* end-file */
HTML
<div>
<example1-date-cell-type></example1-date-cell-type>
</div>

Use the date cell type

Use the object-style configuration by setting the type option to 'intl-date' and dateFormat to an object (recommended). The locale is controlled via the locale option.

// set the date cell type for the entire grid (Intl, recommended)
settings1 = {
type: 'intl-date',
locale: 'en-US',
dateFormat: {
year: 'numeric',
month: '2-digit',
day: '2-digit'
}
};
// set the date cell type for a single column
settings2 = {
columns: [
{
type: 'intl-date',
locale: 'en-US',
dateFormat: { dateStyle: 'short' }
}
]
};
// set the date cell type for a single cell
settings3 = {
cell: [
{
row: 0,
col: 2,
type: 'intl-date',
locale: 'en-US',
dateFormat: { dateStyle: 'medium' }
}
]
};

For intl-date cells, source data must be in ISO 8601 date format (YYYY-MM-DD) for dates to work correctly. The dateFormat object only affects how dates are displayed; sorting and filtering rely on the underlying ISO value.

Format dates

To control how dates are displayed in cell renderers, use the dateFormat option.

Since Handsontable 17.0, the recommended approach is the object form of dateFormat with the intl-date cell type, which uses the native Intl.DateTimeFormat API. The locale is controlled separately via the locale option.

The dateFormat option accepts all properties of Intl.DateTimeFormat options. Use it with type: 'intl-date'.

settings = {
columns: [
{
type: 'intl-date',
locale: 'en-US',
dateFormat: {
year: 'numeric',
month: '2-digit',
day: '2-digit'
}
},
{
type: 'intl-date',
locale: 'de-DE',
dateFormat: { dateStyle: 'long' }
}
]
};

Date-specific options

Style shortcuts:

PropertyPossible valuesDescription
dateStyle'full', 'long', 'medium', 'short'Date formatting style (weekday, day, month, year, era)
timeStyle'full', 'long', 'medium', 'short'Time part style (hour, minute, second, timeZoneName); use for date+time

Date-time component options:

PropertyPossible valuesDescription
weekday'long', 'short', 'narrow'Weekday representation
era'long', 'short', 'narrow'Era representation
year'numeric', '2-digit'Year representation
month'numeric', '2-digit', 'long', 'short', 'narrow'Month representation
day'numeric', '2-digit'Day representation
dayPeriod'narrow', 'short', 'long'Day period (e.g. “am”)
hour'numeric', '2-digit'Hour (if time included)
minute'numeric', '2-digit'Minute
second'numeric', '2-digit'Second
fractionalSecondDigits1, 2, 3Fraction-of-second digits
timeZoneName'long', 'short', 'shortOffset', 'longOffset', 'shortGeneric', 'longGeneric'Time zone display

Locale and other options:

PropertyPossible valuesDescription
localeMatcher'best fit' (default), 'lookup'Locale matching algorithm
calendar'chinese', 'gregory', 'persian', etc.Calendar to use
numberingSystem'latn', 'arab', 'hans', etc.Numbering system
timeZoneIANA time zone (e.g. 'UTC', 'America/New_York')Time zone for formatting
hour12true, false12-hour vs 24-hour time
hourCycle'h11', 'h12', 'h23', 'h24'Hour cycle
formatMatcher'basic', 'best fit' (default)Format matching algorithm

For a complete reference, see the dateFormat API documentation or MDN: Intl.DateTimeFormat.

Using string format with Moment.js (deprecated)

The date cell type with a string dateFormat is still supported but will be removed in next major release.

Deprecated options:

OptionDescriptionReplacement
dateFormat (string)Moment.js format (e.g. 'DD/MM/YYYY')Use intl-date with dateFormat object (see above)
correctFormatAuto-correct entered date to match formatMay be handled by valueParser and/or valueSetter options
datePickerConfigPikaday options for the date pickerintl-date uses a native date picker; no direct equivalent

Migration example:

// Before (deprecated)
columns: [{
type: 'date',
dateFormat: 'YYYY-MM-DD',
}]
// After (recommended)
columns: [{
type: 'intl-date',
locale: 'en-US',
dateFormat: {
year: 'numeric',
month: '2-digit',
day: '2-digit',
}
}]

Editor behavior

The dateFormat option controls how dates are displayed in the cell. The editor (date picker or text input) may show the value in a normalized form; for intl-date, the underlying value remains in ISO 8601 format.

Related guides

Configuration options

Core methods

Hooks