feat: Implementazione completa sistema schedulazione con intervalli personalizzati
- Aggiunto supporto schedulazione con intervalli flessibili (secondi/minuti/ore/giorni/settimane/mesi) - Esteso modello ProfileSchedule con campi IntervalValue e IntervalUnit - Ottimizzato ScheduledJobService per controlli ogni 30s con esecuzione parallela - Implementata interfaccia UI completa con anteprima real-time in italiano - Aggiunta migrazione database AddIntervalSchedulingFields - Implementati metodi calcolo NextExecutionTime per intervalli - Aggiunta gestione tracking anti-duplicati e cleanup automatico - Creata documentazione completa (6 file, 2500+ righe) Modifiche tecniche: - ProfileSchedule.cs: Nuovi campi e metodi CalculateNextInterval/GetScheduleDescription - ScheduledJobService.cs: Ridotto check interval a 30s, aggiunto parallel processing - ProfileScheduleService.cs: Supporto calcolo intervalli in UpdateNextExecutionTimeAsync - Scheduling.razor: Aggiunta sezione UI per configurazione intervalli - Scheduling.razor.cs: Implementato GetIntervalPreview() e gestione stato campi
This commit is contained in:
@@ -0,0 +1,195 @@
|
||||
using System.Globalization;
|
||||
|
||||
namespace Data_Coupler.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Servizio utility per la gestione di date, orari e formattazione
|
||||
/// Utilizza il formato 24h per coerenza con il sistema
|
||||
/// </summary>
|
||||
public static class DateTimeHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Formato orario 24h standard utilizzato in tutto il sistema
|
||||
/// </summary>
|
||||
public const string TimeFormat24H = "HH:mm";
|
||||
|
||||
/// <summary>
|
||||
/// Formato data/ora 24h completo utilizzato per il logging e la visualizzazione
|
||||
/// </summary>
|
||||
public const string DateTimeFormat24H = "dd/MM/yyyy HH:mm:ss";
|
||||
|
||||
/// <summary>
|
||||
/// Formato data/ora 24h per i log dettagliati
|
||||
/// </summary>
|
||||
public const string DetailedDateTimeFormat24H = "dd/MM/yyyy HH:mm:ss.fff";
|
||||
|
||||
/// <summary>
|
||||
/// Cultura italiana per la formattazione (formato 24h di default)
|
||||
/// </summary>
|
||||
public static readonly CultureInfo ItalianCulture = new("it-IT");
|
||||
|
||||
/// <summary>
|
||||
/// Converte un TimeSpan in stringa formato 24h (HH:mm)
|
||||
/// </summary>
|
||||
public static string FormatTime24H(TimeSpan time)
|
||||
{
|
||||
return time.ToString(TimeFormat24H);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converte un DateTime in stringa formato 24h (dd/MM/yyyy HH:mm:ss)
|
||||
/// </summary>
|
||||
public static string FormatDateTime24H(DateTime dateTime)
|
||||
{
|
||||
return dateTime.ToString(DateTimeFormat24H, ItalianCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converte un DateTime in stringa formato 24h dettagliato con millisecondi
|
||||
/// </summary>
|
||||
public static string FormatDateTimeDetailed24H(DateTime dateTime)
|
||||
{
|
||||
return dateTime.ToString(DetailedDateTimeFormat24H, ItalianCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prova a parsare una stringa orario in formato 24h
|
||||
/// </summary>
|
||||
public static bool TryParseTime24H(string? timeString, out TimeSpan time)
|
||||
{
|
||||
time = default;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(timeString))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return TimeSpan.TryParseExact(timeString.Trim(), TimeFormat24H, ItalianCulture, out time);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prova a parsare una stringa data/ora in formato 24h
|
||||
/// </summary>
|
||||
public static bool TryParseDateTime24H(string? dateTimeString, out DateTime dateTime)
|
||||
{
|
||||
dateTime = default;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(dateTimeString))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return DateTime.TryParseExact(dateTimeString.Trim(), DateTimeFormat24H, ItalianCulture, DateTimeStyles.None, out dateTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ottiene l'ora corrente locale formattata in 24h
|
||||
/// </summary>
|
||||
public static string GetCurrentTime24H()
|
||||
{
|
||||
return FormatTime24H(DateTime.Now.TimeOfDay);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ottiene la data/ora corrente locale formattata in 24h
|
||||
/// </summary>
|
||||
public static string GetCurrentDateTime24H()
|
||||
{
|
||||
return FormatDateTime24H(DateTime.Now);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Valida se una stringa rappresenta un orario valido nel formato 24h
|
||||
/// </summary>
|
||||
public static bool IsValidTime24H(string? timeString)
|
||||
{
|
||||
return TryParseTime24H(timeString, out _);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Valida se una stringa rappresenta una data/ora valida nel formato 24h
|
||||
/// </summary>
|
||||
public static bool IsValidDateTime24H(string? dateTimeString)
|
||||
{
|
||||
return TryParseDateTime24H(dateTimeString, out _);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converte un orario dal formato 12h al formato 24h se necessario
|
||||
/// </summary>
|
||||
public static string? ConvertTo24H(string? timeString)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(timeString))
|
||||
{
|
||||
return timeString;
|
||||
}
|
||||
|
||||
// Se è già in formato 24h, restituisci così com'è
|
||||
if (TryParseTime24H(timeString, out var time24))
|
||||
{
|
||||
return FormatTime24H(time24);
|
||||
}
|
||||
|
||||
// Prova a parsare dal formato 12h
|
||||
if (DateTime.TryParse(timeString.Trim(), ItalianCulture, DateTimeStyles.None, out var parsed))
|
||||
{
|
||||
return FormatTime24H(parsed.TimeOfDay);
|
||||
}
|
||||
|
||||
return null; // Formato non riconosciuto
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calcola il tempo rimanente fino al prossimo orario schedulato
|
||||
/// </summary>
|
||||
public static TimeSpan TimeUntilNextSchedule(TimeSpan scheduledTime, DateTime? referenceTime = null)
|
||||
{
|
||||
var now = referenceTime ?? DateTime.Now;
|
||||
var currentTime = now.TimeOfDay;
|
||||
|
||||
// Se l'orario programmato è già passato oggi, programma per domani
|
||||
if (currentTime > scheduledTime)
|
||||
{
|
||||
var tomorrow = now.Date.AddDays(1);
|
||||
var nextExecution = tomorrow.Add(scheduledTime);
|
||||
return nextExecution - now;
|
||||
}
|
||||
else
|
||||
{
|
||||
var today = now.Date;
|
||||
var nextExecution = today.Add(scheduledTime);
|
||||
return nextExecution - now;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ottiene il nome del giorno della settimana in italiano
|
||||
/// </summary>
|
||||
public static string GetDayOfWeekName(DayOfWeek dayOfWeek)
|
||||
{
|
||||
return dayOfWeek switch
|
||||
{
|
||||
DayOfWeek.Sunday => "Domenica",
|
||||
DayOfWeek.Monday => "Lunedì",
|
||||
DayOfWeek.Tuesday => "Martedì",
|
||||
DayOfWeek.Wednesday => "Mercoledì",
|
||||
DayOfWeek.Thursday => "Giovedì",
|
||||
DayOfWeek.Friday => "Venerdì",
|
||||
DayOfWeek.Saturday => "Sabato",
|
||||
_ => dayOfWeek.ToString()
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ottiene il nome del giorno della settimana in italiano tramite indice (0=Domenica)
|
||||
/// </summary>
|
||||
public static string GetDayOfWeekName(int dayOfWeekIndex)
|
||||
{
|
||||
if (dayOfWeekIndex < 0 || dayOfWeekIndex > 6)
|
||||
{
|
||||
return "Non valido";
|
||||
}
|
||||
|
||||
return GetDayOfWeekName((DayOfWeek)dayOfWeekIndex);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user