Struttura DateTime (System)

Cambia visualizzazione:
ScriptFree
Riferimento a .NET Framework
Struttura DateTime

Rappresenta un istante di tempo, in genere espresso come data e ora del giorno.

Spazio dei nomi: System
Assembly: mscorlib (in mscorlib.dll)

Sintassi

Visual Basic - (Dichiarazione)
<SerializableAttribute> _
Public Structure DateTime
	Implements IComparable, IFormattable, IConvertible, ISerializable, _
	IComparable(Of DateTime), IEquatable(Of DateTime)
Visual Basic (Utilizzo)
Dim instance As DateTime

C#
[SerializableAttribute] 
public struct DateTime : IComparable, IFormattable, IConvertible, 
	ISerializable, IComparable<DateTime>, IEquatable<DateTime>
C++
[SerializableAttribute] 
public value class DateTime : IComparable, IFormattable, IConvertible, 
	ISerializable, IComparable<DateTime>, IEquatable<DateTime>
J#
/** @attribute SerializableAttribute() */ 
public final class DateTime extends ValueType implements IComparable, IFormattable, 
	IConvertible, ISerializable, IComparable<DateTime>, IEquatable<DateTime>
JScript
JScript supporta l'utilizzo di strutture ma non la dichiarazione di nuove.
Note

Il tipo di valore DateTime rappresenta i valori di data e ora compresi tra le ore 0:00:00 del 1° gennaio 0001 D.C. e le ore 23.59.59 del 31 dicembre 9999 D.C.

I valori di ora vengono misurati in unità di 100 nanosecondi, definite segni di graduazione. Una determinata data è rappresentata dal numero di segni di graduazione a partire dalle ore 0:00 del 1° gennaio 0001 D.C. del calendario GregorianCalendar. Un valore di segni di graduazione di 31241376000000000L rappresenta, ad esempio, la data venerdì 1° gennaio dell'anno 100, ore 00.00.00. Un valore DateTime viene sempre espresso nel contesto di un calendario predefinito o esplicito.

Considerazioni sulle versioni

Nelle versioni di .NET Framework precedenti alla 2.0, la struttura DateTime contiene un campo a 64 bit composto da un campo a 2 bit inutilizzato concatenato a un campo Segni di graduazione privato, ovvero un campo a 62 bit senza segno che contiene il numero di segni di graduazione che rappresentano la data e l'ora. Per ottenere il valore del campo Segni di graduazione è possibile utilizzare la proprietà Ticks.

A partire dalla versione 2.0 di .NET Framework, la struttura DateTime contiene un campo a 64 bit composto da un campo Tipo privato concatenato al campo Segni di graduazione. Il campo Tipo è un campo a 2 bit in cui viene indicato se la struttura DateTime rappresenta l'ora locale, l'ora UTC (Coordinated Universal Time) oppure se l'ora locale o UTC non sono specificate. Il campo Tipo è utilizzato per la gestione delle conversioni tra l'ora locale e l'ora UTC, ma non per i confronti aritmetici o tra orari. Per ottenere il valore del campo Tipo è possibile utilizzare la proprietà Kind.

Valori delle strutture DateTime

Le descrizioni dei valori di ora nel tipo DateTime vengono spesso espresse utilizzando lo standard UTC (Coordinated Universal Time), noto a livello internazionale come ora di Greenwich (GMT, Greenwich Mean Time). Lo standard UTC definisce l'ora misurata rispetto a un punto di riferimento posto a una longitudine di zero gradi. All'ora UTC non è applicabile l'ora legale.

L'ora locale è relativa a un fuso orario specifico. Un fuso orario è associato a una differenza di fuso orario, ovvero allo scostamento del fuso orario dal punto di riferimento dello standard UTC misurato in ore. Inoltre, l'ora locale è eventualmente influenzata dall'ora legale, che aggiunge o sottrae un'ora dalla durata di una giornata. Pertanto, l'ora locale è calcolata aggiungendo la differenza di fuso orario all'ora UTC e, se necessario, applicando il fattore dovuto all'ora legale. La differenza di fuso orario nel punto di riferimento dello standard UTC è zero.

L'ora UTC è ideale per l'esecuzione di calcoli e confronti e per la memorizzazione di date e orari nei file. L'ora locale, invece, risulta essere più adatta nelle interfacce utente.

