Vali-Time
IValiTime proporciona conversiones de unidades de tiempo de alta precisión usando aritmética decimal — eliminando la deriva de punto flotante habitual en las conversiones basadas en double.
Instalación
dotnet add package Vali-Time
Registro
builder.Services.AddValiTime();
// o mediante el meta-paquete:
builder.Services.AddValiTempo();
Enumeraciones
TimeUnit
Representa una unidad de medida de tiempo:
| Valor | Descripción |
|---|---|
Milliseconds | 1/1000 de un segundo |
Seconds | Unidad SI base de tiempo |
Minutes | 60 segundos |
Hours | 60 minutos |
Days | 24 horas |
Weeks | 7 días |
Months | Mes calendario (promedio 30.4375 días) |
Years | Año calendario (promedio 365.25 días) |
DatePart
Se usa al extraer componentes de un DateTime:
| Valor | Descripción |
|---|---|
Year | El componente año |
Month | El componente mes (1–12) |
Day | El componente día del mes |
Hour | El componente hora (0–23) |
Minute | El componente minuto |
Second | El componente segundo |
DayOfWeek | Día de la semana (0=Domingo) |
WeekStart
Define qué día inicia la semana, usado en los cálculos de semana del año:
| Valor | Descripción |
|---|---|
Sunday | La semana empieza el domingo (convención US) |
Monday | La semana empieza el lunes (estándar ISO 8601) |
API de IValiTime
Convert
Convierte un valor de una unidad de tiempo a otra:
decimal hours = time.Convert(90, TimeUnit.Minutes, TimeUnit.Hours);
// → 1.5
decimal ms = time.Convert(2.5m, TimeUnit.Seconds, TimeUnit.Milliseconds);
// → 2500
Firma: decimal Convert(decimal value, TimeUnit from, TimeUnit to)
SumTimes
Suma múltiples valores (todos en la misma unidad) y devuelve el total en una unidad destino:
decimal totalHours = time.SumTimes(
new[] { 30m, 45m, 90m },
TimeUnit.Minutes,
TimeUnit.Hours
);
// → 2.75
Firma: decimal SumTimes(IEnumerable<decimal> values, TimeUnit inputUnit, TimeUnit outputUnit)
SubtractTimes
Resta un valor de tiempo de otro:
decimal diff = time.SubtractTimes(120m, 45m, TimeUnit.Minutes, TimeUnit.Hours);
// → 1.25
Firma: decimal SubtractTimes(decimal a, decimal b, TimeUnit inputUnit, TimeUnit outputUnit)
FormatTime
Formatea un valor de tiempo decimal en una cadena legible para humanos con redondeo:
string s1 = time.FormatTime(1.5m, TimeUnit.Hours, 0);
// → "2 hours"
string s2 = time.FormatTime(90m, TimeUnit.Minutes, 1);
// → "1.5 hours"
string s3 = time.FormatTime(45m, TimeUnit.Seconds, 0);
// → "45 seconds"
Firma: string FormatTime(decimal value, TimeUnit unit, int decimalPlaces)
GetBestUnit
Dado un tiempo en segundos, devuelve la unidad más legible para humanos junto con el valor convertido:
var (value, unit) = time.GetBestUnit(3661);
// value: 1.0169..., unit: TimeUnit.Hours
var (value2, unit2) = time.GetBestUnit(90);
// value2: 1.5, unit2: TimeUnit.Minutes
Firma: (decimal time, TimeUnit unit) GetBestUnit(decimal seconds)
ParseTime
Analiza una cadena legible para humanos en un valor decimal y su unidad:
(decimal value, TimeUnit unit) = time.ParseTime("2.5 hours");
// value = 2.5, unit = TimeUnit.Hours
(decimal v2, TimeUnit u2) = time.ParseTime("90 minutes");
// v2 = 90, u2 = TimeUnit.Minutes
Firma: (decimal value, TimeUnit unit) ParseTime(string input)
Breakdown
Descompone un valor total en un diccionario de unidades componentes:
var parts = time.Breakdown(3661m, TimeUnit.Seconds);
// → { Hours: 1, Minutes: 1, Seconds: 1 }
var parts2 = time.Breakdown(90m, TimeUnit.Minutes);
// → { Hours: 1, Minutes: 30 }
Firma: Dictionary<TimeUnit, decimal> Breakdown(decimal value, TimeUnit sourceUnit)
ToTimeSpan
Convierte un valor decimal en una unidad dada a un TimeSpan:
TimeSpan ts = time.ToTimeSpan(2.5m, TimeUnit.Hours);
// → TimeSpan de 2h 30m
Firma: TimeSpan ToTimeSpan(decimal value, TimeUnit unit)
FromTimeSpan
Convierte un TimeSpan a un valor decimal en la unidad especificada:
decimal minutes = time.FromTimeSpan(TimeSpan.FromHours(1.5), TimeUnit.Minutes);
// → 90
Firma: decimal FromTimeSpan(TimeSpan span, TimeUnit unit)
Clamp
Restringe un valor dentro de un mínimo y un máximo (todos en la misma unidad):
decimal clamped = time.Clamp(150m, TimeUnit.Minutes, 0m, 120m);
// → 120 (restringido al máximo)
decimal clamped2 = time.Clamp(-5m, TimeUnit.Minutes, 0m, 120m);
// → 0 (restringido al mínimo)
Firma: decimal Clamp(decimal value, TimeUnit unit, decimal min, decimal max)
Compare
Compara dos valores de tiempo (que pueden estar en unidades distintas). Devuelve -1, 0 o 1:
int result = time.Compare(60m, TimeUnit.Minutes, 1m, TimeUnit.Hours);
// → 0 (iguales)
int result2 = time.Compare(90m, TimeUnit.Seconds, 2m, TimeUnit.Minutes);
// → -1 (90s < 2min)
Firma: int Compare(decimal a, TimeUnit aUnit, decimal b, TimeUnit bUnit)
MultiConvert
Convierte un valor de una unidad a múltiples unidades destino a la vez:
var results = time.MultiConvert(3600m, TimeUnit.Seconds,
TimeUnit.Hours, TimeUnit.Minutes, TimeUnit.Days);
// → { Hours: 1, Minutes: 60, Days: 0.0416... }
Firma: Dictionary<TimeUnit, decimal> MultiConvert(decimal value, TimeUnit from, params TimeUnit[] targets)
Ejemplo completo
public class WorklogService(IValiTime time)
{
public void AnalyzeWorklog(decimal[] taskDurationsInMinutes)
{
// Total en horas
decimal totalHours = time.SumTimes(taskDurationsInMinutes, TimeUnit.Minutes, TimeUnit.Hours);
// Mejor unidad de visualización
decimal totalSeconds = time.Convert(totalHours, TimeUnit.Hours, TimeUnit.Seconds);
var (bestValue, bestUnit) = time.GetBestUnit(totalSeconds);
string formatted = time.FormatTime(totalHours, TimeUnit.Hours, 1);
// Desglose en componentes
var parts = time.Breakdown(totalHours, TimeUnit.Hours);
Console.WriteLine($"Total work: {formatted}");
Console.WriteLine($"Hours: {parts[TimeUnit.Hours]}, Minutes: {parts[TimeUnit.Minutes]}");
// Comparar con una jornada de 8 horas
int cmp = time.Compare(totalHours, TimeUnit.Hours, 8m, TimeUnit.Hours);
if (cmp < 0) Console.WriteLine("Undertime");
else if (cmp > 0) Console.WriteLine("Overtime");
else Console.WriteLine("Exact 8 hours");
}
}