# PkInputFormat: typed round-trip for pk-input type="date"/"number"

> Plainkit 0.28.0. Generated by scripts/build-skills.mjs from PkInputFormat.cs. Do not edit: change the source and run the generator.

`PkInput`'s `Value` stays plain `string` (the same text the element exchanges with the DOM: `yyyy-MM-dd` for `type="date"`, invariant-culture numeric text for `type="number"`) — it is not generic, so it takes no typed `DateTime`/`decimal`/`int` directly. `PkInputFormat` is a small set of pure static helpers for the format/parse glue every consumer of a typed date or amount otherwise re-derives by hand. Each parse method's contract: empty or invalid text becomes `null` (or the documented fallback for `ParseInt`), never the previous value — a static method that only takes the text cannot reach for "the previous value" even by accident.

```razor
<PkInput Type="date" Value="@PkInputFormat.FormatDate(_dueDate)"
         ValueChanged="@(text => _dueDate = PkInputFormat.ParseDate(text))" />

<PkInput Type="number" Value="@PkInputFormat.FormatNumber(_amount)"
         ValueChanged="@(text => _amount = PkInputFormat.ParseNumber(text))" />
```

## PkInputFormat

| Member | Description |
|---|---|
| `public static string FormatDate(DateTime? value)` | Formats a date for `pk-input type="date"`'s `Value`: `yyyy-MM-dd`, invariant culture. Returns `""` for `null` (the empty string the element expects for no value). |
| `public static DateTime? ParseDate(string? text)` | Parses `pk-input type="date"`'s `Value` text back to a date, using TryParseExact(string?, string, IFormatProvider?, DateTimeStyles, out DateTime) against `yyyy-MM-dd`, invariant culture. Empty or text that does not match that exact format returns `null` — never the previous value, never a thrown exception. |
| `public static string FormatNumber(decimal? value)` | Formats a decimal for `pk-input type="number"`'s `Value`: invariant-culture text. Returns `""` for `null`. |
| `public static decimal? ParseNumber(string? text)` | Parses `pk-input type="number"`'s `Value` text back to a non-negative decimal, using TryParse(string?, NumberStyles, IFormatProvider?, out decimal) with Number and invariant culture. Empty text, text that fails to parse, and negative values all return `null` — never the previous value, never a thrown exception. Use this for amounts that must never be negative (quantities, prices); a field that legitimately allows negative numbers needs its own parse, not this one. |
| `public static int ParseInt(string? text, int fallback = 0)` | Parses `pk-input type="number"`'s `Value` text back to a whole number, using TryParse(string?, NumberStyles, IFormatProvider?, out int) with Integer and invariant culture. Unlike ParseNumber, this returns a non-nullable `int`: empty or invalid text returns fallback (default `0`) rather than a nullable "no value" — the right shape for a whole-number field (a count, a step) that always needs some number to work with. Callers that need to tell "no value" apart from a real zero should use ParseNumber instead and round or convert themselves. |
