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

commercial-calendar-ts

v1.0.0

Published

Professional TypeScript library for 30/360 commercial calendar calculations. Ideal for fintech, banking, payroll systems, and financial applications.

Readme

Calendario Comercial TypeScript 30/360

TypeScript Jest License: MIT NPM Ready

Librería TypeScript profesional para cálculos financieros usando la convención de conteo de días 30/360 (también conocida como Bond Basis o 30/360 US).

Ideal para: Sistemas bancarios, aplicaciones de nómina, cálculo de intereses, liquidaciones laborales, y aplicaciones fintech que requieren precisión en cálculos de días.

Instalación¿Qué es 30/360?APIEjemplosCasos de Uso


📋 Tabla de Contenidos


📘 ¿Qué es el Calendario Comercial 30/360?

El método 30/360 es una convención de conteo de días ampliamente utilizada en finanzas donde:

  • Cada mes tiene exactamente 30 días
  • Cada año tiene exactamente 360 días
  • Los días 31 se normalizan a 30

Fórmula Matemática

La fórmula básica para calcular días entre dos fechas es:

$$ \text{Días} = (Y_2 - Y_1) \times 360 + (M_2 - M_1) \times 30 + (D_2 - D_1) $$

Donde:

  • $Y_1, Y_2$ = Años (inicio, fin)
  • $M_1, M_2$ = Meses (inicio, fin)
  • $D_1, D_2$ = Días (inicio, fin)

Ajustes:

  • Si $D_1 = 31$, entonces $D_1 = 30$
  • Si $D_2 = 31$ y $D_1 \geq 30$, entonces $D_2 = 30$

Variantes del Método 30/360

Existen varias variantes del método 30/360:

| Convención | También Conocida Como | Uso Principal | |------------|----------------------|---------------| | 30/360 US | Bond Basis, NASD | Bonos corporativos y municipales en EE.UU. | | 30E/360 | Eurobond Basis | Mercados de eurobonos | | 30E/360 ISDA | 30E/360 ISDA | Derivados de tasas de interés | | 30/360 German | 30E/360 ICMA | Bonos alemanes |

Esta librería implementa 30/360 US (Bond Basis), la más utilizada en Latinoamérica para cálculos laborales y financieros.


💼 ¿Por qué es Importante en Finanzas?

1. Simplicidad en Cálculos

En lugar de contar días calendario reales (que varían entre 28-31 días por mes), el método 30/360 simplifica dramáticamente los cálculos financieros:

// ❌ Calendario Real: Complejo
// Enero: 31 días, Febrero: 28/29 días, Marzo: 31 días...

// ✅ Calendario 30/360: Uniforme
// Todos los meses: 30 días, Todos los años: 360 días

2. Estándar en la Industria

  • Bonos Corporativos: El 90% de bonos corporativos en EE.UU. usan 30/360
  • Swaps de Tasas: Mercados de derivados OTC
  • Cálculos Laborales: Legislación laboral en varios países latinoamericanos
  • Software Bancario: SAP, Oracle Financials, sistemas de core bancario

3. Consistencia Legal

Muchas jurisdicciones requieren por ley el uso de calendario comercial para:

  • Cálculo de cesantías / severance pay
  • Liquidaciones laborales
  • Intereses de préstamos específicos
  • Bonificaciones prorrateadas

4. Predictibilidad

Los cálculos son reproducibles y auditables:

// Mismo input = Mismo output, siempre
calculateWorkedDaysInYear('2025-01-15', '2025-06-15', 2025);
// Resultado: 150 días (5 meses × 30)
// No importa si febrero tiene 28 o 29 días

📦 Instalación

npm install commercial-calendar-ts

O clona el repositorio:

git clone https://github.com/YamiCueto/commercial-calendar-ts.git
cd commercial-calendar-ts
npm install

🚀 Inicio Rápido

import { calculateWorkedDaysInYear, getWorkedYears } from 'commercial-calendar-ts';

// Ejemplo 1: Calcular días trabajados en un año específico
const days = calculateWorkedDaysInYear('2025-01-15', '2025-06-15', 2025);
console.log(days); // 150 días (5 meses × 30)