Se la proprietà Kind di un oggetto DateTime è Unspecified, non viene specificato se l'ora rappresentata è locale oppure UTC. In questi casi, l'ora verrà interpretata diversamente a seconda del membro della struttura DateTime utilizzato.

Operazioni sulle strutture DateTime

I calcoli effettuati sulle strutture DateTime, ad esempio mediante i metodi Add o Subtract, non modificano i valori delle strutture. I calcoli di questo tipo, invece, restituiscono una nuova struttura DateTime il cui valore è il risultato del calcolo stesso.

Le operazioni di conversione tra l'ora locale e l'ora UTC tengono in considerazione l'ora legale, al contrario delle operazioni di confronto e aritmetiche.

I calcoli e i confronti fra oggetti DateTime hanno senso solo se gli oggetti rappresentano orari del medesimo fuso orario. Per tale motivo, se non è specificato alcun fuso orario, si presuppone che lo sviluppatore abbia utilizzato un altro meccanismo esterno, ad esempio una variabile o un criterio espliciti, che è possibile utilizzare per determinare il fuso orario in cui è stato creato un oggetto DateTime.

Per eseguire le proprie operazioni, i membri della struttura DateTime utilizzano in modo implicito il calendario gregoriano, ad eccezione dei costruttori che specificano un calendario e dei metodi che dispongono di un parametro derivato da un'interfaccia IFormatProvider, quale ad esempio System.Globalization.DateTimeFormatInfo, che specifica implicitamente un calendario.

Nelle operazioni eseguite dai membri del tipo DateTime si prendono in considerazione dettagli quali gli anni bisestili e il numero di giorni in un mese.

Confronto fra gli oggetti DateTime e TimeSpan

I tipi di valore DateTime e TimeSpan differiscono poiché DateTime rappresenta un istante di tempo, mentre TimeSpan rappresenta un intervallo di tempo. È quindi possibile, ad esempio, sottrarre un'istanza di DateTime da un'altra istanza per ottenere l'intervallo di tempo compreso fra le due. Oppure è possibile aggiungere un TimeSpan positivo al valore DateTime corrente per calcolare una data futura.

A un oggetto DateTime è possibile aggiungere o sottrarre un intervallo di tempo. Gli intervalli di tempo possono essere negativi o positivi, possono essere espressi in unità, ad esempio segni di graduazione o secondi, oppure come un oggetto TimeSpan.

Considerazioni sull'interoperabilità COM

Una sequenza di andata e ritorno si ha quando il valore di un oggetto DateTime viene prima trasferito a un'applicazione COM e quindi trasferito nuovamente a un'applicazione gestita. Tuttavia, contrariamente a quanto si possa pensare, ciò non accade se il valore dell'oggetto DateTime specifica soltanto un orario.

Se la sequenza di andata e ritorno riguarda soltanto un orario, ad esempio le 15:00, la data e l'ora finale saranno il 30 dicembre 1899 D.C. alle 15:00, anziché il 1° gennaio 0001 D.C. alle 15:00; infatti, quando viene specificato soltanto un orario, in .NET Framework e COM viene utilizzata una data predefinita. Si noti che nel sistema COM si utilizza la data di riferimento 30 dicembre 1899 D.C., mentre in .NET Framework si utilizza la data di riferimento 1° gennaio 0001 D.C.

Quando da .NET Framework a COM viene passato soltanto un orario, viene eseguita un'elaborazione speciale che converte l'ora nel formato utilizzato in COM. Quando da COM a .NET Framework viene passato soltanto un orario, non viene eseguita alcuna elaborazione speciale poiché questa danneggerebbe le date e le ore valide corrispondenti o precedenti al 30 dicembre 1899. Ciò significa inoltre che se la data inizia la sequenza di andata e ritorno da COM, .NET Framework e COM manterranno tale data.

Il comportamento di .NET Framework e COM implica che se nell'applicazione viene eseguita una sequenza di andata e ritorno di un oggetto DateTime in cui viene specificato soltanto un orario, è necessario ricordarsi di modificare o ignorare la data errata contenuta nell'oggetto DateTime finale.

Interfacce implementate

Questo tipo implementa le interfacce IComparable, IComparable, IFormattable e IConvertible. Utilizzare la classe Convert per le conversioni anziché l'implementazione del membro esplicito dell'interfaccia IConvertible di questo tipo.

