Skip to content
+

Calendar systems

Use the Date and Time Pickers with non-Gregorian calendars.

Jalali

You can use either the AdapterDateFnsJalali adapter, which is based on date-fns-jalali, or the AdapterMomentJalaali adapter, which is based on moment-jalaali.

The following demo shows how to use the date-fns-jalali adapter:

ب.ظ.⁩ ⁦12:00⁩ ⁦1400/11/12
import * as React from 'react';
import { prefixer } from 'stylis';
import rtlPlugin from '@mui/stylis-plugin-rtl';
import createCache from '@emotion/cache';
import { CacheProvider } from '@emotion/react';
import { AdapterDateFnsJalali } from '@mui/x-date-pickers/AdapterDateFnsJalali';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker';
import { createTheme, ThemeProvider, useTheme } from '@mui/material/styles';

// Create rtl cache
const cacheRtl = createCache({
  key: 'adapter-date-fns-jalali-demo',
  stylisPlugins: [prefixer, rtlPlugin],
});

export default function AdapterJalali() {
  // Inherit the theme from the docs site (dark/light mode)
  // @focus-start @padding 1
  const existingTheme = useTheme();

  const theme = React.useMemo(
    () => createTheme(existingTheme, { direction: 'rtl' }),
    [existingTheme],
  );

  return (
    <CacheProvider value={cacheRtl}>
      <ThemeProvider theme={theme}>
        <div dir="rtl">
          <LocalizationProvider dateAdapter={AdapterDateFnsJalali}>
            <DateTimePicker
              label="AdapterDateFnsJalali"
              defaultValue={new Date(2022, 1, 1, 12)}
              // Setting `dir="rtl"` on the paper is needed if the `<div dir="rtl />` does not contain the portaled element.
              // If you set `dir="rtl"` on the `<body />`, you can skip it.
              slotProps={{
                desktopPaper: {
                  dir: 'rtl',
                },
                mobilePaper: {
                  dir: 'rtl',
                },
              }}
            />
          </LocalizationProvider>
        </div>
      </ThemeProvider>
    </CacheProvider>
  );
}

The following demo shows how to use the moment-jalaali adapter:

۱۲:۰۰⁩ ⁦۱۴۰۰/۱۱/۱۲
import * as React from 'react';
import { prefixer } from 'stylis';
import rtlPlugin from '@mui/stylis-plugin-rtl';
import createCache from '@emotion/cache';
import { CacheProvider } from '@emotion/react';
import moment from 'moment-jalaali';
import { AdapterMomentJalaali } from '@mui/x-date-pickers/AdapterMomentJalaali';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker';
import { createTheme, ThemeProvider, useTheme } from '@mui/material/styles';

// Create rtl cache
const cacheRtl = createCache({
  key: 'adapter-moment-jalali-demo',
  stylisPlugins: [prefixer, rtlPlugin],
});

export default function AdapterMomentJalali() {
  // Inherit the theme from the docs site (dark/light mode)
  // @focus-start @padding 1
  const existingTheme = useTheme();

  const theme = React.useMemo(
    () => createTheme(existingTheme, { direction: 'rtl' }),
    [existingTheme],
  );

  return (
    <CacheProvider value={cacheRtl}>
      <ThemeProvider theme={theme}>
        <div dir="rtl">
          <LocalizationProvider dateAdapter={AdapterMomentJalaali}>
            <DateTimePicker
              label="AdapterMomentJalaali"
              defaultValue={moment('2022-02-01T12:00:00')}
              // Setting `dir="rtl"` on the paper is needed if the `<div dir="rtl />` does not contain the portaled element.
              // If you set `dir="rtl"` on the `<body />`, you can skip it.
              slotProps={{
                desktopPaper: {
                  dir: 'rtl',
                },
                mobilePaper: {
                  dir: 'rtl',
                },
              }}
            />
          </LocalizationProvider>
        </div>
      </ThemeProvider>
    </CacheProvider>
  );
}

Hijri

You can use the AdapterMomentHijri adapter, which is based on moment-hijri:

import * as React from 'react';
import moment from 'moment-hijri';
import { prefixer } from 'stylis';
import rtlPlugin from '@mui/stylis-plugin-rtl';
import createCache from '@emotion/cache';
import { CacheProvider } from '@emotion/react';
import Button from '@mui/material/Button';
import { createTheme, ThemeProvider, useTheme } from '@mui/material/styles';
import { AdapterMomentHijri } from '@mui/x-date-pickers/AdapterMomentHijri';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import type {
  DateTimePickerProps,
  DateTimePickerFieldProps,
} from '@mui/x-date-pickers/DateTimePicker';
import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker';
import { useValidation, validateDate } from '@mui/x-date-pickers/validation';
import {
  useSplitFieldProps,
  useParsedFormat,
  usePickerContext,
} from '@mui/x-date-pickers/hooks';

// Create rtl cache
const cacheRtl = createCache({
  key: 'adapter-moment-hijri-demo',
  stylisPlugins: [prefixer, rtlPlugin],
});

function ButtonDateTimeField(props: DateTimePickerFieldProps) {
  const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date');

  const pickerContext = usePickerContext();
  const parsedFormat = useParsedFormat();
  const { hasValidationError } = useValidation({
    validator: validateDate,
    value: pickerContext.value,
    timezone: pickerContext.timezone,
    props: internalProps,
  });

  const valueStr =
    pickerContext.value == null
      ? parsedFormat
      : pickerContext.value.format(pickerContext.fieldFormat);

  return (
    <Button
      {...forwardedProps}
      variant="outlined"
      color={hasValidationError ? 'error' : 'primary'}
      className={pickerContext.rootClassName}
      sx={pickerContext.rootSx}
      ref={pickerContext.triggerRef}
      onClick={() => pickerContext.setOpen((prev) => !prev)}
    >
      {pickerContext.label ? `${pickerContext.label}: ${valueStr}` : valueStr}
    </Button>
  );
}

function ButtonFieldDateTimePicker(props: DateTimePickerProps) {
  return (
    <DateTimePicker
      {...props}
      slots={{ ...props.slots, field: ButtonDateTimeField }}
    />
  );
}

export default function AdapterHijri() {
  // Inherit the theme from the docs site (dark/light mode)
  // @focus-start @padding 1
  const existingTheme = useTheme();

  const theme = React.useMemo(
    () => createTheme(existingTheme, { direction: 'rtl' }),
    [existingTheme],
  );

  return (
    <CacheProvider value={cacheRtl}>
      <ThemeProvider theme={theme}>
        <div dir="rtl">
          <LocalizationProvider dateAdapter={AdapterMomentHijri}>
            <ButtonFieldDateTimePicker
              defaultValue={moment(new Date(2022, 1, 1))}
              // moment-hijri support dates between 1356-01-01 and 1499-12-29 H (1937-03-14 and 2076-11-26)
              minDate={moment(new Date(1938, 0, 1))}
              maxDate={moment(new Date(2075, 11, 31))}
              // Setting `dir="rtl"` on the paper is needed if the `<div dir="rtl />` does not contain the portaled element.
              // If you set `dir="rtl"` on the `<body />`, you can skip it.
              slotProps={{
                desktopPaper: {
                  dir: 'rtl',
                },
                mobilePaper: {
                  dir: 'rtl',
                },
              }}
            />
          </LocalizationProvider>
        </div>
      </ThemeProvider>
    </CacheProvider>
  );
}

Buddhist

You can use the AdapterDayjsBuddhist adapter, which is based on dayjs. The adapter extends the buddhistEra plugin under the hood.

01/02/2565 12:00
import * as React from 'react';
import dayjs from 'dayjs';
import 'dayjs/locale/th';
import { AdapterDayjsBuddhist } from '@mui/x-date-pickers/AdapterDayjsBuddhist';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker';

export default function AdapterBuddhist() {
  return (
    <LocalizationProvider dateAdapter={AdapterDayjsBuddhist} adapterLocale="th">
      <DateTimePicker
        label="AdapterDayjsBuddhist"
        defaultValue={dayjs(new Date(2022, 1, 1, 12))}
      />
    </LocalizationProvider>
  );
}

The Buddhist Era calendar is used in Thailand and other Southeast Asian countries. It uses the same months and days as the Gregorian calendar but with a year offset of 543, for example, 2024 CE = 2567 BE.

Unsupported libraries

If you need to use a date library that is not supported yet, please open an issue in the MUI X repository.

API

See the documentation below for a complete reference to all of the props and classes available to the components mentioned here.