// Ejemplo 2: Período multi-año
const startDate = '2023-11-01';
const endDate = '2024-08-15';
const years = getWorkedYears(startDate, endDate);

years.forEach(year => {
  const daysInYear = calculateWorkedDaysInYear(startDate, endDate, year);
  console.log(`${year}: ${daysInYear} días`);
});
// Output:
// 2023: 60 días
// 2024: 225 días

📚 API Reference

calculateWorkedDaysInYear(startDate, endDate, targetYear)

Calcula el número de días trabajados en un año específico usando la convención 30/360.

Parámetros:

| Parámetro | Tipo | Descripción | |-----------|------|-------------| | startDate | string | Fecha de inicio en formato YYYY-MM-DD | | endDate | string | Fecha de fin en formato YYYY-MM-DD | | targetYear | number | Año objetivo para el cálculo |

Retorno:

| Tipo | Descripción | |------|-------------| | number | Número de días trabajados en el año objetivo (0-360) |

Reglas de Cálculo:

  1. Ambos días incluidos: La fecha de inicio y fin se cuentan
  2. Ajuste día 31: Los días 31 se convierten automáticamente en día 30
  3. Intersección: Solo cuenta días dentro del año objetivo
  4. Regla especial: Cuando los días del mes son iguales y hay diferencia de meses, no se suma +1 adicional

Ejemplos:

// Mismo día
calculateWorkedDaysInYear('2025-01-01', '2025-01-01', 2025);
// → 1 día

// Días consecutivos
calculateWorkedDaysInYear('2025-01-01', '2025-01-02', 2025);
// → 2 días

// Un mes exacto
calculateWorkedDaysInYear('2025-01-15', '2025-02-15', 2025);
// → 30 días

// Múltiples meses
calculateWorkedDaysInYear('2025-01-01', '2025-06-30', 2025);
// → 180 días (6 meses × 30)

// Año completo
calculateWorkedDaysInYear('2025-01-01', '2025-12-31', 2025);
// → 360 días

// Período multi-año (solo cuenta días de 2024)
calculateWorkedDaysInYear('2023-11-15', '2024-03-20', 2024);
// → 80 días (solo del 1 de enero al 20 de marzo de 2024)

// Día 31 ajustado
calculateWorkedDaysInYear('2025-01-31', '2025-02-28', 2025);
// → 30 días (31 de enero se trata como 30)

Edge Cases Cubiertos:

// Período fuera del año objetivo
calculateWorkedDaysInYear('2023-01-01', '2023-12-31', 2025);
// → 0 días

// Período que no intersecta
calculateWorkedDaysInYear('2025-06-01', '2025-08-31', 2024);
// → 0 días

// Año bisiesto (no afecta, todos los meses son 30 días)
calculateWorkedDaysInYear('2024-02-01', '2024-02-29', 2024);
// → 30 días (febrero también tiene 30 días en 30/360)

getWorkedYears(startDate, endDate)

Extrae todos los años que intersectan con el período de trabajo.

Parámetros:

| Parámetro | Tipo | Descripción | |-----------|------|-------------| | startDate | string | Fecha de inicio en formato YYYY-MM-DD | | endDate | string | Fecha de fin en formato YYYY-MM-DD |

Retorno:

| Tipo | Descripción | |------|-------------| | number[] | Array de años en orden ascendente |

Ejemplo:

getWorkedYears('2022-11-15', '2024-03-20');
// → [2022, 2023, 2024]

getWorkedYears('2025-01-01', '2025-12-31');
// → [2025]

parseLocalYMD(dateString)

Función auxiliar para parsear fechas en formato YYYY-MM-DD sin problemas de zona horaria.

Parámetros:

| Parámetro | Tipo | Descripción | |-----------|------|-------------| | dateString | string | Fecha en formato YYYY-MM-DD |

Retorno:

| Tipo | Descripción | |------|-------------| | Date | Objeto Date con hora 00:00:00 local |

Ejemplo:

import { parseLocalYMD } from 'commercial-calendar-ts/utils/formatter/localYMD';

