---
name: parse_date_or_default
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func ParseDateOrDefault(s string, dflt time.Time, endOfDay bool) time.Time"
description: "Parsea s como fecha (YYYY-MM-DD) o datetime (RFC3339Nano). Retorna dflt si s esta vacio o no encaja en ninguno de los dos formatos. Si endOfDay es true y el formato fue YYYY-MM-DD, ajusta al ultimo nanosegundo del dia (util para rangos de fechas inclusivos por el final)."
tags: [date, parse, time, default, range, YYYY-MM-DD, RFC3339Nano]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports:
  - time
params:
  - name: s
    desc: "Cadena a parsear. Formatos aceptados: '2006-01-02' (YYYY-MM-DD) o RFC3339Nano. String vacio activa el valor por defecto."
  - name: dflt
    desc: "Valor time.Time a retornar cuando s esta vacio o no coincide con ningun formato soportado."
  - name: endOfDay
    desc: "Si es true y el input fue YYYY-MM-DD, suma 24h-1ns para apuntar al ultimo nanosegundo del dia. No tiene efecto sobre RFC3339Nano ni sobre el retorno de dflt."
output: "time.Time parseado desde s, ajustado si endOfDay=true y formato YYYY-MM-DD; o dflt si s esta vacio o es invalido."
tested: true
tests:
  - "string vacio retorna dflt"
  - "formato invalido retorna dflt"
  - "YYYY-MM-DD sin endOfDay retorna inicio de dia"
  - "YYYY-MM-DD con endOfDay retorna ultimo nanosegundo del dia"
  - "RFC3339Nano sin endOfDay retorna timestamp exacto"
  - "RFC3339Nano con endOfDay no se ajusta"
  - "endOfDay false con dflt no lo modifica"
test_file_path: "functions/core/parse_date_or_default_test.go"
file_path: "functions/core/parse_date_or_default.go"
source_repo: "https://github.com/egutierrez/fn_registry/apps/kanban"
source_license: "private"
source_file: "apps/kanban/backend/metrics.go"
---

## Ejemplo

```go
dflt := time.Now().UTC()

// Inicio de rango (incluye el dia completo desde las 00:00)
from := ParseDateOrDefault("2024-01-01", dflt, false)

// Fin de rango (incluye hasta el ultimo nanosegundo del dia)
to := ParseDateOrDefault("2024-01-31", dflt, true)

// Timestamp exacto desde RFC3339Nano (no se ajusta aunque endOfDay=true)
ts := ParseDateOrDefault("2024-01-15T12:00:00Z", dflt, true)

// Valor invalido → dflt
fallback := ParseDateOrDefault("no-es-fecha", dflt, false)
```

## Notas

Unifica las dos funciones originales `parseDateOrDefault` y `parseEndDateOrDefault`
de `apps/kanban/backend/metrics.go:132-156` en una sola funcion parametrica.
`time.Parse` es deterministico, por lo que la funcion es pura aunque use el paquete `time`.
