Procedura: visualizzare le date in calendari non gregoriani
I tipi DateTime e DateTimeOffset utilizzano il calendario gregoriano come calendario predefinito. Ciò significa che la chiamata al metodo ToString di un valore di data e ora visualizza la rappresentazione di stringa di tale data e ora nel calendario gregoriano, anche se la data e l'ora sono state create utilizzando un altro calendario. Questo processo viene illustrato nell'esempio riportato di seguito in cui vengono utilizzate due modalità diverse per creare un valore di data e ora con il calendario persiano ma i valori vengono visualizzati nel calendario gregoriano quando viene chiamato il metodo ToString. L'esempio riflette due tecniche comuni non corrette per la visualizzazione della data in un determinato calendario.
������Dim persianCal As New PersianCalendar()
Dim persianDate As Date = persianCal.ToDateTime(1387, 3, 18, _
12, 0, 0, 0)
Console.WriteLine(persianDate.ToString())
persianDate = New DateTime(1387, 3, 18, persianCal)
Console.WriteLine(persianDate.ToString())
' The example displays the following output to the console:
' 6/7/2008 12:00:00 PM
' 6/7/2008 12:00:00 AM
������PersianCalendar persianCal = new PersianCalendar();
DateTime persianDate = persianCal.ToDateTime(1387, 3, 18, 12, 0, 0, 0);
Console.WriteLine(persianDate.ToString());
persianDate = new DateTime(1387, 3, 18, persianCal);
Console.WriteLine(persianDate.ToString());
// The example displays the following output to the console:
// 6/7/2008 12:00:00 PM
// 6/7/2008 12:00:00 AM
Per visualizzare la data in un determinato calendario è possibile utilizzare due tecniche differenti. La prima richiede che il calendario sia il calendario predefinito per determinate impostazioni cultura. La seconda può essere utilizzata con qualsiasi calendario.
Per visualizzare la data per il calendario predefinito di determinate impostazione cultura
Creare un'istanza di un oggetto calendario derivato dalla classe Calendar che rappresenta il calendario da utilizzare.
Creare un'istanza di un oggetto CultureInfo che rappresenta le impostazioni cultura la cui formattazione verrà utilizzata per la visualizzazione della data.
Chiamare il metodo Array.Exists<T> per determinare se l'oggetto calendario è un membro della matrice restituita dalla proprietà CultureInfo.OptionalCalendars. Ciò indica che il calendario può fungere da calendario predefinito per l'oggetto CultureInfo. Se non è un membro della matrice, seguire le istruzioni riportate nella sezione "Per visualizzare la data in un calendario qualsiasi".
Assegnare l'oggetto calendario alla proprietà Calendar dell'oggetto DateTimeFormatInfo restituito dalla proprietà CultureInfo.DateTimeFormat.
Nota La classe CultureInfo dispone anche di una proprietà Calendar.È tuttavia costante e di sola lettura e non viene modificata per riflettere il nuovo calendario predefinito assegnato alla proprietà DateTimeFormatInfo.Calendar.
Chiamare il metodo ToString o ToString e passare l'oggetto CultureInfo il cui calendario predefinito è stato modificato nel passaggio precedente.
Per visualizzare la data in un calendario qualsiasi
Creare un'istanza di un oggetto calendario derivato dalla classe Calendar che rappresenta il calendario da utilizzare.
Determinare gli elementi di data e ora da visualizzare nella rappresentazione di stringa del valore di data e ora.
Per ogni elemento di data e ora da visualizzare, chiamare il metodo Get dell'oggetto calendario. Sono disponibili i metodi seguenti:
GetYear, per visualizzate l'anno nel calendario appropriato.
GetMonth, per visualizzate il mese nel calendario appropriato.
GetDayOfMonth, per visualizzate il numero del giorno del mese nel calendario appropriato.
GetHour, per visualizzate l'ora del giorno nel calendario appropriato.
GetMinute, per visualizzate i minuti dell'ora nel calendario appropriato.
GetSecond, per visualizzate i secondi del minuto nel calendario appropriato.
GetMilliseconds, per visualizzate i millisecondi del secondo nel calendario appropriato.
Esempio
Nell'esempio viene visualizzata una data utilizzando due calendari diversi. La data viene visualizzata dopo aver definito il calendario Hijri come calendario predefinito per le impostazioni cultura ar-JO e utilizzando il calendario persiano che non è supportato come calendario facoltativo nelle impostazioni cultura fa-IR.
Imports System.Globalization
Public Class CalendarDates
Public Shared Sub Main()
Dim hijriCal As New HijriCalendar()
Dim hijriUtil As New CalendarUtility(hijriCal)
Dim hijriDate1 As Date = New Date(1429, 6, 29, hijriCal)
Dim hijriDate2 As DateTimeOffset = New DateTimeOffset(hijriDate1, _
TimeZoneInfo.Local.GetUtcOffset(hijriDate1))
Dim jc As CultureInfo = CultureInfo.CreateSpecificCulture("ar-JO")
' Display the date using the Gregorian calendar.
Console.WriteLine("Using the system default culture: {0}", _
hijriDate1.ToString("d"))
' Display the date using the ar-JO culture's original default calendar.
Console.WriteLine("Using the ar-JO culture's original default calendar: {0}", _
hijriDate1.ToString("d", jc))
' Display the date using the Hijri calendar.
Console.WriteLine("Using the ar-JO culture with Hijri as the default calendar:")
' Display a Date value.
Console.WriteLine(hijriUtil.DisplayDate(hijriDate1, jc))
' Display a DateTimeOffset value.
Console.WriteLine(hijriUtil.DisplayDate(hijriDate2, jc))
Console.WriteLine()
Dim persianCal As New PersianCalendar()
Dim persianUtil As New CalendarUtility(persianCal)
Dim ic As CultureInfo = CultureInfo.CreateSpecificCulture("fa-IR")
' Display the date using the ir-FA culture's default calendar.
Console.WriteLine("Using the ir-FA culture's default calendar: {0}", _
hijriDate1.ToString("d", ic))
' Display a Date value.
Console.WriteLine(persianUtil.DisplayDate(hijriDate1, ic))
' Display a DateTimeOffset value.
Console.WriteLine(persianUtil.DisplayDate(hijriDate2, ic))
End Sub
End Class
Public Class CalendarUtility
Private thisCalendar As Calendar
Private targetCulture As CultureInfo
Public Sub New(cal As Calendar)
Me.thisCalendar = cal
End Sub
Private Function CalendarExists(culture As CultureInfo) As Boolean
Me.targetCulture = culture
Return Array.Exists(Me.targetCulture.OptionalCalendars, _
AddressOf Me.HasSameName)
End Function
Private Function HasSameName(cal As Calendar) As Boolean
If cal.ToString() = thisCalendar.ToString() Then
Return True
Else
Return False
End If
End Function
Public Function DisplayDate(dateToDisplay As Date, _
culture As CultureInfo) As String
Dim displayOffsetDate As DateTimeOffset = dateToDisplay
Return DisplayDate(displayOffsetDate, culture)
End Function
Public Function DisplayDate(dateToDisplay As DateTimeOffset, _
culture As CultureInfo) As String
Dim specifier As String = "yyyy/MM/dd"
If Me.CalendarExists(culture) Then
Console.WriteLine("Displaying date in supported {0} calendar...", _
thisCalendar.GetType().Name)
culture.DateTimeFormat.Calendar = Me.thisCalendar
Return dateToDisplay.ToString(specifier, culture)
Else
Console.WriteLine("Displaying date in unsupported {0} calendar...", _
thisCalendar.GetType().Name)
Dim separator As String = targetCulture.DateTimeFormat.DateSeparator
Return thisCalendar.GetYear(dateToDisplay.DateTime).ToString("0000") & separator & _
thisCalendar.GetMonth(dateToDisplay.DateTime).ToString("00") & separator & _
thisCalendar.GetDayOfMonth(dateToDisplay.DateTime).ToString("00")
End If
End Function
End Class
' The example displays the following output to the console:
' Using the system default culture: 7/3/2008
' Using the ar-JO culture's original default calendar: 03/07/2008
' Using the ar-JO culture with Hijri as the default calendar:
' Displaying date in supported HijriCalendar calendar...
' 1429/06/29
' Displaying date in supported HijriCalendar calendar...
' 1429/06/29
'
' Using the ir-FA culture's default calendar: 7/3/2008
' Displaying date in unsupported PersianCalendar calendar...
' 1387/04/13
' Displaying date in unsupported PersianCalendar calendar...
' 1387/04/13
using System;
using System.Globalization;
public class CalendarDates
{
public static void Main()
{
HijriCalendar hijriCal = new HijriCalendar();
CalendarUtility hijriUtil = new CalendarUtility(hijriCal);
DateTime hijriDate1 = new DateTime(1429, 6, 29, hijriCal);
DateTimeOffset hijriDate2 = new DateTimeOffset(hijriDate1,
TimeZoneInfo.Local.GetUtcOffset(hijriDate1));
CultureInfo jc = CultureInfo.CreateSpecificCulture("ar-JO");
// Display the date using the Gregorian calendar.
Console.WriteLine("Using the system default culture: {0}",
hijriDate1.ToString("d"));
// Display the date using the ar-JO culture's original default calendar.
Console.WriteLine("Using the ar-JO culture's original default calendar: {0}",
hijriDate1.ToString("d", jc));
// Display the date using the Hijri calendar.
Console.WriteLine("Using the ar-JO culture with Hijri as the default calendar:");
// Display a Date value.
Console.WriteLine(hijriUtil.DisplayDate(hijriDate1, jc));
// Display a DateTimeOffset value.
Console.WriteLine(hijriUtil.DisplayDate(hijriDate2, jc));
Console.WriteLine();
PersianCalendar persianCal = new PersianCalendar();
CalendarUtility persianUtil = new CalendarUtility(persianCal);
CultureInfo ic = CultureInfo.CreateSpecificCulture("fa-IR");
// Display the date using the ir-FA culture's default calendar.
Console.WriteLine("Using the ir-FA culture's default calendar: {0}",
hijriDate1.ToString("d", ic));
// Display a Date value.
Console.WriteLine(persianUtil.DisplayDate(hijriDate1, ic));
// Display a DateTimeOffset value.
Console.WriteLine(persianUtil.DisplayDate(hijriDate2, ic));
}
}
public class CalendarUtility
{
private Calendar thisCalendar;
private CultureInfo targetCulture;
public CalendarUtility(Calendar cal)
{
this.thisCalendar = cal;
}
private bool CalendarExists(CultureInfo culture)
{
this.targetCulture = culture;
return Array.Exists(this.targetCulture.OptionalCalendars,
this.HasSameName);
}
private bool HasSameName(Calendar cal)
{
if (cal.ToString() == thisCalendar.ToString())
return true;
else
return false;
}
public string DisplayDate(DateTime dateToDisplay, CultureInfo culture)
{
DateTimeOffset displayOffsetDate = dateToDisplay;
return DisplayDate(displayOffsetDate, culture);
}
public string DisplayDate(DateTimeOffset dateToDisplay,
CultureInfo culture)
{
string specifier = "yyyy/MM/dd";
if (this.CalendarExists(culture))
{
Console.WriteLine("Displaying date in supported {0} calendar...",
this.thisCalendar.GetType().Name);
culture.DateTimeFormat.Calendar = this.thisCalendar;
return dateToDisplay.ToString(specifier, culture);
}
else
{
Console.WriteLine("Displaying date in unsupported {0} calendar...",
thisCalendar.GetType().Name);
string separator = targetCulture.DateTimeFormat.DateSeparator;
return thisCalendar.GetYear(dateToDisplay.DateTime).ToString("0000") +
separator +
thisCalendar.GetMonth(dateToDisplay.DateTime).ToString("00") +
separator +
thisCalendar.GetDayOfMonth(dateToDisplay.DateTime).ToString("00");
}
}
}
// The example displays the following output to the console:
// Using the system default culture: 7/3/2008
// Using the ar-JO culture's original default calendar: 03/07/2008
// Using the ar-JO culture with Hijri as the default calendar:
// Displaying date in supported HijriCalendar calendar...
// 1429/06/29
// Displaying date in supported HijriCalendar calendar...
// 1429/06/29
//
// Using the ir-FA culture's default calendar: 7/3/2008
// Displaying date in unsupported PersianCalendar calendar...
// 1387/04/13
// Displaying date in unsupported PersianCalendar calendar...
// 1387/04/13
Ogni oggetto CultureInfo può supportare uno o più calendari, indicati dalla proprietà OptionalCalendars. Uno di questi è designato come calendario predefinito delle impostazioni cultura e viene restituito dalla proprietà di sola lettura CultureInfo.Calendar. È possibile designare come impostazione predefinita un altro calendario facoltativo assegnando un oggetto Calendar che rappresenta tale calendario alla proprietà DateTimeFormatInfo.Calendar restituita dalla proprietà CultureInfo.DateTimeFormat. Alcuni calendari, ad esempio quello persiano rappresentato dalla classe PersianCalendar, non fungono tuttavia da calendari facoltativi per tutte le impostazioni cultura.
Nell'esempio viene definita una classe dell'utilità di calendario riutilizzabile CalendarUtility per gestire molti dei dettagli relativi alla generazione della rappresentazione di stringa di una data mediante un determinato calendario. La classe CalendarUtility dispone dei membri seguenti:
Un costruttore con parametri il cui solo parametro è un oggetto Calendar nel quale deve essere rappresentata una data. Viene assegnato a un campo privato della classe.
CalendarExists, un metodo privato che restituisce un valore Boolean che indica se il calendario rappresentato dall'oggetto CalendarUtility è supportato dall'oggetto CultureInfo passato al metodo come parametro. Il metodo esegue il wrapping di una chiamata al metodo Array.Exists<T> al quale passa la matrice CultureInfo.OptionalCalendars.
HasSameName, un metodo privato assegnato al delegato Predicate<T> che viene passato come parametro al metodo Array.Exists<T>. Ogni membro della matrice viene passato al metodo finché quest'ultimo non restituisce true. Il metodo determina se il nome di un calendario facoltativo è identico a quello del calendario rappresentato dall'oggetto CalendarUtility.
DisplayDate, un metodo pubblico di overload al quale vengono passati due parametri, ovvero un valore DateTime o DateTimeOffset da esprimere nel calendario rappresentato dall'oggetto CalendarUtility e le impostazioni cultura le cui regole di formattazione devono essere utilizzate. Il comportamento di restituzione di la rappresentazione di stringa di una data varia a seconda che il calendario di destinazione sia supportato dalle impostazioni cultura le cui regole di formattazione devono essere utilizzate.
Indipendentemente dal calendario utilizzato per creare un valore DateTime o DateTimeOffset in questo esempio, il valore viene in genere espresso in formato gregoriano in quanto i tipi DateTime e DateTimeOffset non mantengono le informazioni del calendario. Internamente vengono rappresentati come numero di cicli trascorsi dopo la mezzanotte del 1 gennaio 0001. L'interpretazione dipende dal calendario. L'interpretazione di tale numero dipende dal calendario . Per la maggior parte delle impostazioni cultura, il calendario predefinito è il calendario gregoriano.
Compilazione del codice
Per questo esempio di codice è richiesto un riferimento a System.Core.dll.
Compilare il codice alla riga di comando utilizzando csc.exe o vb.exe. Per compilare il codice in Visual Studio, inserirlo in un modello di progetto di applicazione console.