Problema DateTime quando la cultura globale del server è diversa su server diversi

Il mio sito web è ospitato su più server in luoghi diversi

Ovunque la cultura del formato dei dati è diversa, usiamo il formato mm/dd/yyyy ogni dove, ma nel caso in cui alcuni server abbiano la cultura impostata su dd/mm/yyyy nostro sito web genera un’eccezione Datetime.

Dovresti specificare quale cultura vuoi utilizzare ogni volta che converti una stringa in una data.

La cultura che dovresti usare dipende da quale cultura sono formattate le date. Ad esempio, se tutte le date che stai analizzando sono formattate in slovacco :

 String s = "24. 10. 2011"; 

Quindi devi analizzare la stringa come se fosse nella cultura slovacca (Slovacchia) ( sk-SK ):

 //Bad: d = DateTime.Parse(s); //Good: d = DateTime.Parse(s, CultureInfo.CreateSpecificCulture("sk-SK")); //Slovak (Slovakia) 

Se le tue date sono tutte in Tagikistan (cirillico del Tagikistan) , devi analizzarle come tg-Cryl-Tj :

 String s = "24.10.11" DateTime d = DateTime.Parse(s, CultureInfo.CreateSpecificCulture("tg-Cryl-Tj")); 

Il che porta alla domanda: quale formato di data stai usando? Non dovresti affidarti alle impostazioni locali del server, dovresti decidere quale formato desideri.

 //Bad String s = d.ToString(); //Good String s = d.ToString(CultureInfo.CreateSpecificCulture("si-LK")); //Sinhala (Sri Lanka) //s = "2011-10-24 12:00:00 පෙ.ව." 

sospetto che tu preferisca fare tutto in inglese. Ma poi devi decidere quale variante dell’inglese:

  • en-AU (inglese Austrailia): 24/10/2011
  • en-IA (inglese India): 24-10-2011
  • en-ZA (inglese Sudafrica): 2011/10/24
  • en-US (Stati Uniti d’America): 10/24/2011

sospetto che tu preferisca l’ inglese (India) ( en-IA ).


Ma se davvero non puoi decidere quale cultura usare quando converti le date in stringhe e viceversa, e le date non devono mai essere mostrate a un utente, puoi usare la cultura invariabile :

 String s = "10/24/2011" //invariant culture formatted date d = DateTime.Parse(s, CultureInfo.InvariantCulture); //parse invariant culture date s = d.ToString(CultureInfo.InvariantCulture); //convert to invariant culture string 

Mai e poi mai archiviare le date internamente come stringhe. Non nel database, non nella tua app.

Se è necessario spostare i valori di data tra i server, andare binario. O se davvero devi usare le stringhe, usa ToString(CultureInfo.InvariantCulture) – o semplicemente serializza la proprietà Ticks .

Inoltre, non passare mai le date come stringhe al database utilizzando i comandi SQL creati utilizzando il codice. Utilizzare SqlParameter per questo, o anche meglio, fare affidamento su alcuni O / R Mapper, come Entity Framework o Linq to SQL.

Se distribuito su un server che non è sotto il tuo controllo, è di vitale importanza assicurarsi che il codice non abbia dipendenze hard-coded sulla cultura.

Probabilmente vorrai cercare il tuo codice per DateTime.Parse o simili. Abbiamo un set di metodi di estensione su DateTime che usiamo per forzare la cultura corretta.

Non fare mai affidamento sulle impostazioni locali predefinite del server. Per il tuo caso, questo significa:

  • Utilizzare le istruzioni preparate in cui si passa la data come object data (non formattato) e non come object stringa (formattato). Non si dovrebbero mai usare stringhe per rappresentare comunque le date nella propria applicazione, poiché non è ansible eseguire su di esse funzioni specifiche della data (ad esempio aggiungere 1 mese, ottenere l’ultimo giorno della settimana corrente, ecc.)

  • Utilizza le funzioni SQL come to_date e to_char ovunque (i nomi esatti dipendono dal tuo DBMS), se hai davvero bisogno di usare oggetti stringa nell’applicazione