Vali-Duration
ValiDuration es un tipo de valor de duración decimal de alta precisión. Proporciona métodos de fábrica, operadores aritméticos, conversión de unidades, formateo e interoperabilidad fluida con TimeSpan.
Instalación
dotnet add package Vali-Duration
Struct ValiDuration
ValiDuration almacena su valor internamente como milisegundos decimal, evitando la deriva de punto flotante en las operaciones aritméticas.
Métodos de fábrica
| Método | Descripción |
|---|---|
ValiDuration.FromMilliseconds(decimal) | Crear desde milisegundos |
ValiDuration.FromSeconds(decimal) | Crear desde segundos |
ValiDuration.FromMinutes(decimal) | Crear desde minutos |
ValiDuration.FromHours(decimal) | Crear desde horas |
ValiDuration.FromDays(decimal) | Crear desde días |
ValiDuration.FromWeeks(decimal) | Crear desde semanas (7 días) |
ValiDuration.FromMonths(decimal) | Crear desde meses (promedio 30.4375 días) |
ValiDuration.FromYears(decimal) | Crear desde años (promedio 365.25 días) |
ValiDuration.FromTimeSpan(TimeSpan) | Crear desde un TimeSpan |
ValiDuration.Zero | Una duración de longitud cero |
var d1 = ValiDuration.FromHours(2.5m);
var d2 = ValiDuration.FromMinutes(90m);
var d3 = ValiDuration.FromTimeSpan(TimeSpan.FromDays(7));
var d4 = ValiDuration.Zero;
Propiedades
| Propiedad | Tipo | Descripción |
|---|---|---|
TotalMilliseconds | decimal | Valor total en milisegundos |
TotalSeconds | decimal | Valor total en segundos |
TotalMinutes | decimal | Valor total en minutos |
TotalHours | decimal | Valor total en horas |
TotalDays | decimal | Valor total en días |
var d = ValiDuration.FromHours(2.5m);
Console.WriteLine(d.TotalMinutes); // → 150
Console.WriteLine(d.TotalMilliseconds); // → 9_000_000
Métodos de instancia
As
Convierte la duración a un valor decimal en la unidad especificada:
var d = ValiDuration.FromDays(1.5m);
decimal hours = d.As(TimeUnit.Hours); // → 36
decimal mins = d.As(TimeUnit.Minutes); // → 2160
Firma: decimal As(TimeUnit unit)
Format
Formatea la duración como una cadena legible para humanos:
var d = ValiDuration.FromMinutes(90m);
Console.WriteLine(d.Format()); // → "1h 30m"
Console.WriteLine(d.Format(1)); // → "1.5 hours"
Firma: string Format(int decimalPlaces = 0)
ToTimeSpan
Convierte a un TimeSpan. Nota: TimeSpan usa double internamente, por lo que valores muy grandes o muy precisos pueden perder precisión:
var d = ValiDuration.FromHours(2.5m);
TimeSpan ts = d.ToTimeSpan();
// → TimeSpan de 2h 30m
Firma: TimeSpan ToTimeSpan()
Operadores aritméticos
ValiDuration admite todas las operaciones aritméticas estándar:
var a = ValiDuration.FromHours(1.5m);
var b = ValiDuration.FromMinutes(30m);
ValiDuration sum = a + b; // 2 horas
ValiDuration diff = a - b; // 1 hora
ValiDuration scaled = a * 2m; // 3 horas
ValiDuration halved = a / 2m; // 45 minutos
bool equal = a == b;
bool greater = a > b;
bool less = a < b;
Operadores de comparación
Se admiten los seis operadores de comparación (==, !=, <, <=, >, >=):
var oneHour = ValiDuration.FromHours(1m);
var twoHours = ValiDuration.FromHours(2m);
bool result = oneHour < twoHours; // → true
Conversiones implícitas
// Desde TimeSpan
ValiDuration d = TimeSpan.FromHours(2); // implícito
// A TimeSpan
TimeSpan ts = ValiDuration.FromMinutes(90m); // implícito
Ejemplo completo
public class BillingService
{
public void CalculateBilling(TimeSpan[] sessionDurations, decimal hourlyRate)
{
// Convertir todas las sesiones a ValiDuration
var durations = sessionDurations
.Select(ValiDuration.FromTimeSpan)
.ToArray();
// Sumar todas las sesiones
var total = durations.Aggregate(ValiDuration.Zero, (acc, d) => acc + d);
Console.WriteLine($"Total time: {total.Format(1)}");
Console.WriteLine($"Total hours: {total.TotalHours:F2}");
// Calcular facturación
decimal billableHours = total.As(TimeUnit.Hours);
decimal amount = billableHours * hourlyRate;
Console.WriteLine($"Billable: {billableHours:F2}h × ${hourlyRate}/h = ${amount:F2}");
// Verificar si supera la jornada de 8 horas
var workday = ValiDuration.FromHours(8m);
if (total > workday)
{
ValiDuration overtime = total - workday;
Console.WriteLine($"Overtime: {overtime.Format(1)}");
}
}
}