npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mafesoftware/fechas-ar

v0.3.0

Published

Dias de calendario vs instantes, con zona horaria explicita. Sin dependencias.

Readme

@mafesoftware/fechas-ar

Dias de calendario vs instantes, con zona horaria explicita. Sin dependencias.

Parte de la familia de paquetes de MAFE Software: sin dependencias de framework, sin ORM, y puros salvo donde se indique. Todo lo que sale a la red acepta un fetch inyectable, así que los tests corren sin red.

bun add @mafesoftware/fechas-ar

La documentación de cada función está en src/index.ts, con el motivo de cada decisión al lado. Los tests (tests/) son la otra mitad de la documentación: cada uno dice qué bug evita.

API

Días de calendario (se leen en UTC)

Un día elegido en un <input type="date"> ("2026-08-19") se guarda como medianoche UTC; estas funciones lo leen de vuelta tal cual, sin que la zona del navegador le reste un día.

import { diaCorto, diaLargo, paraInputFecha, hoyEnInput } from "@mafesoftware/fechas-ar";

diaCorto("2026-08-19");        // "19/08/26"
diaLargo("2026-08-19");        // "19 de agosto de 2026"
paraInputFecha(new Date("2026-08-19T00:00:00Z")); // "2026-08-19"
hoyEnInput();                  // el día de hoy, anclado a America/Argentina/Buenos_Aires

Instantes (se muestran en la zona de la institución)

import { horaCorta, diaDeInstante, diaLargoDeInstante, diaYHora, haceCuanto } from "@mafesoftware/fechas-ar";

const ingreso = new Date("2026-08-26T11:48:00Z"); // 08:48 en Argentina (UTC-3)
horaCorta(ingreso);          // "08:48"
diaDeInstante(ingreso);      // "26 ago"
diaLargoDeInstante(ingreso); // "26 de agosto de 2026"
diaYHora(ingreso);           // "26/08/26, 08:48"
haceCuanto(ingreso, new Date("2026-08-26T12:48:00Z")); // "hace 1 hora"

Zona horaria: día ↔ instante y rangos

import { diaEnZona, inicioDelDia, finDelDia, instanteEnZona, instanteDelDia } from "@mafesoftware/fechas-ar";

diaEnZona(ingreso);                 // "2026-08-26" (el día de calendario en la zona)
inicioDelDia("2026-08-26");         // el instante en que arranca el 26 en la zona
finDelDia("2026-08-26");            // el instante en que arranca el 27 (límite exclusivo)
instanteEnZona("2026-08-26", "08:00"); // las 08:00 de pared del 26, en la zona
instanteDelDia("2026-08-26");       // un instante representativo del día (mediodía UTC)

ZONA_AR ("America/Argentina/Buenos_Aires") es la zona por defecto en todas estas funciones; un club de otro país pasa la suya como último parámetro.

Aritmética de días y de horarios

import { sumarDiasISO, diasEntre, diaDeSemana, aMinutos, deMinutos } from "@mafesoftware/fechas-ar";

sumarDiasISO("2026-08-19", 5); // "2026-08-24"
diasEntre("2026-08-19", "2026-08-24"); // 5
diaDeSemana("2026-08-19"); // 3 (miércoles; 0 = domingo)
aMinutos("08:30");  // 510
deMinutos(510);      // "08:30"

Rangos: varios días y horarios que cruzan la medianoche

import { rangoDeDias, rangoHorario } from "@mafesoftware/fechas-ar";

rangoDeDias("2026-11-14", "2026-11-16"); // "14/11/26 al 16/11/26"
rangoDeDias("2026-11-14", null);         // "14/11/26" (un solo día)
rangoDeDias("2026-11-14", "2026-11-16", formatearFechaDeLaApp); // con el formato de días propio

rangoHorario("21:00:00", "04:00:00");    // "21:00 a 04:00 (+1 día)" (trasnoche)
rangoHorario("09:00", null);             // "desde las 09:00"
rangoHorario(null, null);                // null

API 0.2

Una tercera familia, de calendario puro: recibe y devuelve "YYYY-MM-DD"/"YYYY-MM", nunca un Date. Un formato roto o un calendario imposible ("2026-02-30") tira ErrorFecha, no devuelve null ni NaN.

Errores (errores.ts)

import { ErrorFecha, type CodigoErrorFecha } from "@mafesoftware/fechas-ar";

try {
  // ...
} catch (e) {
  if (e instanceof ErrorFecha) {
    e.codigo; // "formato_invalido" | "fecha_invalida" | "dia_invalido"
  }
}

Períodos mensuales (periodo.ts)

import { esPeriodo, etiquetaPeriodo, periodoDe, periodoLargo, sumarPeriodos, type Periodo } from "@mafesoftware/fechas-ar";

esPeriodo("2026-09");        // true
esPeriodo("2026-13");        // false: no hay mes 13
periodoDe("2026-09-24");     // "2026-09"
sumarPeriodos("2026-11", 3); // "2027-02" (n negativo resta; n === 0 devuelve el mismo período)
etiquetaPeriodo("2026-09");  // "sep-2026"
periodoLargo("2026-11");     // "noviembre de 2026" (para títulos y textos corridos)

Meses de cuota (meses.ts)

import { sumarMeses } from "@mafesoftware/fechas-ar";

// dia es el día objetivo (1..31 o "ultimo"), clamped al último día real del
// mes resultante: nunca se desborda al mes siguiente.
sumarMeses("2026-01-31", 1, 31);     // "2026-02-28" (2026 no es bisiesto)
sumarMeses("2028-01-31", 1, 31);     // "2028-02-29" (2028 sí lo es)
sumarMeses("2026-01-15", 2, "ultimo"); // "2026-03-31"

Días hábiles (habiles.ts)

Los feriados se inyectan (spec 06 §3.1): cada organización trae los suyos.

import { esHabil, siguienteHabil, anteriorHabil } from "@mafesoftware/fechas-ar";

const feriados = new Set(["2026-09-04"]); // viernes feriado

esHabil("2026-09-05", feriados);       // false: sábado
esHabil("2026-09-04", feriados);       // false: feriado (aunque sea viernes)
siguienteHabil("2026-09-04", feriados); // "2026-09-07": viernes feriado + fin de semana -> lunes
siguienteHabil("2026-09-01", feriados); // "2026-09-01": ya es hábil, se devuelve igual (documentado)
anteriorHabil("2026-09-06", feriados);  // "2026-09-03": domingo -> sábado y viernes tampoco sirven (feriado) -> jueves

Probar

bun test