const date = parseLocalYMD('2025-06-15');
// → Date object: 2025-06-15T00:00:00 (hora local)

💡 Ejemplos

Ejemplo 1: Cálculo de Cesantías / Severance Pay

interface ResultadoCesantias {
  year: number;
  baseSalary: number;
  daysWorked: number;
  amount: number;
}

function calcularCesantias(
  fechaIngreso: string,
  fechaRetiro: string,
  salarioMensual: number
): ResultadoCesantias[] {
  const years = getWorkedYears(fechaIngreso, fechaRetiro);
  const resultados: ResultadoCesantias[] = [];

  years.forEach(year => {
    const daysWorked = calculateWorkedDaysInYear(fechaIngreso, fechaRetiro, year);
    
    if (daysWorked > 0) {
      // Fórmula legal: (Salario × Días Trabajados) / 360
      const amount = (salarioMensual * daysWorked) / 360;
      
      resultados.push({
        year,
        baseSalary: salarioMensual,
        daysWorked,
        amount: Math.round(amount)
      });
    }
  });

  return resultados;
}

// Uso
const cesantias = calcularCesantias(
  '2020-03-15',  // Fecha de ingreso
  '2024-11-30',  // Fecha de retiro
  3500000        // Salario mensual
);

console.log(cesantias);
/* Output:
[
  { year: 2020, baseSalary: 3500000, daysWorked: 285, amount: 2771250 },
  { year: 2021, baseSalary: 3500000, daysWorked: 360, amount: 3500000 },
  { year: 2022, baseSalary: 3500000, daysWorked: 360, amount: 3500000 },
  { year: 2023, baseSalary: 3500000, daysWorked: 360, amount: 3500000 },
  { year: 2024, baseSalary: 3500000, daysWorked: 330, amount: 3212500 }
]
*/

// Total cesantías
const total = cesantias.reduce((sum, item) => sum + item.amount, 0);
console.log(`Total cesantías: $${total.toLocaleString('es-CO')}`);
// → Total cesantías: $16,483,750

Ejemplo 2: Cálculo de Intereses con 30/360

interface InterestCalculation {
  principal: number;
  rate: number;
  startDate: string;
  endDate: string;
  days: number;
  interest: number;
}

function calcularInteres(
  principal: number,
  tasaAnual: number,  // Tasa anual (ej: 0.12 = 12%)
  fechaInicio: string,
  fechaFin: string
): InterestCalculation {
  // Usar solo el año de inicio para el cálculo
  const year = new Date(fechaInicio).getFullYear();
  const days = calculateWorkedDaysInYear(fechaInicio, fechaFin, year);
  
  // Fórmula: I = P × r × (d/360)
  const interest = principal * tasaAnual * (days / 360);
  
  return {
    principal,
    rate: tasaAnual,
    startDate: fechaInicio,
    endDate: fechaFin,
    days,
    interest: Math.round(interest * 100) / 100
  };
}

// Uso: Préstamo de $10,000,000 al 12% anual
const calculo = calcularInteres(
  10000000,    // Principal
  0.12,        // 12% anual
  '2025-01-15',
  '2025-04-15'
);

console.log(calculo);
/* Output:
{
  principal: 10000000,
  rate: 0.12,
  startDate: '2025-01-15',
  endDate: '2025-04-15',
  days: 90,
  interest: 300000
}
*/

console.log(`Interés a pagar: $${calculo.interest.toLocaleString('es-CO')}`);
// → Interés a pagar: $300,000

Ejemplo 3: Bonificaciones Prorrateadas

function calcularBonificacionProrrateada(
  bonusAnual: number,
  fechaIngreso: string,
  fechaCorte: string
): number {
  const year = new Date(fechaCorte).getFullYear();
  const diasTrabajados = calculateWorkedDaysInYear(fechaIngreso, fechaCorte, year);
  
  // Bonificación prorrateada: (Bonus Anual × Días Trabajados) / 360
  const bonusProrateado = (bonusAnual * diasTrabajados) / 360;
  
  return Math.round(bonusProrateado);
}

