Domanda

Sto lavorando a un "sistema di promemoria online" progetto (ASP.NET 2.0 (C #) / SQL Server 2005)

Poiché si tratta di un servizio di promemoria che invierà la posta agli utenti in date particolari. Ma il problema è che gli utenti non provengono da un Paese specifico, provengono da tutto il mondo e da fusi orari diversi. Ora, quando mi registro, chiedo il fuso orario degli utenti allo stesso modo in cui Windows chiede il nostro fuso orario al momento dell'installazione.

Ma non vedo se l'utente ha selezionato (+5.30) o qualcosa del fuso orario, quindi come gestire questo fuso orario nella mia applicazione asp.net. Come lavorare in base al fuso orario.

E suggerisci se esiste un modo migliore per gestire i fusi orari in questa applicazione ??

Grazie

È stato utile?

Soluzione

La prima cosa è assicurarsi in quale fuso orario si trovano i tuoi dati. Raccomanderei di assicurarsi che qualsiasi DateTime che memorizzi, sia archiviato nell'ora UTC (usa DateTime.ToUniversalTime () per contattalo).

Quando si memorizza un promemoria per un utente, è necessario l'ora UTC corrente, aggiungere o rimuovere la differenza di fuso orario dell'utente e convertire quel nuovo orario in UTC; questo è ciò che vuoi archiviare nel DB.

Quindi, quando si desidera verificare la presenza di promemoria da inviare, è sufficiente cercare nel database i promemoria da inviare ora, in base all'ora UTC; essenzialmente ottenere tutti i promemoria che hanno un timestamp precedente a DateTime.Now.ToUniversalTime () .

Aggiorna con alcune specifiche di implementazione: Puoi ottenere un elenco di fusi orari dal metodo TimeZoneInfo.GetSystemTimeZones () ; puoi usarli per mostrare un elenco di fusi orari per l'utente. Se memorizzi la proprietà Id dal fuso orario selezionato, puoi creare un'istanza della classe TimeZoneInfo da essa e calcolare l'ora UTC per un dato valore data / ora locale:

TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("<the time zone id>");
// May 7, 08:04:00
DateTime userDateTime = new DateTime(2009, 5, 7, 8, 4, 0);
DateTime utcDateTime = userDateTime.Subtract(tzi.BaseUtcOffset);

Altri suggerimenti

Consiglio di utilizzare sempre l'ora UTC (GMT) sul lato server (in code-behind, database, ecc.) e di convertire l'ora da UTC in ora locale a scopo di visualizzazione solo. Ciò significa che tutte le manipolazioni del tempo, incluso il risparmio di tempo nel database, l'esecuzione di calcoli, ecc., Devono essere eseguite utilizzando UTC.

Il problema è: come fa il code-behind a sapere qual è il fuso orario del browser client? Supponi che l'utente inserisca un valore di data / ora (come 30/12/2009 14:30 ) nel modulo e lo inoltri al server. Supponendo che l'utente abbia inviato l'ora locale, come fa il server a sapere come convertire questo valore in UTC?

L'applicazione può chiedere all'utente di specificare il fuso orario (e salvarlo in un cookie o database persistente), ma richiede un ulteriore sforzo da parte dell'utente e la tua app dovrebbe implementare la logica e le schermate per questo. Sarebbe più bello se l'app potesse determinare automaticamente il fuso orario del cliente .

Ho risolto questo problema con l'aiuto della funzione getTimezoneOffset di JavaScript, che è la funzione JavaScript solo API in grado di comunicare al server la differenza di orario tra l'ora locale sul client e GMT. Dato che si tratta di un'API lato client, ho fatto quanto segue: sul lato server verifica la presenza di un cookie di sessione personalizzato che contenga il valore di time offset e, se non è disponibile, ricarica la pagina (solo durante le chiamate GET e non POST) con qualche logica JavaScript aggiunta per generare il time offset e salvarlo nel cookie. Dal lato client questo è quasi trasparente (una volta durante la sessione ricarico una pagina su GET). Una volta che ho l'offset nel cookie, lo applico alle funzioni di gestione dell'ora in base alla direzione della conversione dell'ora (UTC in ora locale o ora locale in UTC).

Può sembrare un po 'complicato, e lo è, ma dopo che ho scritto le funzioni di supporto, l'integrazione di questa funzione nel sito è stata una questione di chiamata singola in Page_Load (di pagine che richiedevano tempo conversione) e l'utilizzo di routine di conversione temporale durante l'invio e il recupero di valori temporali da e verso il browser. Ecco un esempio di come può essere utilizzato:

using My.Utilities.Web;
...

// Derive the form class from BaseForm instead of Page.
public class WebForm1: BaseForm
{
...
private void Page_Load(object sender, System.EventArgs e)
{
  // If we only want to load the page to generate the time
  // zone offset cookie, we do not need to do anything else.
  if (InitializeLocalTime())
    return;

  // Assume that txtStartDate is a TextBox control.
  if (!IsPostback)
  {
     // To display a date-time value, convert it from GMT (UTC)
     // to local time.
     DateTime startDate = GetStartDateFromDB(...);
     txtStartDate.Text  = FormatLocalDate(startDate);
     ...
  }
  else
  {
     // To save a date-time value, convert it from local
     // time to GMT (UTC).
     DateTime tempDate  = DateTime.Parse(txtStartDate.Text);
     DateTime startDate = ConvertLocalTimeToUtc(tempDate);
     SaveStartDateInDB(startDate, ...);
     ...
  }
}
...
}

Se hai bisogno di maggiori dettagli, consulta È giunto il momento: localizzare l'ora in Articolo Applicazioni ASP.NET (scusate, ma non ho un collegamento diretto all'articolo sul sito dell'editore, poiché asp.netPRO limita l'accesso solo agli abbonati a pagamento; ci sono collegamenti a copie PDF, però). Vorrei poter pubblicare il campione dall'articolo, ma non voglio violare il copyright; tuttavia, ecco un progetto per creare una libreria di supporto che ha tutte le funzionalità e la documentazione necessarie (ignora solo le cose che non ti servono).

AGGIORNAMENTO: l'articolo è stato pubblicato online con un progetto di esempio dal nuovo editore qui .

Il problema con tutte le risposte finora è che non tengono conto di ciò che Prashant sta cercando di ottenere. Se l'utente del suo sistema il giorno prima delle modifiche dell'ora legale ha un offset di +12 e imposta un promemoria per il giorno successivo, il suo offset quando si suppone che il promemoria venga attivato sarà invece +13.

Ecco perché puoi usare l'offset corrente solo per qualcosa che sta accadendo ora. Anche se concordo con tutti gli altri sul fatto che tutte le volte sul lato server (tranne forse quelle utilizzate solo per la visualizzazione) dovrebbero essere archiviate in UTC.

Potresti voler guardare usando DateTimeOffset struttura anziché DateTime se si utilizza Framework 2.0 o versioni successive.

DateTimeOffset rappresenta un punto temporale rispetto all'ora UTC, quindi dovrebbe essere più semplice lavorare in questo caso.

Ci sono 2 passaggi:

  • Rileva fuso orario diverso sul lato client usando Javascript:

    var dt = new Date();
    var diffInMinutes = -dt.getTimezoneOffset();
    
  • Quindi sul lato server, codice C # per convertire l'ora del server in ora del client in base all'offset del fuso orario rilevato sopra:

------------------------;

string queryStr = Request.QueryString["diffInMinutes"];
int diffInMinutes = 0;
if (Int32.TryParse(queryStr, out diffInMinutes))
{
    clientTime = serverTime.ToUniversalTime().AddMinutes(diffInMinutes);
}

Fondamentalmente, tutto ciò che devi fare è aggiungere l'offset (ore + minuti) all'ora locale che l'utente ha inserito. L'aggiunta dell'offset in pratica ti dà un DateTime nel fuso orario UTC (sostanzialmente GMT).

Di solito è più semplice standardizzare tutti i tempi in UTC, in modo che la logica dell'applicazione non debba gestire gli offset.

Questa pagina contiene alcuni buoni esempi: http://msdn.microsoft .com / it-it / library / bb546099.aspx

Il problema è che l'offset da UTC varierà in diversi periodi dell'anno - ogni fuso orario ha le sue regole. (L'ho imparato nel modo più duro durante lo sviluppo dell'app di pianificazione della sala riunioni.)

Sembra che ci sia supporto integrato qui: http : //msdn.microsoft.com/en-us/library/system.timezoneinfo.converttime.aspx

Non l'ho provato da solo, ma sembra promettere la conversione corretta, tenendo conto dell'ora legale.

Altrimenti, ecco uno strumento commerciale (costoso) che ho usato: http: //www.worldtimeserver .com / time_zone_guide /

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top