# React Time Picker: Tippen, 12 oder 24 Stunden je nach Locale

> Bau einen React Time Picker, der Eingaben wie 1430 oder 2p versteht, 12 oder 24 Stunden nach Locale zeigt, belegte Zeiten sperrt und am Handy iOS-Räder öffnet.

- Autor: [Serban Rusu](https://wingo-ui.com/blog/authors/serban), Founder of Wingo UI
- Veröffentlicht: 19. Okt. 2026
- Kategorie: [Komponenten-Guides](https://wingo-ui.com/de/blog/category/components)
- Lesezeit: 8 Min.
- Kanonische URL: https://wingo-ui.com/de/blog/react-time-picker
- Englische Fassung: https://wingo-ui.com/blog/react-time-picker

## Kurz gesagt

Ein guter React Time Picker lässt dich die Uhrzeit so tippen, wie du sie sagst („1430“, „2:30pm“, „2p“), zeigt 12 oder 24 Stunden je nach Locale, während der Wert immer "HH:mm" in 24 Stunden bleibt, und sperrt Zeiten außerhalb der Öffnungszeiten. Am Smartphone öffnet er Räder in einem Bottom Sheet statt der Tastatur. Der Time Picker von Wingo UI erledigt das aus einem Wert-String, einer Locale sowie min, max und disabledTimes.

Du brauchst einen React Time Picker für einen Abholtermin, ein Meeting oder ein Lieferfenster. Als Erstes probierst du das native `<input type="time">`, und oft bleibt es dabei: Das Popup lässt sich nicht stylen, ein Besucher aus den USA sieht 2:30 PM, während dein Design 14:30 zeigt, und eine Mittagspause kannst du nicht ausgrauen. Die meisten Pakete ersetzen es durch eine Reihe von Feldern für Stunde und Minute, die du einzeln ausfüllst. Dieser Guide zeigt, was ein Zeitfeld stattdessen können sollte („1430“ oder „2p“ in einem Rutsch tippen, der Locale folgen, Öffnungszeiten respektieren, am Handy Räder öffnen), welche Props im [Time Picker](https://wingo-ui.com/components/time-picker) von Wingo UI zählen, und ein vollständiges Formularbeispiel.

## Wann reicht input type="time"?

Wenn du es nicht stylen, keine einzelnen Zeiten sperren und nicht zwischen 12 und 24 Stunden wählen musst. Das native Element kostet nichts, ist barrierefrei und funktioniert von Haus aus mit Formularen. Laut [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/time) ist sein Wert immer ein `HH:mm`-String (oder `HH:mm:ss`) in 24 Stunden, während die Locale des Nutzers oder der Browser die Anzeige bestimmt. Es unterstützt `min`, `max` und `step`, und ein `min`, das nach `max` liegt, reicht über Mitternacht hinaus.

Schwierig wird es, wenn das Feld wie der Rest deines Formulars aussehen oder Geschäftsregeln folgen soll. Du kannst keinen Button „Jetzt“ ergänzen, nicht zeigen, dass 13 Uhr belegt ist, und das Stundenformat nicht für alle Besucher gleich halten. Selbst das langjährige [react-time-picker](https://github.com/wojtekmaj/react-time-picker) rät im README, das native Zeitfeld zu erwägen, wenn du keine Unterstützung für alte Browser und keine seiner Extras brauchst.

## Was muss ein React Time Picker können?

Fünf Dinge, und das native Feld deckt zwei davon ab:

1. **In einem Rutsch tippen.** „1430“, „14.30“, „9“, „2:30pm“ und „2p“ sollten genau das bedeuten, was sie sagen. Bei getrennten Feldern für Stunde und Minute musst du Tab drücken oder auf den automatischen Sprung warten.
2. **12 oder 24 Stunden nach Locale.** en-US schreibt 2:30 PM, en-GB schreibt 14:30. Der gespeicherte Wert sollte sich mit der Anzeige nicht ändern.
3. **Grenzen und gesperrte Zeiten.** Öffnungszeiten, eine Mittagspause, belegte Termine. Gesperrte Optionen sollten deaktiviert aussehen, bevor jemand das Formular abschickt.
4. **Eine Auswahl für die Maus.** Spalten mit Stunden und Minuten, die aktuelle Zeit in der Mitte.
5. **Ein Smartphone-Layout.** Räder in einem Bottom Sheet, damit beim Antippen keine Tastatur den halben Bildschirm verdeckt.

## Wie schneiden die Optionen für einen React Time Picker ab?

Wer nach „time input react“ sucht, findet vor allem segmentierte Felder, ein Kästchen pro Stunde, Minute und AM / PM. Die Fakten stammen aus der öffentlichen Doku der Projekte, Stand Oktober 2026.

| Option | Wie du tippst | 12 / 24 Stunden | Wert | Grenzen |
|---|---|---|---|---|
| [`<input type="time">`](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/time) | Segmente, UI des Browsers | Von der Locale oder vom Browser gewählt | `"HH:mm"` | `min`, `max`, `step`, reicht über Mitternacht hinaus |
| [react-time-picker](https://github.com/wojtekmaj/react-time-picker) (MIT) | Getrennte Felder für Stunde, Minute und AM / PM, dazu eine Uhr | `format` (Unicode-Tokens wie `HH:mm` oder `h:mm a`) und `locale` | Date oder String (`"22:15:00"`) | `minTime`, `maxTime` |
| [Mantine TimePicker](https://mantine.dev/dates/time-picker/) | Getrennte Segmente, optional ein Dropdown mit Spalten | `format="12h"` ergänzt ein AM-/PM-Segment | `"HH:mm"` oder `"HH:mm:ss"` | `min`, `max`, `presets` |
| [Dice UI Time Picker](https://diceui.com/docs/components/time-picker) | Inline-Segmente mit automatischem Sprung, Popover mit Spalten | Aus der Locale erkannt, `locale` überschreibt es | 24 Stunden | `minuteStep`, `hourStep`, `secondStep` |
| [Wingo UI Time Picker](https://wingo-ui.com/components/time-picker) (Pro) | Ein Textfeld: „1430“, „2:30pm“, „2p“ | `locale` oder `hourCycle="h12"` / `"h23"` | `"HH:mm"` | `min`, `max`, `disabledTimes`, `minuteStep`, `strictStep` |

Mantine ist die bessere Wahl, wenn deine App schon Mantine nutzt, und Dice UI, wenn du einen kostenlosen shadcn Time Picker willst und dir Segmente reichen. Segmente sind eine echte Designentscheidung: Mit ihnen lässt sich keine ungültige Zeit tippen. Der Preis: Wer schnell tippt, kann nicht einfach „1430“ schreiben und Tab drücken, und genau um diesen Fall geht es im Rest des Guides.

## Wie funktioniert das Tippen einer Uhrzeit?

Das Feld liest den Text, wenn du es verlässt oder Enter drückst. Tipp `14`, und ein Doppelpunkt erscheint, „1430“ liest sich also schon beim Tippen als 14:30. Aus „9“ wird 09:00, aus „930“ wird 09:30, „14h30“ und „14.30“ klappen auch, und ein `a`, `am`, `p` oder `pm` am Ende legt die Tageshälfte fest. Text, der sich nicht auswerten lässt, färbt das Feld beim Tippen rot und springt beim Verlassen auf die letzte gültige Zeit zurück. Eine Zeit außerhalb von `min` und `max` wird auf die nächste Grenze gesetzt.

ArrowUp und ArrowDown ändern die Minuten um `minuteStep` und übernehmen sofort, Shift mit einer Pfeiltaste springt um eine Stunde, und beide überspringen gesperrte Zeiten. Alt + ArrowDown öffnet das Panel mit dem Fokus auf der Stundenspalte.

```bash
npx wingo-ui@latest add time-picker
```

```tsx
"use client";

import { useState } from "react";
import { TimePicker } from "@/components/ui/time-picker";

// ein termin ist gesperrt, wenn er in der pause von 13 bis 14 uhr beginnt
const lunchBreak = (time: string) => time >= "13:00" && time < "14:00";

export function PickupTime() {
  const [time, setTime] = useState("11:30");

  return (
    <TimePicker
      label="Abholzeit"
      description="Der Laden hat von 9 bis 18 Uhr geöffnet."
      value={time}
      onValueChange={setTime}
      locale="en-US"
      min="09:00"
      max="18:00"
      minuteStep={15}
      disabledTimes={lunchBreak}
      clearable
      showNow
      name="pickup_time"
    />
  );
}
```

`disabledTimes` bekommt `"HH:mm"`-Strings, und weil sie führende Nullen haben, kannst du sie als Text vergleichen. Gesperrte Optionen sind in den Spalten deaktiviert, eine Stunde ohne freie Minuten wird grau, und eine getippte gesperrte Zeit springt auf den nächsten freien Termin.

Tipp 2:30pm oder 1430 in das Feld unten und drück Tab, dann klick hinein, um die Spalten zu sehen.

> Live-Demo (Time Picker): Tipp 1430 oder 2p und drück Tab, dann klick ins Feld für die Spalten: Die Mittagsstunde um 1 PM ist ausgegraut, und ArrowUp ändert die Minuten. Probier sie unter [Time Picker](https://wingo-ui.com/components/time-picker) aus und installier sie mit `npx wingo-ui@latest add time-picker`.

## Wie zeige ich 12 oder 24 Stunden nach Locale?

Gib `locale` mit, und `hourCycle="auto"` (der Standard) folgt ihr: en-US zeigt 2:30 PM, en-GB zeigt 14:30, und Mitternacht liest sich in 12 Stunden als 12:00 AM. Der Wert ist unabhängig von der Anzeige `"HH:mm"` in 24 Stunden, ein Feld mit 12 und eins mit 24 Stunden teilen sich also denselben State und dieselbe Datenbankspalte. Um das Format festzulegen, nimm `hourCycle="h23"` für 24 Stunden überall oder `"h12"` für AM und PM. Wenn du nach „react time picker 24 stunden“ gesucht hast: `hourCycle="h23"` ist die ganze Antwort.

Ohne `locale`-Prop liest die Komponente die Locale aus `UIProvider`, dann aus dem nächsten `LocaleProvider`, dann das `lang` der Seite und die Sprache des Browsers. Ist nichts davon gesetzt, rendert sie auf dem Server und während der Hydration `en-US`, weil `Intl` sonst mit der Sprache des Servers formatieren würde und das HTML dann nicht übereinstimmt. Setz die React Time Picker Locale einmal an der Wurzel der App, damit schon der erste Paint stimmt. `UIProvider` ist eine Client Component, das Root Layout kann also eine Server Component bleiben:

```tsx
import { UIProvider } from "@/lib/ui-config";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en-GB">
      <body>
        <UIProvider locale="en-GB">{children}</UIProvider>
      </body>
    </html>
  );
}
```

Hier ist dasselbe Feld mit `locale="en-GB"`. Tipp trotzdem „2:30pm“: Es wird als 14:30 gelesen.

> Live-Demo (Time Picker): Dasselbe Feld in en-GB: Zeiten lauten 14:30, es gibt keine AM-/PM-Spalte, und 2:30pm wird trotzdem erkannt. Probier sie unter [Time Picker](https://wingo-ui.com/components/time-picker) aus und installier sie mit `npx wingo-ui@latest add time-picker`.

## Was passiert am Smartphone?

Unter 768px öffnet das Feld ein Bottom Sheet mit Rädern, die wie unter iOS einrasten, und das Eingabefeld ist schreibgeschützt und hat `inputMode="none"`, damit keine Tastatur aufgeht. Die Räder ticken spürbar unter dem Daumen, wo der Browser Vibration unterstützt (Chromium-Browser unter Android; Safari hat keine [Vibration API](https://wingo-ui.com/de/blog/web-vibration-api-haptic-feedback)). Done übernimmt die Zeit; ziehst du das Sheet weg, bleibt die alte. Mit `responsive={false}` bekommen Smartphones stattdessen das Desktop-Panel.

Das Rad selbst wird als `TimePickerWheel` exportiert, für Wecker und kurze Listen. Für Dauern, Datumsangaben und andere Spalten ist das [Picker Wheel](https://wingo-ui.com/components/picker-wheel) die vollständige Komponente, und der [Guide zum React Wheel Picker](https://wingo-ui.com/de/blog/react-wheel-picker) erklärt, wie das native Scroll Snapping und die 3D-Zeilen funktionieren. Dieser Beitrag bleibt beim Feld zum Tippen.

## Wie schicke ich die Uhrzeit ab und validiere sie?

`name` rendert ein verstecktes Input-Feld mit dem `"HH:mm"`-Wert, ein normales Formular oder eine Server Action bekommt also denselben String, den das native Zeitfeld schicken würde. Das sichtbare Input hat keinen Namen. Ein Reset des Formulars setzt das Feld auf `defaultValue` zurück, und Enter übernimmt den getippten Text, bevor das Formular ihn liest.

Validier auf dem Server noch einmal, denn eine Grenze im Client ist nur Komfort:

```tsx
// app/pickup/actions.ts
"use server";

const TIME = /^([01]\d|2[0-3]):[0-5]\d$/;

export async function schedulePickup(formData: FormData) {
  const time = String(formData.get("pickup_time") ?? "");
  if (!TIME.test(time)) return { error: "Wähl eine gültige Uhrzeit." };
  if (time < "09:00" || time > "18:00") return { error: "Wähl eine Uhrzeit innerhalb der Öffnungszeiten." };
  // hier die abholung speichern
  return { ok: true };
}
```

Zeig einen Fehler vom Server über die Prop `error`: Er ersetzt die Beschreibung, markiert das Feld als ungültig und verknüpft die Meldung über `aria-describedby`. `withSeconds` stellt den Wert auf `"HH:mm:ss"` um und ergänzt eine Sekundenspalte, und `strictStep` rundet getippte Minuten beim Verlassen auf den Schritt (aus 14:37 wird bei einem Schritt von 5 Minuten 14:35).

## Ist der Time Picker barrierefrei?

Ja. Das Textfeld ist ein echtes Input, verknüpft mit Label und Beschreibung, mit einem Hinweis zum Format für Screenreader („Format HH:mm“, aus `labels.format`). Jede Spalte im Panel und jedes Rad ist eine Listbox mit Optionen. In den Spalten wandern ArrowUp und ArrowDown durch die Optionen und wählen sie aus, PageUp und PageDown springen fünf weiter, Home und End gehen an die Enden, ArrowLeft und ArrowRight wechseln die Spalte, Enter bestätigt und Escape gibt den Fokus ans Feld zurück. Jeder sichtbare und gesprochene Text steckt in `labels`, eine deutsche oder rumänische App übersetzt den Picker also, ohne ihn zu forken. Der [Guide zu React-Formularkomponenten](https://wingo-ui.com/de/blog/react-form-components-guide) wendet dieselben Regeln auf jedes Feld eines Formulars an.

## Was sind die typischen Fallen bei Zeitfeldern in React?

Vier Fehler zeigen sich, sobald echte Menschen das Feld nutzen: „2:30“ als Nachmittag lesen, formatierten Text speichern, den Tag vergessen und Zeitfenster über Nacht.

- **„2:30“ heißt in einem 12-Stunden-Feld 2:30 AM.** Ohne Tageshälfte liest der Parser die Stunde so, wie sie dasteht. Tipp „2:30p“, oder nimm 24 Stunden für Zeitpläne, die überwiegend nachmittags liegen.
- **Einen formatierten String speichern.** Speicher `"14:30"`, nie „2:30 PM“. Der formatierte Text ändert sich mit der Locale, der Wert nicht.
- **Eine Uhrzeit ohne Tag.** „14:30“ hat weder Zeitzone noch Datum. Wenn der genaue Moment zählt (ein Call über Zeitzonen hinweg, eine Erinnerung), nimm stattdessen ein Feld für Datum und Uhrzeit.
- **Zeitfenster über Nacht.** Eine Nachtschicht von 22:00 bis 06:00 ist `min="22:00"` und `max="06:00"`: Ein `min`, das nach `max` liegt, reicht über Mitternacht hinaus, wie beim nativen Feld.

## Wann nehme ich stattdessen den Date Time Picker?

Nimm den [Date Time Picker](https://wingo-ui.com/components/date-time-picker), wenn du einen absoluten Zeitpunkt brauchst: eine Buchung, eine Deadline, eine Erinnerung. Sein Wert ist ein `Date`, und er zeigt einen Kalender neben einer Spalte mit Zeitslots für den gewählten Tag, mit einer IANA-`timeZone`, Presets wie Tomorrow 9:00 und `getTimeSlots` für die Verfügbarkeit pro Tag (belegte Slots sind durchgestrichen). `name` schickt `value.toISOString()` ab.

```tsx
"use client";

import { useState } from "react";
import { DateTimePicker } from "@/components/ui/date-time-picker";

export function BookCall() {
  const [value, setValue] = useState<Date | null>(null);

  return (
    <DateTimePicker
      label="Call mit Liam Walker"
      value={value}
      onValueChange={setValue}
      minuteStep={30}
      startTime="09:00"
      endTime="17:00"
      disablePast
      timeZone="America/New_York"
      locale="en-US"
      name="call_at"
    />
  );
}
```

> Live-Demo (Date Time Picker): Wähl einen Tag, dann einen freien Termin: Belegte Zeiten sind durchgestrichen, die Zeitzone steht in der Fußzeile, und am Smartphone werden die Termine zu einer Reihe von Chips in einem Sheet. Probier sie unter [Date Time Picker](https://wingo-ui.com/components/date-time-picker) aus und installier sie mit `npx wingo-ui@latest add date-time-picker`.

Für ein Start- und ein Enddatum zeigt der [Guide zum React Date Range Picker](https://wingo-ui.com/de/blog/react-date-range-picker) den Kalender für Zeiträume.

## Wie füge ich ihn meinem Projekt hinzu?

Führ `npx wingo-ui@latest add time-picker` aus. Die CLI kopiert den Quellcode nach `components/ui`, ergänzt Button, Field, Drawer sowie die Helfer für Datum, Locale und Motion, die die Komponente importiert, und installiert die npm-Pakete, die sie brauchen, etwa `@radix-ui/react-popover`, `motion`, `lucide-react`, `vaul` für das Sheet am Smartphone und `date-fns` für die Datumshelfer. `npx wingo-ui@latest add date-time-picker` bringt zusätzlich den Calendar und das Select für die Zeitzone mit. Time Picker, Date Time Picker und Picker Wheel sind Pro-Komponenten ([Preise](https://wingo-ui.com/de/pricing)). Weitere Deep Dives zu einzelnen Komponenten findest du in der [Kategorie Komponenten-Guides](https://wingo-ui.com/de/blog/category/components).

## Komponenten in diesem Artikel

- [Time Picker](https://wingo-ui.com/components/time-picker) (Pro): A React time picker to type a time or pick it from columns, with 12 / 24 hours by locale, minute steps, limits and wheels on phones. Installation: `npx wingo-ui@latest add time-picker`
- [Date Time Picker](https://wingo-ui.com/components/date-time-picker) (Pro): A React date time picker: a calendar beside a column of free time slots, presets and a time zone label in one field, a sheet on phones. Installation: `npx wingo-ui@latest add date-time-picker`
- [Picker Wheel](https://wingo-ui.com/components/picker-wheel) (Pro): A React iOS-style picker wheel whose columns spin with momentum and snap on a 3D cylinder. Installation: `npx wingo-ui@latest add picker-wheel`

## Häufige Fragen

### Wie zeige ich in React einen Time Picker mit 24 Stunden?

Nimm eine Locale, die 24 Stunden schreibt, etwa en-GB oder de-DE, oder erzwing es über eine Option für den Stundenzyklus. Im Time Picker von Wingo UI zeigt hourCycle="h23" unabhängig von der Locale 14:30, und der Wert ist in beiden Fällen "14:30".

### Kann ich input type="time" auf 24 Stunden zwingen?

Nicht zuverlässig. Laut MDN wählt die Locale des Nutzers oder der Browser das Anzeigeformat, und es gibt kein Attribut, um das zu überschreiben. Der Wert ist immer HH:mm in 24 Stunden, nur die Anzeige ändert sich.

### Gibt es einen shadcn Time Picker?

shadcn/ui selbst hat Stand Oktober 2026 keine Time-Picker-Komponente; die Doku zum Date Picker kombiniert den Kalender mit einem separaten Zeitfeld. Registries von Drittanbietern füllen die Lücke: Dice UI installierst du über die shadcn CLI, den Time Picker von Wingo UI als Quellcode mit npx wingo-ui@latest add time-picker.

### Welches Wertformat sollte ein React Time Picker nutzen?

Speicher "HH:mm" in 24 Stunden, denselben String, den input type="time" abschickt. Er lässt sich als Text sortieren und vergleichen, übersteht einen Wechsel der Locale und ist auf dem Server leicht zu validieren.

### Ist der Time Picker von Wingo UI kostenlos?

Nein. Time Picker, Date Time Picker und Picker Wheel sind Pro-Komponenten. Field und Drawer, auf denen sie aufbauen, sind kostenlos, ebenso der Duration Picker.

---

Quelle: https://wingo-ui.com/de/blog/react-time-picker