Esempio

Nell'esempio di codice riportato di seguito viene illustrato il confronto fra valori di oggetti DateTime approssimativamente corrispondenti, accettando un piccolo margine di differenza nella dichiarazione di tali valori come "uguali".

Visual Basic

Class DateTimeTester
   
   Shared Function RoughlyEquals(time As DateTime, timeWithWindow As DateTime, windowInSeconds As Integer, frequencyInSeconds As Integer) As Boolean
      
      Dim delta As Long = (timeWithWindow.Subtract(time)).TotalSeconds Mod frequencyInSeconds
      
      If delta > windowInSeconds Then 
	delta = frequencyInSeconds - delta 
      End If
   
      
      Return Math.Abs(delta) < windowInSeconds

   End Function 'RoughlyEquals
    
   
   Public Shared Sub Main()

      Dim window As Integer = 10
      Dim freq As Integer = 60 * 60 * 2 ' 2 hours;
      Dim d1 As DateTime = DateTime.Now
      
      Dim d2 As DateTime = d1.AddSeconds((2 * window))
      Dim d3 As DateTime = d1.AddSeconds((- 2 * window))
      Dim d4 As DateTime = d1.AddSeconds((window / 2))
      Dim d5 As DateTime = d1.AddSeconds((- window / 2))
      
      Dim d6 As DateTime = d1.AddHours(2).AddSeconds((2 * window))
      Dim d7 As DateTime = d1.AddHours(2).AddSeconds((- 2 * window))
      Dim d8 As DateTime = d1.AddHours(2).AddSeconds((window / 2))
      Dim d9 As DateTime = d1.AddHours(2).AddSeconds((- window / 2))
      
      Console.WriteLine("d1 ~= d1 [true]: " + CStr(RoughlyEquals(d1, d1, window, freq)))
      Console.WriteLine("d1 ~= d2 [false]: " + CStr(RoughlyEquals(d1, d2, window, freq)))
      Console.WriteLine("d1 ~= d3 [false]: " + CStr(RoughlyEquals(d1, d3, window, freq)))
      Console.WriteLine("d1 ~= d4 [true]: " + CStr(RoughlyEquals(d1, d4, window, freq)))
      Console.WriteLine("d1 ~= d5 [true]: " + CStr(RoughlyEquals(d1, d5, window, freq)))
      
      Console.WriteLine("d1 ~= d6 [false]: " + CStr(RoughlyEquals(d1, d6, window, freq)))
      Console.WriteLine("d1 ~= d7 [false]: " + CStr(RoughlyEquals(d1, d7, window, freq)))
      Console.WriteLine("d1 ~= d8 [true]: " + CStr(RoughlyEquals(d1, d8, window, freq)))
      Console.WriteLine("d1 ~= d9 [true]: " + CStr(RoughlyEquals(d1, d9, window, freq)))

   End Sub 'Main 

End Class 'DateTimeTester 


C#
class DateTimeTester {

	static bool RoughlyEquals(DateTime time, DateTime timeWithWindow, int windowInSeconds, int frequencyInSeconds)
	{

            long delta = (long)((TimeSpan)(timeWithWindow - time)).TotalSeconds % frequencyInSeconds;

            delta = delta > windowInSeconds ? frequencyInSeconds - delta : delta;

            return Math.Abs(delta) < windowInSeconds;

	}

