Procedura: consentire agli utenti di risolvere orari ambigui
Aggiornamento: novembre 2007
Un'ora ambigua è un'ora associata a più ore UTC (Coordinated Universal Time). Si verifica quando l'orario viene portato indietro, ad esempio durante la transizione da ora legale a ora solare di un fuso orario. Quando si gestisce un'ora ambigua, è possibile effettuare una delle operazioni seguenti:
Se l'ora ambigua è un elemento di dati immesso dall'utente, sarà l'utente a risolvere l'ambiguità.
Fare una supposizione sul modo in cui l'ora viene associata all'ora UTC. Ad esempio, è possibile presupporre che un'ora ambigua sia sempre espressa nell'ora solare del fuso orario.
In questo argomento viene illustrato come consentire a un utente di risolvere un'ora ambigua.
Per consentire a un utente di risolvere un'ora ambigua
Ottenere l'input di data e ora dall'utente.
Chiamare il metodo IsAmbiguousTime per determinare se l'ora è ambigua.
Se l'ora è ambigua, chiamare il metodo GetAmbiguousTimeOffsets per recuperare una matrice di oggetti TimeSpan. Ogni elemento della matrice contiene un offset UTC a cui è possibile associare l'ora ambigua.
Consentire all'utente di selezionare l'offset desiderato.
Ottenere la data e ora UTC sottraendo l'offset selezionato dall'utente dall'ora locale.
Chiamare il metodo static (Shared in Visual Basic .NET) SpecifyKind per impostare la proprietà Kind del valore di data e ora UTC su DateTimeKind.Utc.
Esempio
Nell'esempio seguente viene richiesto all'utente di immettere una data e ora e, se è ambigua, consente all'utente di selezionare l'ora UTC alla quale è associata l'ora ambigua.
Private Sub GetUserDateInput()
' Get date and time from user
Dim inputDate As Date = GetUserDateTime()
Dim utcDate As Date
' Exit if date has no significant value
If inputDate = Date.MinValue Then Exit Sub
If TimeZoneInfo.Local.IsAmbiguousTime(inputDate) Then
Console.WriteLine("The date you've entered is ambiguous.")
Console.WriteLine("Please select the correct offset from Universal Coordinated Time:")
Dim offsets() As TimeSpan = TimeZoneInfo.Local.GetAmbiguousTimeOffsets(inputDate)
For ctr As Integer = 0 to offsets.Length - 1
Dim zoneDescription As String
If offsets(ctr).Equals(TimeZoneInfo.Local.BaseUtcOffset) Then
zoneDescription = TimeZoneInfo.Local.StandardName
Else
zoneDescription = TimeZoneInfo.Local.DaylightName
End If
Console.WriteLine("{0}.) {1} hours, {2} minutes ({3})", _
ctr, offsets(ctr).Hours, offsets(ctr).Minutes, zoneDescription)
Next
Console.Write("> ")
Dim selection As Integer = CInt(Console.ReadLine())
' Convert local time to UTC, and set Kind property to DateTimeKind.Utc
utcDate = Date.SpecifyKind(inputDate - offsets(selection), DateTimeKind.Utc)
Console.WriteLine("{0} local time corresponds to {1} {2}.", inputDate, utcDate, utcDate.Kind.ToString())
Else
utcDate = inputDate.ToUniversalTime()
Console.WriteLine("{0} local time corresponds to {1} {2}.", inputDate, utcDate, utcDate.Kind.ToString())
End If
End Sub
Private Function GetUserDateTime() As Date
Dim exitFlag As Boolean = False ' flag to exit loop if date is valid
Dim dateString As String
Dim inputDate As Date = Date.MinValue
Console.Write("Enter a local date and time: ")
Do While Not exitFlag
dateString = Console.ReadLine()
If dateString.ToUpper = "E" Then exitFlag = True
If Date.TryParse(dateString, inputDate) Then
exitFlag = true
Else
Console.Write("Enter a valid date and time, or enter 'e' to exit: ")
End If
Loop
Return inputDate
End Function
private void GetUserDateInput()
{
// Get date and time from user
DateTime inputDate = GetUserDateTime();
DateTime utcDate;
// Exit if date has no significant value
if (inputDate == DateTime.MinValue) return;
if (TimeZoneInfo.Local.IsAmbiguousTime(inputDate))
{
Console.WriteLine("The date you've entered is ambiguous.");
Console.WriteLine("Please select the correct offset from Universal Coordinated Time:");
TimeSpan[] offsets = TimeZoneInfo.Local.GetAmbiguousTimeOffsets(inputDate);
for (int ctr = 0; ctr < offsets.Length; ctr++)
{
Console.WriteLine("{0}.) {1} hours, {2} minutes", ctr, offsets[ctr].Hours, offsets[ctr].Minutes);
}
Console.Write("> ");
int selection = Convert.ToInt32(Console.ReadLine());
// Convert local time to UTC, and set Kind property to DateTimeKind.Utc
utcDate = DateTime.SpecifyKind(inputDate - offsets[selection], DateTimeKind.Utc);
Console.WriteLine("{0} local time corresponds to {1} {2}.", inputDate, utcDate, utcDate.Kind.ToString());
}
else
{
utcDate = inputDate.ToUniversalTime();
Console.WriteLine("{0} local time corresponds to {1} {2}.", inputDate, utcDate, utcDate.Kind.ToString());
}
}
private DateTime GetUserDateTime()
{
bool exitFlag = false; // flag to exit loop if date is valid
string dateString;
DateTime inputDate = DateTime.MinValue;
Console.Write("Enter a local date and time: ");
while (! exitFlag)
{
dateString = Console.ReadLine();
if (dateString.ToUpper() == "E")
exitFlag = true;
if (DateTime.TryParse(dateString, out inputDate))
exitFlag = true;
else
Console.Write("Enter a valid date and time, or enter 'e' to exit: ");
}
return inputDate;
}
Nel codice di esempio viene utilizzata una matrice di oggetti TimeSpan per indicare i possibili offset dell'ora ambigua dall'ora UTC. Questi offset non saranno però significativi per l'utente. Per chiarificare il significato di offset, nel codice viene anche indicato se un offset rappresenta l'ora solare o l'ora legale del fuso orario locale. Dal confronto dell'offset con il valore della proprietà BaseUtcOffset è possibile stabilire quale sia l'ora solare e quale l'ora legale. Questa proprietà indica la differenza tra l'ora UTC e l'ora solare del fuso orario.
In questo esempio, tutti i riferimenti al fuso orario locale vengono eseguiti tramite la proprietà TimeZoneInfo.Local. Il fuso orario locale non viene mai assegnato a una variabile oggetto. È una procedura consigliata poiché una chiamata al metodo TimeZoneInfo.ClearCachedData invalida tutti gli oggetti assegnati al fuso orario locale.
Compilazione del codice
Per questo esempio è necessario:
Aggiungere un riferimento a System.Core.dll al progetto.
Importare lo spazio dei nomi System con l'istruzione using (richiesto nel codice C#).
Vedere anche
Attività
Procedura: risolvere orari ambigui