Porady: wyświetlanie dat w kalendarzach innych niż gregoriański
Typy DateTime i DateTimeOffset używają kalendarza gregoriańskiego jako kalendarza domyślnego. Oznacza to, że wywołanie metody wartości ToString
daty i godziny wyświetla ciąg reprezentujący tę datę i godzinę w kalendarzu gregoriańskim, nawet jeśli ta data i godzina została utworzona przy użyciu innego kalendarza. Przedstawiono to w poniższym przykładzie, który używa dwóch różnych sposobów tworzenia wartości daty i godziny z kalendarzem perskim, ale nadal wyświetla te wartości daty i godziny w kalendarzu gregoriańskim, gdy wywołuje metodę ToString . W tym przykładzie przedstawiono dwie powszechnie używane, ale niepoprawne techniki wyświetlania daty w określonym kalendarzu.
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
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
Dwie różne techniki mogą służyć do wyświetlania daty w określonym kalendarzu. Pierwszy wymaga, aby kalendarz był domyślnym kalendarzem dla określonej kultury. Drugi może być używany z dowolnym kalendarzem.
Aby wyświetlić datę domyślnego kalendarza kultury
Utwórz wystąpienie obiektu kalendarza pochodzącego Calendar z klasy reprezentującej kalendarz do użycia.
Utwórz wystąpienie obiektu reprezentującego kulturę CultureInfo , której formatowanie będzie używane do wyświetlania daty.
Wywołaj metodę , Array.Exists aby określić, czy obiekt kalendarza jest elementem członkowskim tablicy zwracanej przez CultureInfo.OptionalCalendars właściwość . Oznacza to, że kalendarz może służyć jako domyślny kalendarz dla CultureInfo obiektu. Jeśli nie jest członkiem tablicy, postępuj zgodnie z instrukcjami w sekcji "Aby wyświetlić datę w dowolnym kalendarzu".
Przypisz obiekt kalendarza do Calendar właściwości DateTimeFormatInfo obiektu zwróconego CultureInfo.DateTimeFormat przez właściwość .
Uwaga
Klasa CultureInfo ma Calendar również właściwość . Jednak jest to tylko do odczytu i stała; nie zmienia się tak, aby odzwierciedlał nowy kalendarz domyślny przypisany do DateTimeFormatInfo.Calendar właściwości.
Wywołaj metodę ToStringToString lub i przekaż go CultureInfo do obiektu, którego kalendarz domyślny został zmodyfikowany w poprzednim kroku.
Aby wyświetlić datę w dowolnym kalendarzu
Utwórz wystąpienie obiektu kalendarza pochodzącego Calendar z klasy reprezentującej kalendarz do użycia.
Określ, które elementy daty i godziny powinny być wyświetlane w ciągu reprezentującym wartość daty i godziny.
Dla każdego elementu daty i godziny, który chcesz wyświetlić, wywołaj obiekt
Get
kalendarza ... Metoda. Dostępne są następujące metody:GetYear, aby wyświetlić rok w odpowiednim kalendarzu.
GetMonth, aby wyświetlić miesiąc w odpowiednim kalendarzu.
GetDayOfMonth, aby wyświetlić liczbę dni miesiąca w odpowiednim kalendarzu.
GetHour, aby wyświetlić godzinę dnia w odpowiednim kalendarzu.
GetMinute, aby wyświetlić minuty w godzinie w odpowiednim kalendarzu.
GetSecond, aby wyświetlić sekundy w minutie w odpowiednim kalendarzu.
GetMilliseconds, aby wyświetlić milisekundy w drugim w odpowiednim kalendarzu.
Przykład
W przykładzie jest wyświetlana data używająca dwóch różnych kalendarzy. Wyświetla datę po zdefiniowaniu kalendarza Hidżry jako kalendarza domyślnego dla kultury ar-JO i wyświetla datę przy użyciu kalendarza perskiego, który nie jest obsługiwany jako opcjonalny kalendarz przez kulturę fa-IR.
using System;
using System.Globalization;
public class CalendarDates
{
public static void Main()
{
HijriCalendar hijriCal = new HijriCalendar();
CalendarUtility hijriUtil = new CalendarUtility(hijriCal);
DateTime dateValue1 = new DateTime(1429, 6, 29, hijriCal);
DateTimeOffset dateValue2 = new DateTimeOffset(dateValue1,
TimeZoneInfo.Local.GetUtcOffset(dateValue1));
CultureInfo jc = CultureInfo.CreateSpecificCulture("ar-JO");
// Display the date using the Gregorian calendar.
Console.WriteLine("Using the system default culture: {0}",
dateValue1.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}",
dateValue1.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(dateValue1, jc));
// Display a DateTimeOffset value.
Console.WriteLine(hijriUtil.DisplayDate(dateValue2, 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}",
dateValue1.ToString("d", ic));
// Display a Date value.
Console.WriteLine(persianUtil.DisplayDate(dateValue1, ic));
// Display a DateTimeOffset value.
Console.WriteLine(persianUtil.DisplayDate(dateValue2, 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
Imports System.Globalization
Public Class CalendarDates
Public Shared Sub Main()
Dim hijriCal As New HijriCalendar()
Dim hijriUtil As New CalendarUtility(hijriCal)
Dim dateValue1 As Date = New Date(1429, 6, 29, hijriCal)
Dim dateValue2 As DateTimeOffset = New DateTimeOffset(dateValue1, _
TimeZoneInfo.Local.GetUtcOffset(dateValue1))
Dim jc As CultureInfo = CultureInfo.CreateSpecificCulture("ar-JO")
' Display the date using the Gregorian calendar.
Console.WriteLine("Using the system default culture: {0}", _
dateValue1.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}", _
dateValue1.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(dateValue1, jc))
' Display a DateTimeOffset value.
Console.WriteLine(hijriUtil.DisplayDate(dateValue2, 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}", _
dateValue1.ToString("d", ic))
' Display a Date value.
Console.WriteLine(persianUtil.DisplayDate(dateValue1, ic))
' Display a DateTimeOffset value.
Console.WriteLine(persianUtil.DisplayDate(dateValue2, 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
Każdy CultureInfo obiekt może obsługiwać co najmniej jeden kalendarz, który jest wskazywany OptionalCalendars przez właściwość . Jeden z nich jest wyznaczony jako domyślny kalendarz kultury i jest zwracany przez właściwość tylko do CultureInfo.Calendar odczytu. Innym z opcjonalnych kalendarzy można wyznaczyć jako domyślne, przypisując Calendar obiekt reprezentujący ten kalendarz do DateTimeFormatInfo.Calendar właściwości zwróconej CultureInfo.DateTimeFormat przez właściwość . Jednak niektóre kalendarze, takie jak kalendarz perski reprezentowany przez klasę PersianCalendar , nie służą jako opcjonalne kalendarze dla żadnej kultury.
W przykładzie zdefiniowano klasę narzędzia kalendarza wielokrotnego użytku , CalendarUtility
w celu obsługi wielu szczegółów generowania reprezentacji ciągu daty przy użyciu określonego kalendarza. Klasa CalendarUtility
ma następujące elementy członkowskie:
Konstruktor sparametryzowany, którego pojedynczy parametr jest obiektem Calendar , w którym ma być reprezentowana data. Jest to przypisane do pola prywatnego klasy.
CalendarExists
, metoda prywatna zwracająca wartość logiczną wskazującą, czy kalendarz reprezentowany przez obiekt jest obsługiwany przezCalendarUtility
CultureInfo obiekt przekazywany do metody jako parametr. Metoda opakowuje wywołanie Array.Exists metody , do której przekazuje tablicę CultureInfo.OptionalCalendars .HasSameName
, metoda prywatna przypisana do Predicate<T> delegata, który jest przekazywany jako parametr do Array.Exists metody . Każdy element członkowski tablicy jest przekazywany do metody, dopóki metoda nie zwrócitrue
metody . Metoda określa, czy nazwa opcjonalnego kalendarza jest taka sama jak kalendarz reprezentowany przezCalendarUtility
obiekt.DisplayDate
, przeciążona metoda publiczna, która jest przekazywana dwa parametry: DateTime wartość lub DateTimeOffset do wyrażenia w kalendarzuCalendarUtility
reprezentowanym przez obiekt; oraz kultury, której reguły formatowania mają być używane. Jego zachowanie w zwracaniu reprezentacji ciągu daty zależy od tego, czy kalendarz docelowy jest obsługiwany przez kulturę, której reguły formatowania mają być używane.
Niezależnie od kalendarza użytego do utworzenia DateTime wartości lub DateTimeOffset w tym przykładzie ta wartość jest zwykle wyrażona jako data gregoriański. Dzieje się tak, ponieważ DateTime typy i DateTimeOffset nie zachowują żadnych informacji kalendarza. Wewnętrznie są one reprezentowane jako liczba kleszczy, które upłynęły od północy 1 stycznia 0001 roku. Interpretacja tej liczby zależy od kalendarza. W przypadku większości kultur domyślnym kalendarzem jest kalendarz gregoriański.