2012-01-03 10 views
7

Ho un'applicazione ASP.NET e un timestamp UTC sul server. Voglio visualizzare il timestamp all'utente nel fuso orario corretto e utilizzando il formato data/ora locale.Come visualizzare le informazioni di data e ora localizzate per gli utenti Web con ASP.NET

E.g. Jan 2, 2012 14:00:00 UTC deve essere visualizzato come 1/2/2012 9:00 AM per un utente a New York, Stati Uniti (UTC -0500) e come 02/01/2012 14:00 per un utente a Londra, Regno Unito.

Questo compito apparentemente semplice si è rivelato sorprendentemente difficile. MSDN has an article con lo stesso titolo, ma parla dell'analisi dell'input dell'utente anziché della visualizzazione dei dati sul lato server, quindi non si applica completamente. compensati

fuso orario è facilmente determinato sul client tramite JavaScript

offset = new Date().getTimezoneOffset();,

ma JavaScript fornisce un supporto molto povero per la formattazione data/ora. Tutto quello che ottieni è il metodo toLocaleString(), che risulta in una stringa lunga e brutta come Monday, January 02, 2012 9:00:00 AM. Non vi è alcuna disposizione per i formati più brevi, quindi sul client siamo bloccati con buone informazioni sul fuso orario e cattive funzionalità di formato data/ora.

La situazione è esattamente opposta sul server. Siamo in grado di sfruttare intestazione HTTP Accept-Language per ottenere il locali dell'utente (not the best choice, but may be good enough), quindi toccare nel database .NET delle zone conosciute, quindi il nostro codice va lungo le linee di

CultureInfo userCulture = new CultureInfo(Request.UserLanguages[0]); più alcune gestione degli errori.

Ma poi siamo bloccati sul problema del fuso orario. Sì, si può ottenere tramite JavaScript e poi tornare come cookie o come dati di postback, ma cosa succede se abbiamo bisogno di visualizzare le date nella prima pagina dell'applicazione? Si potrebbe obiettare che la prima pagina è sempre la pagina di accesso, ma non è così quando le informazioni di accesso dell'utente vengono mantenute tra le sessioni (opzione "ricordami"). La soluzione potrebbe essere quella di salvare l'offset del fuso orario come parte del profilo utente, ma in tal caso potrebbe facilmente diventare obsoleto (accendendo e spegnendo l'ora legale tra una sessione e l'altra).

Esiste una soluzione completa a questo problema che funziona bene e non richiede la scrittura di tonnellate di codice? Sono molto curioso, per favore consiglio.

risposta

4

si dovrebbe passare la stringa di tempo per il cliente in un modulo standard, come ad esempio ISO8601:

var timeString = '2012-01-02T16:00:00Z'; 

alcuni browser correttamente analizzare le stringhe ISO8601 e alcuni abitudine, in modo da analizzare manualmente per essere sicuri. Che è piuttosto semplice, creare un oggetto Date locale, quindi impostare la data e l'ora UTC:

function localDateFromUTC(s) { 

    var x = s.split(/[-\s:tz]/i); 
    var d = new Date(); 

    d.setUTCFullYear(x[0], x[1], x[2]); 
    d.setUTCHours(x[3], x[4], x[5]); 
    return d; 
} 

var s = '2012-01-02T16:00:00Z'; 
var d = localDateFromUTC(s); 
alert(d); // Shows local date and time for the provided UTC date and time 

Se si vuole una potenza specifica, è necessario formattare manualmente, per esempio

function formatDate(d) { 
    var days = ['Sunday','Monday','Tuesday','Wednesday', 
       'Thursday','Friday','Saturday']; 
    var months = ['January','February','March','April','May','June','July', 
       'August','September','October','November','December']; 

    return days[d.getDay()] + ', ' + d.getDate() + ' ' + 
       months[d.getMonth()] + ', ' + d.getFullYear(); 
} 

Si può provare a utilizzare toLocaleString() ma i risultati variano notevolmente tra i vari browser, la maggior parte sembrano ignorare le impostazioni locali in ogni caso.

+0

_Se si desidera un'uscita specifica_ Mi piace l'idea di passare la data in questo modo, ma il problema di determinare il formato di data/ora locale rimane irrisolto.Come fai a sapere cosa usare: ''01/02/2012 14:00'', '' 2012-01-02 14.00'', o, forse ''02 .01.2012 14: 00''? –

+0

La solita soluzione è di scriverlo in un formato non ambiguo, come "2 febbraio 2012", che dovrebbe essere compreso chiaramente da chiunque, anche se preferiscono le date in qualche altro formato. Se i browser avessero un discreto * toLocaleString *, potresti usarlo, ma non lo fanno. – RobG

+1

Ho provato a decodificare come Gmail gestisce i fusi orari. È davvero abbastanza intelligente. Fanno la formattazione della data e la conversione del fuso orario sul server. Sul client cercano di determinare le date degli switch di risparmio di luce (se presenti) eseguendo la ricerca binaria tra il 1 ° gennaio 2010 e il 30 giugno 2010 e successivamente il 30 giugno e il 1 ° gennaio 2011. Codificano tali informazioni, insieme al tempo corrente zona offset, in una stringa e (guarda le mie mani!) do '(nuova immagine) .src = encoded_string'! In questo modo possono passare i dati al server prima del completamento del rendering della pagina principale, senza cookie O postback. –

Problemi correlati