# DatePicker

> Selección de fecha en un calendario mensual, con rango permitido opcional y devolución del día elegido.

Source: https://crossfly.dev/es/docs/ui/widgets/datepicker — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# DatePicker

`DatePicker` selecciona una **fecha** en un calendario mensual, con navegación por mes, por año y cuadrículas de selección rápida de mes/año. Sigue el patrón de los pickers: devuelve el valor vía `getAnswer()` consumido por `show(onAnswer)` al cerrar (ver [`Picker`](/docs/ui/widgets/picker)).

> 🟡 · **Paquete:** `dev.crossfly.ui.picker` · **Extiende:** `Picker` · **Estilo:** `DatePickerStyle`

## Cuándo usar
- Recoger una fecha (cumpleaños, agendamiento, vencimiento) con UI de calendario.

## Cuándo NO usar
- Recoger hora → usa [`TimePicker`](/docs/ui/widgets/timepicker).

## Apariencia
Tarjeta con barra de título, fila de mes (`< Nombre >`), fila de año (`< 2026 >`) y una cuadrícula de 6×7 celdas de días. Se dimensiona en ~90% de `Screen.minSize`.

## Ejemplo completo (copiar, pegar y ejecutar)
```java
package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.picker.*;

/** Pantalla principal ejecutable. Apunta el launcher (classname) y corre: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      Button abrir = new Button("Escolher data");
      abrir.onAction(c ->
      {
         DatePicker dp = new DatePicker().title("Data de nascimento");
         dp.show(answer -> Hint.show("Data: " + (String) answer, 2000));
      });
      add(LAY_AUTO, abrir);
   }
}
```

> Los fragmentos siguientes muestran **solo el núcleo** (lo que va dentro de `onShow()`). Para ejecutarlos, colócalos en el esqueleto `MainWindow` de arriba.

## Uso básico
```java
DatePicker dp = new DatePicker();
dp.show(answer -> campoData.setText((String) answer));
```

## Constructores
| Constructor | Descripción |
|---|---|
| `DatePicker()` | Sin parámetros; inicia en la fecha de hoy. |

## Propiedades y personalización (fluidos)
| Método | Tipo | Por defecto | Qué hace |
|---|---|---|---|
| `setDate(int year, int month, int day)` | año, mes **0-based**, día 1-based | hoy | Preselecciona la fecha. |
| `title(String)` | `String` | `"Date Picker"` | Texto de la barra de título. |
| `yearRange(int before, int after)` | `int`, `int` | 30, 10 | Años antes/después para la cuadrícula de años. |
| `style(DatePickerStyle)` | estilo | skin | Estilo personalizado. |
| `getSelectedDay()` | `int` | — | Día seleccionado (1-based). |
| `getDisplayYear()` / `getDisplayMonth()` | `int` | — | Año / mes mostrados (mes 0-based). |

## Callbacks y eventos
| Callback | Cuándo se dispara |
|---|---|
| `onSelect(Action)` | al tocar un día (recibe el propio `DatePicker`). |
| `show(onAnswer)` | al cerrar, entrega la `String` de la fecha (si se confirmó). |

`getAnswer()` devuelve la fecha en el formato de `DateTimeUtils.formatDate` — **el orden (DMY/MDY/YMD) y el separador dependen de `LocaleFormats`**, no es fijo `dd/MM/yyyy`.

## Estados
- Navegar entre meses pone `selectedDay` a `-1` (ningún día marcado hasta que el usuario elija).
- Estilos por estado: hoy, seleccionado, otro mes, normal (vía `DatePickerStyle`).

### Fecha de nacimiento
```java
DatePicker dp = new DatePicker()
   .title("Data de nascimento")
   .yearRange(100, 0)     // hasta 100 años atrás, ninguno en el futuro
   .setDate(2000, 0, 1);  // 01/Ene/2000 (¡mes 0-based!)

dp.onSelect(p ->
{
   DatePicker d = (DatePicker) p;
   Debug.log("dia=" + d.getSelectedDay() + " mes=" + (d.getDisplayMonth() + 1));
});

dp.show(answer ->
{
   String data = (String) answer; // ej.: "01/01/2000" según LocaleFormats
   campoData.setText(data);
});
```

## Buenas prácticas
- Recuerda que **`month` es 0-based** en `setDate`.
- Para localizar nombres de meses/días, reasigna las constantes públicas `MONTH_NAMES`/`MONTH_SHORT`.

## Errores comunes
- **Pasar mes 1-based en `setDate`** — enero es `0`.
- **Esperar formato fijo** — la salida sigue `LocaleFormats.dateFormat`/`dateSeparator`.
- **`yearRange` como clamp de selección** — solo limita la *navegación* de años; cualquier día del mes mostrado es seleccionable.

## Ver también
- Guía del área: [`ui/`](/docs/ui) · Recetas: [`cookbook/`](/docs/cookbook)
- Base del patrón: [`Picker`](/docs/ui/widgets/picker)
- Componentes relacionados: [`TimePicker`](/docs/ui/widgets/timepicker)
