# Date and time formatting

This guide shows how to customize date/time formatting in SDK components.

## Best Practices

- Centralize formatting in i18n JSON to keep UI consistent across components.
- Use `timestampTranslationKey` only when you need per-instance overrides.
- Prefer `calendar` formats for conversational timelines and `format` for precise timestamps.
- Ensure locale-specific formats are complete to avoid English fallbacks.
- Test formatting with long dates and different locales to catch layout issues.

## SDK components displaying date & time

These SDK components display date/time:

- `ChannelPreviewStatus` - Component showing last message date and time in `ChannelList`.
- `ImageGalleryHeader` - Component showing the header in the `ImageGallery`.
- `InlineDateSeparator` - Component separating groups of messages in `MessageList`.
- `MessageEditedTimestamp` - Component showing edited message time when clicked on an edited message.
- `MessageSystem` - Component showing system message.
- `MessageTimestamp` - Component showing message timestamp.
- `StickyHeader` - Component showing sticky header on the top of the `MessageList`/`Channel`.

## Format Customization

Customize date/time formatting via the `i18n` JSON.

### Date & time formatting with i18n service

Formatting via i18n provides SDK-wide configuration stored in translation JSON. Advantages:

- It is centralized.
- It takes into consideration the locale out of the box.
- High granularity: per string, not per component.
- Reuse: apply the same configuration in multiple places via one translation key.
- Allows for custom formatting logic.

The default date time formatting configuration is stored in the JSON translation files. The default translation keys are namespaced with prefix `timestamp/` followed by the component name. For example, the message date formatting can be targeted via `timestamp/MessageTimestamp`, because the underlying component is called `MessageTimestamp`.

Override formatting in your translation JSON. Example:

```json
"timestamp/SystemMessage": "{{ timestamp | timestampFormatter(format: YYYY) }}",
```

You can also override the translation key via `timestampTranslationKey`. All listed components support it.

```tsx
import {
  MessageTimestampProps,
  MessageTimestamp,
} from "stream-chat-react-native";

const CustomMessageTimestamp = (props: MessageTimestampProps) => (
  <MessageTimestamp
    {...props}
    timestampTranslationKey="customTimestampTranslationKey"
  />
);
```

### Understanding the formatting syntax

Once default prop values are nulled, the JSON translation overrides formatting. Example:

```json
"timestamp/MessageSystem": "{{ timestamp | timestampFormatter(calendar: true) }}",
```

or with custom calendar formats:

```json
"timestamp/MessageSystem": "{{ timestamp | timestampFormatter(calendar: true; calendarFormats: {\"lastDay: \"[gestern um] LT\", \"lastWeek\": \"[letzten] dddd [um] LT\", \"nextDay\": \"[morgen um] LT\", \"nextWeek\": \"dddd [um] LT\", \"sameDay\": \"[heute um] LT\", \"sameElse\": \"L\"}) }}",
```

or with custom format:

```json
"timestamp/MessageTimestamp": "{{ timestamp | timestampFormatter(format: LT) }}",
```

Let's dissect the example:

- The curly brackets (`{{`, `}}`) indicate the place where a value will be interpolated (inserted) into the string.
- `timestamp` is the variable inserted into the string.
- The `|` character is a pipe that separates the variable from the formatting function.
- `timestampFormatter` converts the `timestamp` value into the desired format.
- `timestampFormatter` accepts the same parameters as the components (`calendar`, `calendarFormats`, `format`).

**Params**:

- `calendar` - This is a `Boolean` field to decide if the date format should be in calendar format or not. The default value is `false`.
- `calendarFormats` - This is an object that contains the formats for the calendar. The default value is `{ sameDay: 'LT', nextDay: 'LT', nextWeek: 'dddd', lastDay: 'dddd', lastWeek: 'dddd', sameElse: 'L' }`.
- `format` - This is a string that contains the format of the date.

If `calendar` is enabled, dates use relative words ("yesterday at ...", "last ..."). Customize via `calendarFormats`, which should cover all cases:

```js
{
  lastDay: '[gestern um] LT',
  lastWeek: '[letzten] dddd [um] LT',
  nextDay: '[morgen um] LT',
  nextWeek: 'dddd [um] LT',
  sameDay: '[heute um] LT',
  sameElse: 'L',
}
```

<admonition type="tip">

If any `calendarFormats` keys are missing, the library falls back to hard-coded English equivalents.

</admonition>

If `calendar` is enabled, `format` is ignored. Disable `calendar` to use `format`.

<admonition type="note">

The described rules follow the formatting rules required by the i18n library used under the hood - `i18next`. You can learn more about the rules in [the formatting section of the `i18next` documentation](https://www.i18next.com/translation-function/formatting#basic-usage).

</admonition>

### Custom date time formatter functions

You can also override the default `timestampFormatter` by providing a custom `Streami18n` instance:

```tsx
import { Chat, Streami18n } from "stream-chat-react-native";

const chatClient = "Your Chat client here";

const i18n = new Streami18n({
  formatters: {
    timestampFormatter: () => (val: string | Date) => {
      return new Date(val).getTime() + "";
    },
  },
});

export const ChatApp = ({ apiKey, userId, userToken }) => {
  return <Chat client={chatClient} i18nInstance={i18n}></Chat>;
};
```


---

This page was last updated at 2026-04-17T17:33:45.400Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react-native/v8/guides/date-time-formatting/](https://getstream.io/chat/docs/sdk/react-native/v8/guides/date-time-formatting/).