18 novembre 2010  0

Uno script per visualizzare date ed ore in formato relativo

Microsoft c# Dopo lunghissimo tempo si torna a parlare di programmazione e voglio affrontare, giusto per non partire da subito con argomenti particolarmente complessi, la realizzazione di una semplice funzione che consenta di trasformare un istante temporale (identificato da una data e un orario specifico) in una rappresentazione relativa rispetto alla data ed orario correnti al momento della consultazione.

Supponiamo, ad esempio, di dover visualizzare all’interno della nostra applicazione un flusso di commenti, pubblicati in tempo reale e corredati di data ed ora di registrazione, in ordine cronologico inverso (ovvero dal più recente al più remoto).

La strada più semplice è quella, ovviamente, di limitarsi a mostrare date ed orari nel formato canonico (ad es.: “registrato il 18 novembre 2010 ore 11:00”). Volendo invece seguire l’attuale trend di rappresentazione di queste informazioni, ormai istituzionalizzato con l’avvento delle “timeline” dei social network, è possibile ricorrere ad un formato più “amichevole” e, probabilmente, comprensibile, basato sulla rappresentazione del tempo trascorso dal momento della registrazione del contenuto, a quello della sua consultazione.

In questo modo, l’esempio appena mostrato, potrebbe trasformarsi ad esempio in “registrato due ore fa” o “registrato 16 secondi fa”, a seconda del momento in cui ne avviene la lettura da parte dell’utente. E’ evidente che questa modalità di rappresentazione delle indicazioni temporali non è precisa quanto un’indicazione esatta, ma ne rappresenta una forma quantizzata che, evidentemente, non può essere utilizzata in qualunque contesto.

Lo script che consente questa trasformazione è di una semplicità disarmante. La versione proposta in c#, ma l’algoritmo è talmente semplice che può essere convertito in PHP o altri linguaggi in maniera estremamente banale.

private const int Minute = 60;
private const int Hour = Minute * 60;
private const int Day = Hour * 24;
private const int Year = Day * 365;
 
public string RelativeDateTime(DateTime dateTime)
{
    var difference = DateTime.UtcNow - dateTime.ToUniversalTime();
 
    if (difference.TotalSeconds < 2) return "un secondo fa";
    if (difference.TotalSeconds < Minute) return String.Format("{0} secondi fa", 
                        Math.Floor(difference.TotalSeconds));
    if (difference.TotalSeconds < 2 * Minute) return "un minuto fa";
    if (difference.TotalSeconds < Hour) return String.Format("{0} minuti fa", 
                        Math.Floor(difference.TotalMinutes));
    if (difference.TotalSeconds < 2 * Hour) return "un'ora fa";
    if (difference.TotalSeconds < Day) return String.Format("{0} ore fa", 
                        Math.Floor(difference.TotalHours));
    if (difference.TotalSeconds < 2 * Day) return "ieri";
    if (difference.TotalSeconds < 30 * Day) return String.Format("{0} giorni fa", 
                        Math.Floor(difference.TotalDays));
    if (difference.TotalSeconds < 60 * Day) return "il mese scorso";
    if (difference.TotalSeconds < Year) return String.Format("{0} mesi fa", 
                        Math.Floor(difference.TotalDays / 30));
    if (difference.TotalSeconds < 2 * Year) return "l'anno scorso";
    return String.Format("{0} anni fa", difference.TotalDays / 365);
}

 

Il codice è estremamente semplificato e assume che il dato passato alla funzione sia ovviamente di tipo DateTime (in caso diverso potrebbe venire generata un eccezione in fase di esecuzione. Viene restituita una stringa (string) contenente l’espressione temporale in formato relativo.

La versione originale è, naturalmente un po’ più elaborata, in quanto consente di restituire un’espressione di testo tradotta nella lingua del client browser utilizzato dall’utente. Tale operazione è molto semplice da implementare, visto che è sufficiente sostituire alla stringhe di testo utilizzate le opportune funzioni relative alla gestione delle risorse in base alla “cultura” utilizzata.

La funzione può essere ulteriormente elaborata inserendo ulteriori condizioni per rappresentare le settimane o espressioni del tipo “l’altro ieri” al posto di “2 giorni fa”. Tutto dipende dalla fantasia e dalla voglia dello sviluppatore.

A tal proposito, qualcuno potrebbe obiettare che sarebbe stato più elegante utilizzare un costrutto switch al posto di una serie di if sequenziali. La scelta è stata dettata esclusivamente da motivi di praticità; nel primo caso, infatti, si sarebbe dovuto scrivere più codice.

Una soluzione ancora più elaborata sarebbe stata quella di realizzare un dizionario di regole e ridurre la funzione alla semplice valutazione di una “lambda expression”, ma questo potrebbe essere argomento di un prossimo articolo …

Esprimi il tuo giudizio

Aggiungi Commento

biucitecode
  • Commento
  • Anteprima
Loading


| |   |  

Codice QR

Codice QR - cristianofino.net

Ultimi Commenti