// Uso
const bonus = calcularBonificacionProrrateada(
  6000000,      // Bonus anual
  '2025-04-01', // Fecha de ingreso
  '2025-12-31'  // Fecha de corte
);

console.log(`Bonus prorrateado: $${bonus.toLocaleString('es-CO')}`);
// → Bonus prorrateado: $4,500,000
// (270 días trabajados de 360 posibles)

Más ejemplos en: /examples


🔄 Comparación de Convenciones de Calendario

Tabla Comparativa

| Convención | Días/Mes | Días/Año | Ajuste Día 31 | Uso Principal | |------------|----------|----------|---------------|---------------| | 30/360 US (Esta librería) | 30 | 360 | Sí | Bonos corporativos, cálculos laborales | | Actual/Actual | Real | Real | No | Bonos del tesoro, mercados gubernamentales | | Actual/360 | Real | 360 | No | Préstamos bancarios, líneas de crédito | | Actual/365 | Real | 365 | No | UK gilts, algunos mercados europeos | | 30E/360 | 30 | 360 | Sí (diferente) | Eurobonos |

Ejemplo de Diferencias

// Período: 15 de enero a 15 de marzo de 2024

// 30/360 US (esta librería)
calculateWorkedDaysInYear('2024-01-15', '2024-03-15', 2024);
// → 60 días (2 meses × 30)

// Actual/Actual (calendario real)
// Enero: 17 días (15-31)
// Febrero: 29 días (año bisiesto)
// Marzo: 15 días
// → 61 días

// Diferencia: 1 día

¿Cuándo Usar Cada Convención?

Usa 30/360 cuando:

  • ✅ Calcules cesantías o liquidaciones laborales
  • ✅ Trabajes con bonos corporativos o municipales
  • ✅ Necesites simplicidad y reproducibilidad
  • ✅ La legislación local lo requiera
  • ✅ Implementes sistemas de nómina

Usa Actual/Actual cuando:

  • ✅ Trabajes con bonos del tesoro
  • ✅ Necesites máxima precisión con días reales
  • ✅ Calcules intereses de mercados gubernamentales

Usa Actual/360 cuando:

  • ✅ Calcules intereses de préstamos bancarios
  • ✅ Trabajes con líneas de crédito comercial
  • ✅ Implementes sistemas de tesorería

🎯 Casos de Uso

1. Sistemas de Nómina (Payroll Systems)

// Calcular días trabajados para liquidación
const diasLiquidacion = calculateWorkedDaysInYear(
  empleado.fechaIngreso,
  empleado.fechaRetiro,
  añoActual
);

const liquidacion = {
  cesantias: (salario * diasLiquidacion) / 360,
  primaServicios: (salario * diasLiquidacion) / 360,
  vacaciones: (salario * diasLiquidacion) / 720
};

2. Plataformas de Inversión (Investment Platforms)

// Calcular rendimientos de bonos
const diasInversion = calculateWorkedDaysInYear(
  fechaCompra,
  fechaVencimiento,
  año
);

const rendimiento = principal * (tasaCupon / 100) * (diasInversion / 360);

3. Core Bancario (Banking Core Systems)

// Cálculo de intereses moratorios
const diasMora = calculateWorkedDaysInYear(
  fechaVencimiento,
  fechaPagoReal,
  año
);

const interesMoratorio = saldoPendiente * tasaMora * (diasMora / 360);

4. Aplicaciones Fintech

// Robo-advisors, préstamos P2P, crowdfunding
const diasPrestamo = calculateWorkedDaysInYear(
  fechaDesembolso,
  fechaPago,
  año
);

const interesDevengado = montoDesembolsado * tasa * (diasPrestamo / 360);

5. Software de RRHH (HR Software)

// Cálculo de beneficios prorrateados
const diasTrabajados = calculateWorkedDaysInYear(
  fechaIngreso,
  fechaCorte,
  año
);

const beneficioProrrateado = beneficioAnual * (diasTrabajados / 360);

Documentación completa de casos de uso: USE-CASES.md


🧪 Tests

La librería incluye 18 tests exhaustivos que cubren:

Edge Cases Cubiertos

  1. Mismo día: Fecha inicio = Fecha fin
  2. Días consecutivos: Diferencia de 1 día
  3. Meses exactos: Del día 15 al día 15 del siguiente mes
  4. Años completos: 360 días
  5. Períodos multi-año: Distribución correcta por año
  6. Día 31: Ajuste automático a día 30
  7. Febrero: Tratado como mes de 30 días
  8. Períodos fuera del año objetivo: Retorna 0
  9. Intersecciones parciales: Solo días dentro del año

Ejecutar Tests

# Ejecutar todos los tests
npm test

# Tests con coverage
npm run test:coverage

# Tests en modo watch
npm run test:watch

Resultados

Test Suites: 1 passed, 1 total
Tests:       18 passed, 18 total
Snapshots:   0 total
Time:        1.1 s

Coverage:
--------------------|---------|----------|---------|---------|
File                | % Stmts | % Branch | % Funcs | % Lines |
--------------------|---------|----------|---------|---------|
All files           |     100 |      100 |     100 |     100 |
 calculateWorked... |     100 |      100 |     100 |     100 |
 getWorkedYears.ts  |     100 |      100 |     100 |     100 |
 localYMD.ts        |     100 |      100 |     100 |     100 |
--------------------|---------|----------|---------|---------|

📁 Estructura del Proyecto

commercial-calendar-ts/
├── calculateWorkedDaysInYear.ts       # Función principal
├── calculateWorkedDaysInYear.test.ts  # Suite de tests
├── getWorkedYears.ts                  # Extractor de años
├── utils/
│   └── formatter/
│       └── localYMD.ts                # Date parser
├── examples/
│   ├── severance-pay.ts               # Ejemplo: Cesantías
│   ├── interest-calculation.ts        # Ejemplo: Intereses
│   └── worked-days.ts                 # Ejemplo: Días trabajados
├── docs/
│   └── USE-CASES.md                   # Casos de uso detallados
├── package.json
├── tsconfig.json
├── jest.config.js
├── .npmignore
├── LICENSE
└── README.md

🗺️ Roadmap

v1.1.0 (Próximo Release)

  • [ ] Soporte para 30E/360 (Eurobond Basis)
  • [ ] Soporte para Actual/360
  • [ ] Soporte para Actual/365
  • [ ] CLI tool para cálculos rápidos
  • [ ] Publicación en NPM

v1.2.0

  • [ ] Plugin para Excel/Google Sheets
  • [ ] API REST opcional
  • [ ] Soporte para múltiples monedas
  • [ ] Calculadora web interactiva

v2.0.0

  • [ ] Soporte para 30/360 ISDA
  • [ ] Cálculo de intereses compuestos
  • [ ] Amortización de préstamos
  • [ ] Integración con sistemas ERP

🤝 Contribuciones

¡Las contribuciones son bienvenidas! Por favor:

  1. Fork el repositorio
  2. Crea una rama (git checkout -b feature/nueva-funcionalidad)
  3. Commit tus cambios (git commit -am 'Add: nueva funcionalidad')
  4. Push a la rama (git push origin feature/nueva-funcionalidad)
  5. Abre un Pull Request

Guías de contribución: Asegúrate de que todos los tests pasen y la cobertura se mantenga en 100%.


👤 Autor

Yami Cueto


📄 Licencia

MIT License - Ver LICENSE para más detalles.


🙏 Agradecimientos

  • Basado en estándares ISDA y NASD para convenciones de conteo de días
  • Inspirado en librerías financieras como QuantLib y Apache Commons Math
  • Especificaciones de Bond Market Association

📚 Referencias


🔒 Seguridad

Si encuentras vulnerabilidades de seguridad, por favor envía un email a [email protected] en lugar de abrir un issue público.


⚡ Performance

Esta librería es extremadamente eficiente:

  • 0 dependencias externas (solo devDependencies para testing)
  • < 5KB minificado
  • O(1) complejidad para cálculos individuales
  • Type-safe con TypeScript
  • Tree-shakeable para bundlers modernos

¿Preguntas? ¿Sugerencias?
Abre un issue o un discussion


Hecho con ❤️ para desarrolladores fintech y sistemas bancarios