	public static void Main() 
	{
            int window = 10;
            int freq = 60 * 60 * 2; // 2 hours;

            DateTime d1 = DateTime.Now;

            DateTime d2 = d1.AddSeconds(2 * window);
            DateTime d3 = d1.AddSeconds(-2 * window);
            DateTime d4 = d1.AddSeconds(window / 2);
            DateTime d5 = d1.AddSeconds(-window / 2);

            DateTime d6 = (d1.AddHours(2)).AddSeconds(2 * window);
            DateTime d7 = (d1.AddHours(2)).AddSeconds(-2 * window);
            DateTime d8 = (d1.AddHours(2)).AddSeconds(window / 2);
            DateTime d9 = (d1.AddHours(2)).AddSeconds(-window / 2);

            Console.WriteLine("d1 ~= d1 [true]: " + RoughlyEquals(d1, d1, window, freq));
            Console.WriteLine("d1 ~= d2 [false]: " + RoughlyEquals(d1, d2, window, freq));
            Console.WriteLine("d1 ~= d3 [false]: " + RoughlyEquals(d1, d3, window, freq));
            Console.WriteLine("d1 ~= d4 [true]: " + RoughlyEquals(d1, d4, window, freq));
            Console.WriteLine("d1 ~= d5 [true]: " + RoughlyEquals(d1, d5, window, freq));

            Console.WriteLine("d1 ~= d6 [false]: " + RoughlyEquals(d1, d6, window, freq));
            Console.WriteLine("d1 ~= d7 [false]: " + RoughlyEquals(d1, d7, window, freq));
            Console.WriteLine("d1 ~= d8 [true]: " + RoughlyEquals(d1, d8, window, freq));
            Console.WriteLine("d1 ~= d9 [true]: " + RoughlyEquals(d1, d9, window, freq));


	}
}

C++
bool RoughlyEquals( DateTime time, DateTime timeWithWindow, int windowInSeconds, int frequencyInSeconds )
{
   long delta = (long)((TimeSpan)(timeWithWindow - time)).TotalSeconds % frequencyInSeconds;
   delta = delta > windowInSeconds ? frequencyInSeconds - delta : delta;
   return Math::Abs( delta ) < windowInSeconds;
}

int main()
{
   int window = 10;
   int freq = 60 * 60 * 2; // 2 hours;

   DateTime d1 = DateTime::Now;
   DateTime d2 = d1.AddSeconds( 2 * window );
   DateTime d3 = d1.AddSeconds(  -2 * window );
   DateTime d4 = d1.AddSeconds( window / 2 );
   DateTime d5 = d1.AddSeconds(  -window / 2 );
   DateTime d6 = (d1.AddHours( 2 )).AddSeconds( 2 * window );
   DateTime d7 = (d1.AddHours( 2 )).AddSeconds(  -2 * window );
   DateTime d8 = (d1.AddHours( 2 )).AddSeconds( window / 2 );
   DateTime d9 = (d1.AddHours( 2 )).AddSeconds(  -window / 2 );
   Console::WriteLine( "d1 ~= d1 [true]: {0}", RoughlyEquals( d1, d1, window, freq ) );
   Console::WriteLine( "d1 ~= d2 [false]: {0}", RoughlyEquals( d1, d2, window, freq ) );
   Console::WriteLine( "d1 ~= d3 [false]: {0}", RoughlyEquals( d1, d3, window, freq ) );
   Console::WriteLine( "d1 ~= d4 [true]: {0}", RoughlyEquals( d1, d4, window, freq ) );
   Console::WriteLine( "d1 ~= d5 [true]: {0}", RoughlyEquals( d1, d5, window, freq ) );
   Console::WriteLine( "d1 ~= d6 [false]: {0}", RoughlyEquals( d1, d6, window, freq ) );
   Console::WriteLine( "d1 ~= d7 [false]: {0}", RoughlyEquals( d1, d7, window, freq ) );
   Console::WriteLine( "d1 ~= d8 [true]: {0}", RoughlyEquals( d1, d8, window, freq ) );
   Console::WriteLine( "d1 ~= d9 [true]: {0}", RoughlyEquals( d1, d9, window, freq ) );
}


J#
class DateTimeTester
{
    public static boolean RoughlyEquals(DateTime time, 
        DateTime timeWithWindow, int windowInSeconds, int frequencyInSeconds)
    {
        long delta = (long)((TimeSpan)timeWithWindow.Subtract(time)).
            get_TotalSeconds() % frequencyInSeconds;
        delta = delta > windowInSeconds ? frequencyInSeconds - delta : delta;
        return (System.Convert.ToBoolean(System.Math.Abs(delta) 
            < windowInSeconds));
    } //RoughlyEquals

    public static void main(String[] args)
    {
        int window = 10;
        int freq = 60 * 60 * 2; // 2 hours;
        DateTime d1 = DateTime.get_Now();
        DateTime d2 = d1.AddSeconds(2 * window);
        DateTime d3 = d1.AddSeconds(-2 * window);
        DateTime d4 = d1.AddSeconds(window / 2);
        DateTime d5 = d1.AddSeconds(-window / 2);

        DateTime d6 = d1.AddHours(2).AddSeconds(2 * window);
        DateTime d7 = d1.AddHours(2).AddSeconds(-2 * window);
        DateTime d8 = d1.AddHours(2).AddSeconds(window / 2);
        DateTime d9 = d1.AddHours(2).AddSeconds(-window / 2);

        Console.WriteLine("d1 ~= d1 [true]: " 
            + RoughlyEquals(d1, d1, window, freq));
        Console.WriteLine("d1 ~= d2 [false]: " 
            + RoughlyEquals(d1, d2, window, freq));
        Console.WriteLine("d1 ~= d3 [false]: " 
            + RoughlyEquals(d1, d3, window, freq));
        Console.WriteLine("d1 ~= d4 [true]: " 
            + RoughlyEquals(d1, d4, window, freq));
        Console.WriteLine("d1 ~= d5 [true]: " 
            + RoughlyEquals(d1, d5, window, freq));
        Console.WriteLine("d1 ~= d6 [false]: " 
            + RoughlyEquals(d1, d6, window, freq));
        Console.WriteLine("d1 ~= d7 [false]: " 
            + RoughlyEquals(d1, d7, window, freq));
        Console.WriteLine("d1 ~= d8 [true]: " 
            + RoughlyEquals(d1, d8, window, freq));
        Console.WriteLine("d1 ~= d9 [true]: " 
            + RoughlyEquals(d1, d9, window, freq));
    } //main 
} //DateTimeTester 

Codice thread safe

I membri statici pubblici (Shared in Visual Basic) di questo tipo sono validi per le operazioni multithreading. I membri di istanza non sono garantiti come thread safe.
Piattaforme

Windows 98, Windows 2000 SP4, Windows CE, Windows Millennium Edition, Windows Mobile per Pocket PC, Windows Mobile per Smartphone, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition

.NET Framework non supporta tutte le versioni di ciascuna piattaforma. Per un elenco delle versioni supportate, vedere Requisiti di sistema.

Informazioni sulla versione

.NET Framework

Supportato in: 2.0 1.1 1.0

.NET Compact Framework

Supportato in: 2.0 1.0
Vedere anche

Contenuto della community

Michele Locuratolo
Pratiche raccomandate in ASP.NET (UTC Time)

DateTime può creare molta confusione quando si sviluppa in un contesto di server condiviso. Molto probabilmente non sarà possibile contare sul fatto che il DateTime generato sia nella timezone che ci si aspetta. Questo è particolarmente vero quando si estraggono, trasformano ed inseriscono dati in un datasource remoto.

UTC (Universal Time Coordinated) è fatto apposta per evitare questi problemi. UTC si basa sul meridiano di Greenwich (GMT).

Qui alcune raccomandazioni:

  1. Usare solo l'UTC Time nei dati e nello strato intermedio dell'applicazione. E' buona norma avere set di dati omogenei in questi due livelli. Mischiare i tempi di diverse timezone potrebbe essere disastroso!
  2. Non effettuare la conversione nella timezone locale se non durante la presentazione dei dati nell'interfaccia utente.
  3. Evitare di aggiungere o sottrarre ore per convertire nella timezone locale! Usare i metodi ToLoacTime() o ToUniversalTime() per effettuare correttamente le conversioni. 
  4. Utilizzare i tipi nativi di .NET per aiutarti a mischiare le timezone: costruire alcune classi per la gestione del tempo e fornire dei metodi per la coversione di tutti i DateTime locali al tipo di DateTime da usare. Queste classi agiranno come delle scatole nere. Tutti i tempi devono entrare ed uscire da queste scatole per assicurarsi che i tempi siano omogenei.In questo modo si potrà evitare che un MyDatabaseTime ed un MyLocalHostTime vengano tra loro mischiati.
  5. Prestare attenzione quando si utilizza ToLocalTime() o ToUniversalTime() per convertire le date da e verso il formato UTC. Questo infatti convertirà il dato tenendo conto delle convenzioni di ora solare/legale impostate sul computer in cui viene eseguita la conversione. Un ottimo articolo è consultabile al seguente indirizzo: http://msdn2.microsoft.com/en-us/library/ms973825.aspx .

 

(Tradotto dal blocco di David M. Kean su MSDN Contenuti community in lingua inglese)