Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Aunque un valor de fecha y hora representa un momento en el tiempo, su representación en forma de cadena es sensible a la cultura y depende tanto de las convenciones utilizadas para mostrar los valores de fecha y hora por una cultura específica como del calendario utilizado por esa cultura. En este tema se explora la compatibilidad con calendarios en .NET y se describe el uso de las clases de calendario al trabajar con valores de fecha.
Calendarios en .NET
Todos los calendarios de .NET derivan de la System.Globalization.Calendar clase , que proporciona la implementación del calendario base. Una de las clases que hereda de la Calendar clase es la EastAsianLunisolarCalendar clase , que es la clase base para todos los calendarios lunisolars. .NET incluye las siguientes implementaciones de calendario:
ChineseLunisolarCalendar, que representa el calendario lunisolar chino.
GregorianCalendar, que representa el calendario gregoriano. Este calendario se divide aún más en subtipos (como árabe y francés de Oriente Medio) definidos por la System.Globalization.GregorianCalendarTypes enumeración. La GregorianCalendar.CalendarType propiedad especifica el subtipo del calendario gregoriano.
HebrewCalendar, que representa el calendario hebreo.
HijriCalendar, que representa el calendario Hijri.
JapaneseCalendar, que representa el calendario japonés.
JapaneseLunisolarCalendar, que representa el calendario lunisolar japonés.
JulianCalendar, que representa el calendario juliano.
KoreanCalendar, que representa el calendario coreano.
KoreanLunisolarCalendar, que representa el calendario lunisolar coreano.
PersianCalendar, que representa el calendario persa.
TaiwanCalendar, que representa el calendario de Taiwán.
TaiwanLunisolarCalendar, que representa el calendario lunisolar de Taiwán.
ThaiBuddhistCalendar, que representa el calendario budista tailandés.
UmAlQuraCalendar, que representa el calendario Um Al Qura.
Un calendario se puede usar de una de estas dos maneras:
Como el calendario utilizado por una cultura específica. Cada CultureInfo objeto tiene un calendario actual, que es el calendario que el objeto está usando actualmente. Las representaciones de cadena de todos los valores de fecha y tiempo reflejan automáticamente la cultura actual y su calendario. Normalmente, el calendario actual es el calendario predeterminado de la cultura. CultureInfo Los objetos también tienen calendarios opcionales, que incluyen calendarios adicionales que la cultura puede usar.
Como calendario independiente independientemente de una referencia cultural específica. En este caso, Calendar los métodos se usan para expresar fechas como valores que reflejan el calendario.
Tenga en cuenta que seis clases de calendario : ChineseLunisolarCalendar, , JapaneseLunisolarCalendarJulianCalendarKoreanLunisolarCalendar, , PersianCalendary TaiwanLunisolarCalendar solo se pueden usar como calendarios independientes. No se usan por ninguna cultura como calendario predeterminado ni como calendario opcional.
Calendarios y referencias culturales
Cada referencia cultural tiene un calendario predeterminado, que se define mediante la CultureInfo.Calendar propiedad . La CultureInfo.OptionalCalendars propiedad devuelve una matriz de Calendar objetos que especifica todos los calendarios admitidos por una referencia cultural determinada, incluido el calendario predeterminado de esa referencia cultural.
El siguiente ejemplo ilustra las propiedades CultureInfo.Calendar y CultureInfo.OptionalCalendars.
CultureInfo
crea objetos para las culturas tailandesa (Tailandia) y japonesa (Japón) y muestra sus calendarios predeterminados y opcionales. Tenga en cuenta que el calendario predeterminado de la cultura también se incluye en la colección CultureInfo.OptionalCalendars en ambos casos.
using System;
using System.Globalization;
public class Example
{
public static void Main()
{
// Create a CultureInfo for Thai in Thailand.
CultureInfo th = CultureInfo.CreateSpecificCulture("th-TH");
DisplayCalendars(th);
// Create a CultureInfo for Japanese in Japan.
CultureInfo ja = CultureInfo.CreateSpecificCulture("ja-JP");
DisplayCalendars(ja);
}
static void DisplayCalendars(CultureInfo ci)
{
Console.WriteLine($"Calendars for the {ci.Name} culture:");
// Get the culture's default calendar.
Calendar defaultCalendar = ci.Calendar;
Console.Write(" Default Calendar: {0}", GetCalendarName(defaultCalendar));
if (defaultCalendar is GregorianCalendar)
Console.WriteLine($" ({((GregorianCalendar) defaultCalendar).CalendarType})");
else
Console.WriteLine();
// Get the culture's optional calendars.
Console.WriteLine(" Optional Calendars:");
foreach (var optionalCalendar in ci.OptionalCalendars) {
Console.Write("{0,6}{1}", "", GetCalendarName(optionalCalendar));
if (optionalCalendar is GregorianCalendar)
Console.Write(" ({0})",
((GregorianCalendar) optionalCalendar).CalendarType);
Console.WriteLine();
}
Console.WriteLine();
}
static string GetCalendarName(Calendar cal)
{
return cal.ToString().Replace("System.Globalization.", "");
}
}
// The example displays the following output:
// Calendars for the th-TH culture:
// Default Calendar: ThaiBuddhistCalendar
// Optional Calendars:
// ThaiBuddhistCalendar
// GregorianCalendar (Localized)
//
// Calendars for the ja-JP culture:
// Default Calendar: GregorianCalendar (Localized)
// Optional Calendars:
// GregorianCalendar (Localized)
// JapaneseCalendar
// GregorianCalendar (USEnglish)
Imports System.Globalization
Public Module Example
Public Sub Main()
' Create a CultureInfo for Thai in Thailand.
Dim th As CultureInfo = CultureInfo.CreateSpecificCulture("th-TH")
DisplayCalendars(th)
' Create a CultureInfo for Japanese in Japan.
Dim ja As CultureInfo = CultureInfo.CreateSpecificCulture("ja-JP")
DisplayCalendars(ja)
End Sub
Sub DisplayCalendars(ci As CultureInfo)
Console.WriteLine("Calendars for the {0} culture:", ci.Name)
' Get the culture's default calendar.
Dim defaultCalendar As Calendar = ci.Calendar
Console.Write(" Default Calendar: {0}", GetCalendarName(defaultCalendar))
If TypeOf defaultCalendar Is GregorianCalendar Then
Console.WriteLine(" ({0})",
CType(defaultCalendar, GregorianCalendar).CalendarType)
Else
Console.WriteLine()
End If
' Get the culture's optional calendars.
Console.WriteLine(" Optional Calendars:")
For Each optionalCalendar In ci.OptionalCalendars
Console.Write("{0,6}{1}", "", GetCalendarName(optionalCalendar))
If TypeOf optionalCalendar Is GregorianCalendar Then
Console.Write(" ({0})",
CType(optionalCalendar, GregorianCalendar).CalendarType)
End If
Console.WriteLine()
Next
Console.WriteLine()
End Sub
Function GetCalendarName(cal As Calendar) As String
Return cal.ToString().Replace("System.Globalization.", "")
End Function
End Module
' The example displays the following output:
' Calendars for the th-TH culture:
' Default Calendar: ThaiBuddhistCalendar
' Optional Calendars:
' ThaiBuddhistCalendar
' GregorianCalendar (Localized)
'
' Calendars for the ja-JP culture:
' Default Calendar: GregorianCalendar (Localized)
' Optional Calendars:
' GregorianCalendar (Localized)
' JapaneseCalendar
' GregorianCalendar (USEnglish)
El calendario actualmente en uso por un objeto particular CultureInfo está definido por la propiedad DateTimeFormatInfo.Calendar de la cultura. La propiedad DateTimeFormatInfo devuelve el objeto CultureInfo.DateTimeFormat de la referencia cultural. Cuando se crea una cultura, su valor predeterminado es el mismo que el valor de la propiedad CultureInfo.Calendar. Sin embargo, puede cambiar el calendario actual de la referencia cultural a cualquier calendario contenido en la matriz devuelta por la propiedad CultureInfo.OptionalCalendars. Si intenta establecer el calendario actual en un calendario que no está incluido en el valor de propiedad CultureInfo.OptionalCalendars, se produce ArgumentException.
En el siguiente ejemplo se cambia el calendario utilizado en la cultura árabe (Arabia Saudita). Primero crea una instancia de un valor DateTime y lo muestra utilizando la cultura actual, que en este caso es inglés (Estados Unidos), y el calendario de la cultura actual, que en este caso es el calendario gregoriano. A continuación, cambia la referencia cultural actual a árabe (Arabia Saudita) y muestra la fecha con su calendario um Al-Qura predeterminado. A continuación, llama al método CalendarExists
para determinar si el calendario Hijri es compatible con la cultura árabe de Arabia Saudita. Debido a que hay soporte para el calendario, se cambia el calendario actual a Hijri y se muestra nuevamente la fecha. Tenga en cuenta que, en cada caso, la fecha se muestra mediante el calendario vigente según la cultura actual.
using System;
using System.Globalization;
using System.Threading;
public class Example
{
public static void Main()
{
DateTime date1 = new DateTime(2011, 6, 20);
DisplayCurrentInfo();
// Display the date using the current culture and calendar.
Console.WriteLine(date1.ToString("d"));
Console.WriteLine();
CultureInfo arSA = CultureInfo.CreateSpecificCulture("ar-SA");
// Change the current culture to Arabic (Saudi Arabia).
Thread.CurrentThread.CurrentCulture = arSA;
// Display date and information about the current culture.
DisplayCurrentInfo();
Console.WriteLine(date1.ToString("d"));
Console.WriteLine();
// Change the calendar to Hijri.
Calendar hijri = new HijriCalendar();
if (CalendarExists(arSA, hijri)) {
arSA.DateTimeFormat.Calendar = hijri;
// Display date and information about the current culture.
DisplayCurrentInfo();
Console.WriteLine(date1.ToString("d"));
}
}
private static void DisplayCurrentInfo()
{
Console.WriteLine($"Current Culture: {CultureInfo.CurrentCulture.Name}");
Console.WriteLine($"Current Calendar: {DateTimeFormatInfo.CurrentInfo.Calendar}");
}
private static bool CalendarExists(CultureInfo culture, Calendar cal)
{
foreach (Calendar optionalCalendar in culture.OptionalCalendars)
if (cal.ToString().Equals(optionalCalendar.ToString()))
return true;
return false;
}
}
// The example displays the following output:
// Current Culture: en-US
// Current Calendar: System.Globalization.GregorianCalendar
// 6/20/2011
//
// Current Culture: ar-SA
// Current Calendar: System.Globalization.UmAlQuraCalendar
// 18/07/32
//
// Current Culture: ar-SA
// Current Calendar: System.Globalization.HijriCalendar
// 19/07/32
Imports System.Globalization
Imports System.Threading
Module Example
Public Sub Main()
Dim date1 As Date = #6/20/2011#
DisplayCurrentInfo()
' Display the date using the current culture and calendar.
Console.WriteLine(date1.ToString("d"))
Console.WriteLine()
Dim arSA As CultureInfo = CultureInfo.CreateSpecificCulture("ar-SA")
' Change the current culture to Arabic (Saudi Arabia).
Thread.CurrentThread.CurrentCulture = arSA
' Display date and information about the current culture.
DisplayCurrentInfo()
Console.WriteLine(date1.ToString("d"))
Console.WriteLine()
' Change the calendar to Hijri.
Dim hijri As Calendar = New HijriCalendar()
If CalendarExists(arSA, hijri) Then
arSA.DateTimeFormat.Calendar = hijri
' Display date and information about the current culture.
DisplayCurrentInfo()
Console.WriteLine(date1.ToString("d"))
End If
End Sub
Private Sub DisplayCurrentInfo()
Console.WriteLine("Current Culture: {0}",
CultureInfo.CurrentCulture.Name)
Console.WriteLine("Current Calendar: {0}",
DateTimeFormatInfo.CurrentInfo.Calendar)
End Sub
Private Function CalendarExists(ByVal culture As CultureInfo,
cal As Calendar) As Boolean
For Each optionalCalendar As Calendar In culture.OptionalCalendars
If cal.ToString().Equals(optionalCalendar.ToString()) Then Return True
Next
Return False
End Function
End Module
' The example displays the following output:
' Current Culture: en-US
' Current Calendar: System.Globalization.GregorianCalendar
' 6/20/2011
'
' Current Culture: ar-SA
' Current Calendar: System.Globalization.UmAlQuraCalendar
' 18/07/32
'
' Current Culture: ar-SA
' Current Calendar: System.Globalization.HijriCalendar
' 19/07/32
Fechas y calendarios
A excepción de los constructores que incluyen un parámetro de tipo Calendar y permiten que los elementos de una fecha (es decir, el mes, el día y el año) reflejen los valores en un calendario designado, los valores y DateTimeDateTimeOffset siempre se basan en el calendario gregoriano. Esto significa, por ejemplo, que la DateTime.Year propiedad devuelve el año en el calendario gregoriano y la DateTime.Day propiedad devuelve el día del mes en el calendario gregoriano.
Importante
Es importante recordar que hay una diferencia entre un valor de fecha y su representación de cadena. El primero se basa en el calendario gregoriano; este último se basa en el calendario actual de una referencia cultural específica.
En el ejemplo siguiente se muestra esta diferencia entre las propiedades DateTime y sus métodos correspondientes Calendar. En el ejemplo, la referencia cultural actual es árabe (Egipto) y el calendario actual es Um Al Qura. Un DateTime valor se establece en el decimoquinto día del séptimo mes de 2011. Es evidente que esto se interpreta como una fecha gregoriana, ya que el DateTime.ToString(String, IFormatProvider) método devuelve estos mismos valores cuando usa las convenciones de la referencia cultural invariable. La representación de cadena de la fecha formateada según las convenciones de la cultura actual es 14/08/32, que es la fecha equivalente en el calendario Um Al Qura. A continuación, los miembros de DateTime
y Calendar
se usan para devolver el día, el mes y el año del DateTime valor. En cada caso, los valores devueltos por DateTime los miembros reflejan valores en el calendario gregoriano, mientras que los valores devueltos por UmAlQuraCalendar los miembros reflejan valores en el calendario Uum al-Qura.
using System;
using System.Globalization;
using System.Threading;
public class Example
{
public static void Main()
{
// Make Arabic (Egypt) the current culture
// and Umm al-Qura calendar the current calendar.
CultureInfo arEG = CultureInfo.CreateSpecificCulture("ar-EG");
Calendar cal = new UmAlQuraCalendar();
arEG.DateTimeFormat.Calendar = cal;
Thread.CurrentThread.CurrentCulture = arEG;
// Display information on current culture and calendar.
DisplayCurrentInfo();
// Instantiate a date object.
DateTime date1 = new DateTime(2011, 7, 15);
// Display the string representation of the date.
Console.WriteLine($"Date: {date1:d}");
Console.WriteLine($"Date in the Invariant Culture: {date1.ToString("d", CultureInfo.InvariantCulture)}");
Console.WriteLine();
// Compare DateTime properties and Calendar methods.
Console.WriteLine($"DateTime.Month property: {date1.Month}");
Console.WriteLine($"UmAlQura.GetMonth: {cal.GetMonth(date1)}");
Console.WriteLine();
Console.WriteLine($"DateTime.Day property: {date1.Day}");
Console.WriteLine($"UmAlQura.GetDayOfMonth: {cal.GetDayOfMonth(date1)}");
Console.WriteLine();
Console.WriteLine($"DateTime.Year property: {date1.Year:D4}");
Console.WriteLine($"UmAlQura.GetYear: {cal.GetYear(date1)}");
Console.WriteLine();
}
private static void DisplayCurrentInfo()
{
Console.WriteLine($"Current Culture: {CultureInfo.CurrentCulture.Name}");
Console.WriteLine($"Current Calendar: {DateTimeFormatInfo.CurrentInfo.Calendar}");
}
}
// The example displays the following output:
// Current Culture: ar-EG
// Current Calendar: System.Globalization.UmAlQuraCalendar
// Date: 14/08/32
// Date in the Invariant Culture: 07/15/2011
//
// DateTime.Month property: 7
// UmAlQura.GetMonth: 8
//
// DateTime.Day property: 15
// UmAlQura.GetDayOfMonth: 14
//
// DateTime.Year property: 2011
// UmAlQura.GetYear: 1432
Imports System.Globalization
Imports System.Threading
Module Example
Public Sub Main()
' Make Arabic (Egypt) the current culture
' and Umm al-Qura calendar the current calendar.
Dim arEG As CultureInfo = CultureInfo.CreateSpecificCulture("ar-EG")
Dim cal As Calendar = New UmAlQuraCalendar()
arEG.DateTimeFormat.Calendar = cal
Thread.CurrentThread.CurrentCulture = arEG
' Display information on current culture and calendar.
DisplayCurrentInfo()
' Instantiate a date object.
Dim date1 As Date = #07/15/2011#
' Display the string representation of the date.
Console.WriteLine("Date: {0:d}", date1)
Console.WriteLine("Date in the Invariant Culture: {0}",
date1.ToString("d", CultureInfo.InvariantCulture))
Console.WriteLine()
' Compare DateTime properties and Calendar methods.
Console.WriteLine("DateTime.Month property: {0}", date1.Month)
Console.WriteLine("UmAlQura.GetMonth: {0}",
cal.GetMonth(date1))
Console.WriteLine()
Console.WriteLine("DateTime.Day property: {0}", date1.Day)
Console.WriteLine("UmAlQura.GetDayOfMonth: {0}",
cal.GetDayOfMonth(date1))
Console.WriteLine()
Console.WriteLine("DateTime.Year property: {0:D4}", date1.Year)
Console.WriteLine("UmAlQura.GetYear: {0}",
cal.GetYear(date1))
Console.WriteLine()
End Sub
Private Sub DisplayCurrentInfo()
Console.WriteLine("Current Culture: {0}",
CultureInfo.CurrentCulture.Name)
Console.WriteLine("Current Calendar: {0}",
DateTimeFormatInfo.CurrentInfo.Calendar)
End Sub
End Module
' The example displays the following output:
' Current Culture: ar-EG
' Current Calendar: System.Globalization.UmAlQuraCalendar
' Date: 14/08/32
' Date in the Invariant Culture: 07/15/2011
'
' DateTime.Month property: 7
' UmAlQura.GetMonth: 8
'
' DateTime.Day property: 15
' UmAlQura.GetDayOfMonth: 14
'
' DateTime.Year property: 2011
' UmAlQura.GetYear: 1432
Crear instancias de fechas basadas en un calendario
Dado que los valores de DateTime y DateTimeOffset se basan en el calendario gregoriano, debe llamar a un constructor sobrecargado que incluya un parámetro de tipo Calendar para crear una instancia de un valor de fecha si desea usar los valores de día, mes o año de un calendario diferente. También puede llamar a una de las sobrecargas del método Calendar.ToDateTime de un calendario específico para crear instancias de un objeto DateTime basándose en los valores de un calendario determinado.
En el ejemplo siguiente se crea una instancia de un DateTime valor pasando un HebrewCalendar objeto a un DateTime constructor y se crea una instancia de un segundo DateTime valor llamando al HebrewCalendar.ToDateTime(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32) método . Dado que los dos valores se crean con valores idénticos del calendario hebreo, la llamada al DateTime.Equals método muestra que los dos DateTime valores son iguales.
using System;
using System.Globalization;
public class Example
{
public static void Main()
{
HebrewCalendar hc = new HebrewCalendar();
DateTime date1 = new DateTime(5771, 6, 1, hc);
DateTime date2 = hc.ToDateTime(5771, 6, 1, 0, 0, 0, 0);
Console.WriteLine("{0:d} (Gregorian) = {1:d2}/{2:d2}/{3:d4} ({4}): {5}",
date1,
hc.GetMonth(date2),
hc.GetDayOfMonth(date2),
hc.GetYear(date2),
GetCalendarName(hc),
date1.Equals(date2));
}
private static string GetCalendarName(Calendar cal)
{
return cal.ToString().Replace("System.Globalization.", "").
Replace("Calendar", "");
}
}
// The example displays the following output:
// 2/5/2011 (Gregorian) = 06/01/5771 (Hebrew): True
Imports System.Globalization
Module Example
Public Sub Main()
Dim hc As New HebrewCalendar()
Dim date1 As New Date(5771, 6, 1, hc)
Dim date2 As Date = hc.ToDateTime(5771, 6, 1, 0, 0, 0, 0)
Console.WriteLine("{0:d} (Gregorian) = {1:d2}/{2:d2}/{3:d4} ({4}): {5}",
date1,
hc.GetMonth(date2),
hc.GetDayOfMonth(date2),
hc.GetYear(date2),
GetCalendarName(hc),
date1.Equals(date2))
End Sub
Private Function GetCalendarName(cal As Calendar) As String
Return cal.ToString().Replace("System.Globalization.", "").
Replace("Calendar", "")
End Function
End Module
' The example displays the following output:
' 2/5/2011 (Gregorian) = 06/01/5771 (Hebrew): True
Representar fechas en el calendario actual
Los métodos de formato de fecha y hora siempre usan el calendario actual al convertir fechas en cadenas. Esto significa que la representación de cadena del año, el mes y el día del mes reflejan el calendario actual y no reflejan necesariamente el calendario gregoriano.
En el ejemplo siguiente se muestra cómo afecta el calendario actual a la representación de cadena de una fecha. Cambia la referencia cultural actual a Chino (tradicional, Taiwán) y crea instancias de un valor de fecha. A continuación, muestra el calendario actual y la fecha, cambia el calendario actual a TaiwanCalendary muestra el calendario y la fecha actuales una vez más. La primera vez que se muestra la fecha, se representa como una fecha en el calendario gregoriano. La segunda vez que se muestra, se representa como una fecha en el calendario de Taiwán.
using System;
using System.Globalization;
using System.Threading;
public class Example
{
public static void Main()
{
// Change the current culture to zh-TW.
CultureInfo zhTW = CultureInfo.CreateSpecificCulture("zh-TW");
Thread.CurrentThread.CurrentCulture = zhTW;
// Define a date.
DateTime date1 = new DateTime(2011, 1, 16);
// Display the date using the default (Gregorian) calendar.
Console.WriteLine($"Current calendar: {zhTW.DateTimeFormat.Calendar}");
Console.WriteLine(date1.ToString("d"));
// Change the current calendar and display the date.
zhTW.DateTimeFormat.Calendar = new TaiwanCalendar();
Console.WriteLine($"Current calendar: {zhTW.DateTimeFormat.Calendar}");
Console.WriteLine(date1.ToString("d"));
}
}
// The example displays the following output:
// Current calendar: System.Globalization.GregorianCalendar
// 2011/1/16
// Current calendar: System.Globalization.TaiwanCalendar
// 100/1/16
Imports System.Globalization
Imports System.Threading
Module Example
Public Sub Main()
' Change the current culture to zh-TW.
Dim zhTW As CultureInfo = CultureInfo.CreateSpecificCulture("zh-TW")
Thread.CurrentThread.CurrentCulture = zhTW
' Define a date.
Dim date1 As Date = #1/16/2011#
' Display the date using the default (Gregorian) calendar.
Console.WriteLine("Current calendar: {0}",
zhTW.DateTimeFormat.Calendar)
Console.WriteLine(date1.ToString("d"))
' Change the current calendar and display the date.
zhTW.DateTimeFormat.Calendar = New TaiwanCalendar()
Console.WriteLine("Current calendar: {0}",
zhTW.DateTimeFormat.Calendar)
Console.WriteLine(date1.ToString("d"))
End Sub
End Module
' The example displays the following output:
' Current calendar: System.Globalization.GregorianCalendar
' 2011/1/16
' Current calendar: System.Globalization.TaiwanCalendar
' 100/1/16
Representar fechas en un calendario no actual
Para representar una fecha con un calendario que no sea el calendario actual de una referencia cultural determinada, debe llamar a métodos de ese Calendar objeto. Por ejemplo, los Calendar.GetYearmétodos , Calendar.GetMonthy Calendar.GetDayOfMonth convierten el año, mes y día en valores que reflejan un calendario determinado.
Advertencia
Puesto que algunos calendarios no son calendarios opcionales de ninguna referencia cultural, para representar fechas en estos calendarios siempre es necesario llamar a métodos de calendario. Esto es cierto de todos los calendarios que derivan de las EastAsianLunisolarCalendarclases , JulianCalendary PersianCalendar .
En el ejemplo siguiente se usa un JulianCalendar objeto para crear una instancia de una fecha, 9 de enero de 1905, en el calendario juliano. Cuando esta fecha se muestra con el calendario predeterminado (gregoriano), se representa como 22 de enero de 1905. Las llamadas a métodos individuales JulianCalendar permiten representar la fecha en el calendario juliano.
using System;
using System.Globalization;
public class Example
{
public static void Main()
{
JulianCalendar julian = new JulianCalendar();
DateTime date1 = new DateTime(1905, 1, 9, julian);
Console.WriteLine("Date ({0}): {1:d}",
CultureInfo.CurrentCulture.Calendar,
date1);
Console.WriteLine("Date in Julian calendar: {0:d2}/{1:d2}/{2:d4}",
julian.GetMonth(date1),
julian.GetDayOfMonth(date1),
julian.GetYear(date1));
}
}
// The example displays the following output:
// Date (System.Globalization.GregorianCalendar): 1/22/1905
// Date in Julian calendar: 01/09/1905
Imports System.Globalization
Module Example
Public Sub Main()
Dim julian As New JulianCalendar()
Dim date1 As New Date(1905, 1, 9, julian)
Console.WriteLine("Date ({0}): {1:d}",
CultureInfo.CurrentCulture.Calendar,
date1)
Console.WriteLine("Date in Julian calendar: {0:d2}/{1:d2}/{2:d4}",
julian.GetMonth(date1),
julian.GetDayOfMonth(date1),
julian.GetYear(date1))
End Sub
End Module
' The example displays the following output:
' Date (System.Globalization.GregorianCalendar): 1/22/1905
' Date in Julian calendar: 01/09/1905
Calendarios y intervalos de fechas
La fecha más temprana admitida por un calendario se indica mediante la propiedad Calendar.MinSupportedDateTime de ese calendario. Para la GregorianCalendar clase , esa fecha es el 1 de enero de 0001 C.E. La mayoría de los demás calendarios de .NET admiten una fecha posterior. Al intentar trabajar con un valor de fecha y hora anterior a la fecha compatible más temprana de un calendario, se produce una excepción ArgumentOutOfRangeException.
Sin embargo, hay una excepción importante. El valor predeterminado (sin inicializar) de un DateTime objeto y un DateTimeOffset objeto es igual al GregorianCalendar.MinSupportedDateTime valor. Si intenta dar formato a esta fecha en un calendario que no admite el 1 de enero de 0001 C.E. y no proporciona un especificador de formato, el método de formato usa el especificador de formato "s" (patrón de fecha y hora ordenable) en lugar del especificador de formato "G" (patrón general de fecha y hora). Como resultado, la operación de formato no produce una ArgumentOutOfRangeException excepción. En su lugar, devuelve la fecha no admitida. Esto se ilustra en el ejemplo siguiente, que muestra el valor de DateTime.MinValue cuando la referencia cultural actual se establece en japonés (Japón) con el calendario japonés y en árabe (Egipto) con el calendario Um Al Qura. También establece la referencia cultural actual en inglés (Estados Unidos) y llama al método DateTime.ToString(IFormatProvider) con cada uno de estos objetos CultureInfo. En cada caso, la fecha se muestra mediante el patrón de fecha y hora ordenable.
using System;
using System.Globalization;
using System.Threading;
public class Example
{
public static void Main()
{
DateTime dat = DateTime.MinValue;
// Change the current culture to ja-JP with the Japanese Calendar.
CultureInfo jaJP = CultureInfo.CreateSpecificCulture("ja-JP");
jaJP.DateTimeFormat.Calendar = new JapaneseCalendar();
Thread.CurrentThread.CurrentCulture = jaJP;
Console.WriteLine($"Earliest supported date by {GetCalendarName(jaJP)} calendar: {jaJP.DateTimeFormat.Calendar.MinSupportedDateTime:d}");
// Attempt to display the date.
Console.WriteLine(dat.ToString());
Console.WriteLine();
// Change the current culture to ar-EG with the Um Al Qura calendar.
CultureInfo arEG = CultureInfo.CreateSpecificCulture("ar-EG");
arEG.DateTimeFormat.Calendar = new UmAlQuraCalendar();
Thread.CurrentThread.CurrentCulture = arEG;
Console.WriteLine($"Earliest supported date by {GetCalendarName(arEG)} calendar: {arEG.DateTimeFormat.Calendar.MinSupportedDateTime:d}");
// Attempt to display the date.
Console.WriteLine(dat.ToString());
Console.WriteLine();
// Change the current culture to en-US.
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
Console.WriteLine(dat.ToString(jaJP));
Console.WriteLine(dat.ToString(arEG));
Console.WriteLine(dat.ToString("d"));
}
private static string GetCalendarName(CultureInfo culture)
{
Calendar cal = culture.DateTimeFormat.Calendar;
return cal.GetType().Name.Replace("System.Globalization.", "").Replace("Calendar", "");
}
}
// The example displays the following output:
// Earliest supported date by Japanese calendar: 明治 1/9/8
// 0001-01-01T00:00:00
//
// Earliest supported date by UmAlQura calendar: 01/01/18
// 0001-01-01T00:00:00
//
// 0001-01-01T00:00:00
// 0001-01-01T00:00:00
// 1/1/0001
Imports System.Globalization
Imports System.Threading
Module Example
Public Sub Main()
Dim dat As Date = DateTime.MinValue
' Change the current culture to ja-JP with the Japanese Calendar.
Dim jaJP As CultureInfo = CultureInfo.CreateSpecificCulture("ja-JP")
jaJP.DateTimeFormat.Calendar = New JapaneseCalendar()
Thread.CurrentThread.CurrentCulture = jaJP
Console.WriteLine("Earliest supported date by {1} calendar: {0:d}",
jaJP.DateTimeFormat.Calendar.MinSupportedDateTime,
GetCalendarName(jaJP))
' Attempt to display the date.
Console.WriteLine(dat.ToString())
Console.WriteLine()
' Change the current culture to ar-EG with the Um Al Qura calendar.
Dim arEG As CultureInfo = CultureInfo.CreateSpecificCulture("ar-EG")
arEG.DateTimeFormat.Calendar = New UmAlQuraCalendar()
Thread.CurrentThread.CurrentCulture = arEG
Console.WriteLine("Earliest supported date by {1} calendar: {0:d}",
arEG.DateTimeFormat.Calendar.MinSupportedDateTime,
GetCalendarName(arEG))
' Attempt to display the date.
Console.WRiteLine(dat.ToString())
Console.WRiteLine()
' Change the current culture to en-US.
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US")
Console.WriteLine(dat.ToString(jaJP))
Console.WriteLine(dat.ToString(arEG))
Console.WriteLine(dat.ToString("d"))
End Sub
Private Function GetCalendarName(culture As CultureInfo) As String
Dim cal As Calendar = culture.DateTimeFormat.Calendar
Return cal.GetType().Name.Replace("System.Globalization.", "").Replace("Calendar", "")
End Function
End Module
' The example displays the following output:
' Earliest supported date by Japanese calendar: 明治 1/9/8
' 0001-01-01T00:00:00
'
' Earliest supported date by UmAlQura calendar: 01/01/18
' 0001-01-01T00:00:00
'
' 0001-01-01T00:00:00
' 0001-01-01T00:00:00
' 1/1/0001
Trabajar con eras
Los calendarios suelen dividir las fechas en eras. Sin embargo, las Calendar clases de .NET no admiten todas las eras definidas por un calendario y la mayoría de las Calendar clases solo admiten una sola era. Solo las JapaneseCalendar clases y JapaneseLunisolarCalendar admiten varias eras.
Importante
La era Reiwa, una nueva era en JapaneseCalendar y JapaneseLunisolarCalendar, comienza el 1 de mayo de 2019. Este cambio afecta a todas las aplicaciones que usan estos calendarios. Para obtener más información, consulte los siguientes artículos:
- Control de una nueva era en el calendario japonés en .NET, que documenta las características agregadas a .NET para admitir calendarios con varias eras y describe los procedimientos recomendados que se deben usar al controlar calendarios de varias eras.
- Prepare la aplicación para el cambio de la era japonesa, que proporciona información sobre cómo probar las aplicaciones en Windows para garantizar su preparación para el cambio de era.
- Resumen de las nuevas actualizaciones de era japonesa para .NET Framework, que enumera las actualizaciones de .NET Framework para versiones individuales de Windows relacionadas con la nueva era del calendario japonés, señala las nuevas características de .NET Framework para la compatibilidad con varias eras e incluye cosas que se deben buscar en las pruebas de las aplicaciones.
Una era en la mayoría de los calendarios denota un período de tiempo extremadamente largo. En el calendario gregoriano, por ejemplo, la era actual abarca más de dos milenios. Para los JapaneseCalendar y JapaneseLunisolarCalendar, los dos calendarios que admiten varias eras, esto no es el caso. Una era corresponde al período del reinado de un emperador. La compatibilidad con varias eras, especialmente cuando se desconoce el límite superior de la era actual, plantea desafíos especiales.
Eras y nombres de era
En .NET, los enteros que representan las eras admitidas por una implementación de calendario determinada se almacenan en orden inverso en la Calendar.Eras matriz. La era actual (que es la era con el intervalo de tiempo más reciente) está en el índice cero y para Calendar las clases que admiten varias eras, cada índice sucesivo refleja la era anterior. La propiedad estática Calendar.CurrentEra define el índice de la era actual de la Calendar.Eras matriz; es una constante cuyo valor es siempre cero. Las clases individuales Calendar también incluyen campos estáticos que devuelven el valor de la era actual. Se muestran en la tabla siguiente.
El nombre que corresponde a un número de era determinado se puede recuperar pasando el número correspondiente a una era al método DateTimeFormatInfo.GetEraName o al método DateTimeFormatInfo.GetAbbreviatedEraName. En el ejemplo siguiente se llama a estos métodos para recuperar información sobre la compatibilidad de eras de la clase GregorianCalendar. Muestra la fecha del calendario gregoriano que corresponde al 1 de enero del segundo año de la era actual, así como a la fecha del calendario gregoriano que corresponde al 1 de enero del segundo año de cada era de calendario japonesa admitida.
using System;
using System.Globalization;
public class Example
{
public static void Main()
{
int year = 2;
int month = 1;
int day = 1;
Calendar cal = new JapaneseCalendar();
Console.WriteLine("\nDate instantiated without an era:");
DateTime date1 = new DateTime(year, month, day, 0, 0, 0, 0, cal);
Console.WriteLine("{0}/{1}/{2} in Japanese Calendar -> {3:d} in Gregorian",
cal.GetMonth(date1), cal.GetDayOfMonth(date1),
cal.GetYear(date1), date1);
Console.WriteLine("\nDates instantiated with eras:");
foreach (int era in cal.Eras) {
DateTime date2 = cal.ToDateTime(year, month, day, 0, 0, 0, 0, era);
Console.WriteLine("{0}/{1}/{2} era {3} in Japanese Calendar -> {4:d} in Gregorian",
cal.GetMonth(date2), cal.GetDayOfMonth(date2),
cal.GetYear(date2), cal.GetEra(date2), date2);
}
}
}
Imports System.Globalization
Module Example
Public Sub Main()
Dim year As Integer = 2
Dim month As Integer = 1
Dim day As Integer = 1
Dim cal As New JapaneseCalendar()
Console.WriteLine("Date instantiated without an era:")
Dim date1 As New Date(year, month, day, 0, 0, 0, 0, cal)
Console.WriteLine("{0}/{1}/{2} in Japanese Calendar -> {3:d} in Gregorian",
cal.GetMonth(date1), cal.GetDayOfMonth(date1),
cal.GetYear(date1), date1)
Console.WriteLine()
Console.WriteLine("Dates instantiated with eras:")
For Each era As Integer In cal.Eras
Dim date2 As Date = cal.ToDateTime(year, month, day, 0, 0, 0, 0, era)
Console.WriteLine("{0}/{1}/{2} era {3} in Japanese Calendar -> {4:d} in Gregorian",
cal.GetMonth(date2), cal.GetDayOfMonth(date2),
cal.GetYear(date2), cal.GetEra(date2), date2)
Next
End Sub
End Module
Además, la cadena de formato de fecha y hora personalizada "g" incluye el nombre de era de un calendario en la representación textual de una fecha y hora. Para más información, consulte Cadenas con formato de fecha y hora personalizado.
Crear instancias de una fecha con una era
Para las dos Calendar clases que admiten varias eras, una fecha que consta de un año, mes y día del mes puede ser ambigua. Por ejemplo, todas las eras admitidas por JapaneseCalendar tienen años cuyo número es 1. Normalmente, si no se especifica una era, los métodos de fecha y hora y calendario asumen que los valores pertenecen a la era actual. Esto es cierto tanto para los constructores DateTime y DateTimeOffset que incluyen parámetros de tipo Calendar, como para los métodos JapaneseCalendar.ToDateTime y JapaneseLunisolarCalendar.ToDateTime. En el ejemplo siguiente se crea una instancia de una fecha que representa el 1 de enero del segundo año de una era no especificada. Si ejecuta el ejemplo cuando la era Reiwa es la era actual, la fecha se interpreta como el segundo año de la era reiwa. La era, 令和, precede al año en la cadena devuelta por el DateTime.ToString(String, IFormatProvider) método y corresponde al 1 de enero de 2020, en el calendario gregoriano. (La era Reiwa comienza en el año 2019 del calendario gregoriano).
using System;
using System.Globalization;
public class Example
{
public static void Main()
{
var japaneseCal = new JapaneseCalendar();
var jaJp = new CultureInfo("ja-JP");
jaJp.DateTimeFormat.Calendar = japaneseCal;
var date = new DateTime(2, 1, 1, japaneseCal);
Console.WriteLine($"Gregorian calendar date: {date:d}");
Console.WriteLine($"Japanese calendar date: {date.ToString("d", jaJp)}");
}
}
Imports System.Globalization
Public Module Example
Public Sub Main()
Dim japaneseCal = New JapaneseCalendar()
Dim jaJp = New CultureInfo("ja-JP")
jaJp.DateTimeFormat.Calendar = japaneseCal
Dim dat = New DateTime(2, 1, 1, japaneseCal)
Console.WriteLine($"Gregorian calendar dat: {dat:d}")
Console.WriteLine($"Japanese calendar dat: {dat.ToString("d", jaJp)}")
End Sub
End Module
Sin embargo, si cambia la era, la intención de este código se convierte en ambigua. ¿Está previsto que la fecha represente el segundo año de la era actual o que represente el segundo año de la era heisei? Hay dos maneras de evitar esta ambigüedad:
Cree una instancia del valor de fecha y hora mediante la clase predeterminada GregorianCalendar . A continuación, puede usar el calendario japonés o el calendario lunisolar japonés para la representación de cadena de fechas, como se muestra en el ejemplo siguiente.
using System; using System.Globalization; public class Example { public static void Main() { var japaneseCal = new JapaneseCalendar(); var jaJp = new CultureInfo("ja-JP"); jaJp.DateTimeFormat.Calendar = japaneseCal; var date = new DateTime(1905, 2, 12); Console.WriteLine($"Gregorian calendar date: {date:d}"); // Call the ToString(IFormatProvider) method. Console.WriteLine($"Japanese calendar date: {date.ToString("d", jaJp)}"); // Use a FormattableString object. FormattableString fmt = $"{date:d}"; Console.WriteLine($"Japanese calendar date: {fmt.ToString(jaJp)}"); // Use the JapaneseCalendar object. Console.WriteLine($"Japanese calendar date: {jaJp.DateTimeFormat.GetEraName(japaneseCal.GetEra(date))}" + $"{japaneseCal.GetYear(date)}/{japaneseCal.GetMonth(date)}/{japaneseCal.GetDayOfMonth(date)}"); // Use the current culture. CultureInfo.CurrentCulture = jaJp; Console.WriteLine($"Japanese calendar date: {date:d}"); } } // The example displays the following output: // Gregorian calendar date: 2/12/1905 // Japanese calendar date: 明治38/2/12 // Japanese calendar date: 明治38/2/12 // Japanese calendar date: 明治38/2/12 // Japanese calendar date: 明治38/2/12
Imports System.Globalization Public Module Example Public Sub Main() Dim japaneseCal = New JapaneseCalendar() Dim jaJp = New CultureInfo("ja-JP") jaJp.DateTimeFormat.Calendar = japaneseCal Dim dat = New DateTime(1905, 2, 12) Console.WriteLine($"Gregorian calendar date: {dat:d}") ' Call the ToString(IFormatProvider) method. Console.WriteLine($"Japanese calendar date: {dat.ToString("d", jaJp)}") ' Use a FormattableString object. Dim fmt As FormattableString = $"{dat:d}" Console.WriteLine($"Japanese calendar date: {fmt.ToString(jaJp)}") ' Use the JapaneseCalendar object. Console.WriteLine($"Japanese calendar date: {jaJp.DateTimeFormat.GetEraName(japaneseCal.GetEra(dat))}" + $"{japaneseCal.GetYear(dat)}/{japaneseCal.GetMonth(dat)}/{japaneseCal.GetDayOfMonth(dat)}") ' Use the current culture. CultureInfo.CurrentCulture = jaJp Console.WriteLine($"Japanese calendar date: {dat:d}") End Sub End Module ' The example displays the following output: ' Gregorian calendar date: 2/12/1905 ' Japanese calendar date: 明治38/2/12 ' Japanese calendar date: 明治38/2/12 ' Japanese calendar date: 明治38/2/12 ' Japanese calendar date: 明治38/2/12
Llamar a un método de fecha y hora que especifique explícitamente una era. Esto incluye los métodos siguientes:
Método ToDateTime(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32) de la clase JapaneseCalendar o JapaneseLunisolarCalendar.
Método de análisis DateTime o DateTimeOffset, como Parse, TryParse, ParseExact o TryParseExact, que incluye la cadena que se va a analizar y, opcionalmente, un argumento DateTimeStyles si la cultura actual es Japanese-Japan ("ja-JP") y el calendario de esa cultura es el JapaneseCalendar. La cadena que se va a analizar debe incluir la era.
Método DateTime o DateTimeOffset de análisis que incluye un parámetro
provider
de tipo IFormatProvider.provider
debe ser un CultureInfo objeto que represente la referencia cultural Japanese-Japan ("ja-JP") cuyo calendario actual es JapaneseCalendar o un DateTimeFormatInfo objeto cuya Calendar propiedad es JapaneseCalendar. La cadena que se va a analizar debe incluir la era.
En el ejemplo siguiente se usan tres de estos métodos para crear instancias de una fecha y hora en la era Meiji, que comenzó el 8 de septiembre de 1868 y finalizó el 29 de julio de 1912.
using System; using System.Globalization; public class Example { public static void Main() { var japaneseCal = new JapaneseCalendar(); var jaJp = new CultureInfo("ja-JP"); jaJp.DateTimeFormat.Calendar = japaneseCal; // We can get the era index by calling DateTimeFormatInfo.GetEraName. int eraIndex = 0; for (int ctr = 0; ctr < jaJp.DateTimeFormat.Calendar.Eras.Length; ctr++) if (jaJp.DateTimeFormat.GetEraName(ctr) == "明治") eraIndex = ctr; var date1 = japaneseCal.ToDateTime(23, 9, 8, 0, 0, 0, 0, eraIndex); Console.WriteLine($"{date1.ToString("d", jaJp)} (Gregorian {date1:d})"); try { var date2 = DateTime.Parse("明治23/9/8", jaJp); Console.WriteLine($"{date2.ToString("d", jaJp)} (Gregorian {date2:d})"); } catch (FormatException) { Console.WriteLine("The parsing operation failed."); } try { var date3 = DateTime.ParseExact("明治23/9/8", "gyy/M/d", jaJp); Console.WriteLine($"{date3.ToString("d", jaJp)} (Gregorian {date3:d})"); } catch (FormatException) { Console.WriteLine("The parsing operation failed."); } } } // The example displays the following output: // 明治23/9/8 (Gregorian 9/8/1890) // 明治23/9/8 (Gregorian 9/8/1890) // 明治23/9/8 (Gregorian 9/8/1890)
Imports System.Globalization Public Module Example Public Sub Main() Dim japaneseCal = New JapaneseCalendar() Dim jaJp = New CultureInfo("ja-JP") jaJp.DateTimeFormat.Calendar = japaneseCal ' We can get the era index by calling DateTimeFormatInfo.GetEraName. Dim eraIndex As Integer = 0 For ctr As Integer = 0 To jaJp.DateTimeFormat.Calendar.Eras.Length - 1 If jaJp.DateTimeFormat.GetEraName(ctr) = "明治" Then eraIndex = ctr Next Dim date1 = japaneseCal.ToDateTime(23, 9, 8, 0, 0, 0, 0, eraIndex) Console.WriteLine($"{date1.ToString("d", jaJp)} (Gregorian {date1:d})") Try Dim date2 = DateTime.Parse("明治23/9/8", jaJp) Console.WriteLine($"{date2.ToString("d", jaJp)} (Gregorian {date2:d})") Catch e As FormatException Console.WriteLine("The parsing operation failed.") End Try Try Dim date3 = DateTime.ParseExact("明治23/9/8", "gyy/M/d", jaJp) Console.WriteLine($"{date3.ToString("d", jaJp)} (Gregorian {date3:d})") Catch e As FormatException Console.WriteLine("The parsing operation failed.") End Try End Sub End Module ' The example displays the following output: ' 明治23/9/8 (Gregorian 9/8/1890) ' 明治23/9/8 (Gregorian 9/8/1890) ' 明治23/9/8 (Gregorian 9/8/1890)
Sugerencia
Al trabajar con calendarios que admiten varias eras, use siempre la fecha gregoriana para crear una instancia de una fecha o especificar la era cuando cree una instancia de una fecha y hora en función de ese calendario.
Al especificar una era para el método ToDateTime(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32), se proporciona el índice de la era en la propiedad Eras del calendario. Sin embargo, en el caso de los calendarios cuyas eras están sujetas a cambios, estos índices no son valores constantes; la era actual está en el índice 0 y la era más antigua está en el índice Eras.Length - 1
. Cuando se agrega una nueva era a un calendario, los índices de las eras anteriores aumentan en uno. Puede proporcionar el índice de era adecuado de la siguiente manera:
Para las fechas en la era actual, siempre use la propiedad CurrentEra del calendario.
Para las fechas de una era especificada, use el DateTimeFormatInfo.GetEraName método para recuperar el índice que corresponde a un nombre de era especificado. Esto requiere que el calendario actual del JapaneseCalendar sea del objeto CultureInfo que representa la cultura ja-JP. (Esta técnica también funciona para el JapaneseLunisolarCalendar, ya que admite las mismas eras que el JapaneseCalendar.) En el ejemplo anterior se ilustra este enfoque.
Calendarios, eras e intervalos de fechas: comprobaciones de intervalos relajadas
Muy parecido a como los calendarios individuales admiten intervalos de fechas, las eras en las clases JapaneseCalendar y JapaneseLunisolarCalendar también tienen intervalos admitidos. Anteriormente, .NET usaba comprobaciones estrictas de rango de era para asegurarse de que una fecha específica de la era se encontraba dentro del rango de esa era. Es decir, si una fecha está fuera del intervalo de la era especificada, el método lanza una ArgumentOutOfRangeExceptionexcepción. Actualmente, .NET usa la comprobación de intervalos relajados de forma predeterminada. Novedades a todas las versiones de .NET introdujo comprobaciones de intervalo de era relajada; el intento de crear una instancia de una fecha específica de la era que está fuera del intervalo de la era especificada "desborda" en la siguiente era y no se produce ninguna excepción.
En el ejemplo siguiente se intenta crear una instancia de una fecha en el año 65 de la era showa, que comenzó el 25 de diciembre de 1926 y finalizó el 7 de enero de 1989. Esta fecha corresponde al 9 de enero de 1990, que está fuera del intervalo de la era Showa en JapaneseCalendar. Como se muestra en la salida del ejemplo, la fecha mostrada por el ejemplo es el 9 de enero de 1990, en el segundo año de la era heisei.
using System;
using System.Globalization;
public class Example
{
public static void Main()
{
var jaJp = new CultureInfo("ja-JP");
var cal = new JapaneseCalendar();
jaJp.DateTimeFormat.Calendar = cal;
string showaEra = "昭和";
var dt = cal.ToDateTime(65, 1, 9, 15, 0, 0, 0, GetEraIndex(showaEra));
FormattableString fmt = $"{dt:d}";
Console.WriteLine($"Japanese calendar date: {fmt.ToString(jaJp)}");
Console.WriteLine($"Gregorian calendar date: {fmt}");
int GetEraIndex(string eraName)
{
foreach (var ctr in cal.Eras)
if (jaJp.DateTimeFormat.GetEraName(ctr) == eraName)
return ctr;
return 0;
}
}
}
// The example displays the following output:
// Japanese calendar date: 平成2/1/9
// Gregorian calendar date: 1/9/1990
Imports System.Globalization
Public Module Example
Dim jaJp As CultureInfo
Dim cal As Calendar
Public Sub Main()
jaJp = New CultureInfo("ja-JP")
cal = New JapaneseCalendar()
jaJp.DateTimeFormat.Calendar = cal
Dim showaEra = "昭和"
Dim dt = cal.ToDateTime(65, 1, 9, 15, 0, 0, 0, GetEraIndex(showaEra))
Dim fmt As FormattableString = $"{dt:d}"
Console.WriteLine($"Japanese calendar date: {fmt.ToString(jaJp)}")
Console.WriteLine($"Gregorian calendar date: {fmt}")
End Sub
Private Function GetEraIndex(eraName As String) As Integer
For Each ctr As Integer In cal.Eras
If jaJp.DateTimeFormat.GetEraName(ctr) = eraName Then Return ctr
Next
Return 0
End Function
End Module
' The example displays the following output:
' Japanese calendar date: 平成2/1/9
' Gregorian calendar date: 1/9/1990
Si las comprobaciones de intervalos relajadas no son deseadas, puede restaurar comprobaciones de intervalo estrictas de varias maneras, en función de la versión de .NET en la que se ejecuta la aplicación:
.NET Core: Agregue lo siguiente al archivo de configuración de.netcore.runtime.json :
"runtimeOptions": { "configProperties": { "Switch.System.Globalization.EnforceJapaneseEraYearRanges": true } }
.NET Framework 4.6 o posterior: Establezca el siguiente modificador AppContext en el archivo app.config :
<?xml version="1.0" encoding="utf-8"?> <configuration> <runtime> <AppContextSwitchOverrides value="Switch.System.Globalization.EnforceJapaneseEraYearRanges=true" /> </runtime> </configuration>
.NET Framework 4.5.2 o versiones anteriores: Establezca el siguiente valor del Registro:
Importancia clave HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\AppContext Entrada Switch.System.Globalization.EnforceJapaneseEraYearRanges Tipo REG_SZ Valor cierto
Con las comprobaciones de intervalo estrictas habilitadas, en el ejemplo anterior se produce una ArgumentOutOfRangeException y se muestra la siguiente salida:
Unhandled Exception: System.ArgumentOutOfRangeException: Valid values are between 1 and 64, inclusive.
Parameter name: year
at System.Globalization.GregorianCalendarHelper.GetYearOffset(Int32 year, Int32 era, Boolean throwOnError)
at System.Globalization.GregorianCalendarHelper.ToDateTime(Int32 year, Int32 month, Int32 day, Int32 hour, Int32 minute, Int32 second, Int32 millisecond, Int32 era)
at Example.Main()
Representar fechas en calendarios con varias eras
Si un objeto Calendar admite eras y es el calendario actual de un objeto CultureInfo, la era se incluye en la representación de cadena de un valor de fecha y hora para los modelos de fecha y hora completa, fecha larga y fecha corta. En el ejemplo siguiente se muestran estos patrones de fecha cuando la referencia cultural actual es Japón (japonés) y el calendario actual es el calendario japonés.
using System;
using System.Globalization;
using System.IO;
using System.Threading;
public class Example
{
public static void Main()
{
StreamWriter sw = new StreamWriter(@".\eras.txt");
DateTime dt = new DateTime(2012, 5, 1);
CultureInfo culture = CultureInfo.CreateSpecificCulture("ja-JP");
DateTimeFormatInfo dtfi = culture.DateTimeFormat;
dtfi.Calendar = new JapaneseCalendar();
Thread.CurrentThread.CurrentCulture = culture;
sw.WriteLine("\n{0,-43} {1}", "Full Date and Time Pattern:", dtfi.FullDateTimePattern);
sw.WriteLine(dt.ToString("F"));
sw.WriteLine();
sw.WriteLine("\n{0,-43} {1}", "Long Date Pattern:", dtfi.LongDatePattern);
sw.WriteLine(dt.ToString("D"));
sw.WriteLine("\n{0,-43} {1}", "Short Date Pattern:", dtfi.ShortDatePattern);
sw.WriteLine(dt.ToString("d"));
sw.Close();
}
}
// The example writes the following output to a file:
// Full Date and Time Pattern: gg y'年'M'月'd'日' H:mm:ss
// 平成 24年5月1日 0:00:00
//
// Long Date Pattern: gg y'年'M'月'd'日'
// 平成 24年5月1日
//
// Short Date Pattern: gg y/M/d
// 平成 24/5/1
Imports System.Globalization
Imports System.IO
Imports System.Threading
Module Example
Public Sub Main()
Dim sw As New StreamWriter(".\eras.txt")
Dim dt As Date = #05/01/2012#
Dim culture As CultureInfo = CultureInfo.CreateSpecificCulture("ja-JP")
Dim dtfi As DateTimeFormatInfo = culture.DateTimeFormat
dtfi.Calendar = New JapaneseCalendar()
Thread.CurrentThread.CurrentCulture = culture
sw.WriteLine("{0,-43} {1}", "Full Date and Time Pattern:", dtfi.FullDateTimePattern)
sw.WriteLine(dt.ToString("F"))
sw.WriteLine()
sw.WriteLine("{0,-43} {1}", "Long Date Pattern:", dtfi.LongDatePattern)
sw.WriteLine(dt.ToString("D"))
sw.WriteLine()
sw.WriteLine("{0,-43} {1}", "Short Date Pattern:", dtfi.ShortDatePattern)
sw.WriteLine(dt.ToString("d"))
sw.WriteLine()
sw.Close()
End Sub
End Module
' The example writes the following output to a file:
' Full Date and Time Pattern: gg y'年'M'月'd'日' H:mm:ss
' 平成 24年5月1日 0:00:00
'
' Long Date Pattern: gg y'年'M'月'd'日'
' 平成 24年5月1日
'
' Short Date Pattern: gg y/M/d
' 平成 24/5/1
Advertencia
La JapaneseCalendar clase es la única clase de calendario en .NET que admite fechas en más de una era y que puede ser el calendario actual de un CultureInfo objeto , específicamente, de un CultureInfo objeto que representa la referencia cultural japonesa (Japón).
Para todos los calendarios, el especificador de formato personalizado "g" incluye la era en la cadena de resultado. En el ejemplo siguiente se usa la cadena de formato personalizado "MM-dd-aaaa g" para incluir la era en la cadena de resultado cuando el calendario actual es el calendario gregoriano.
DateTime dat = new DateTime(2012, 5, 1);
Console.WriteLine($"{dat:MM-dd-yyyy g}");
// The example displays the following output:
// 05-01-2012 A.D.
Dim dat As Date = #05/01/2012#
Console.WriteLine("{0:MM-dd-yyyy g}", dat)
' The example displays the following output:
' 05-01-2012 A.D.
En los casos en los que la representación de cadena de una fecha se expresa en un calendario que no es el calendario actual, la Calendar clase incluye un Calendar.GetEra método que se puede usar junto con los Calendar.GetYearmétodos , Calendar.GetMonthy Calendar.GetDayOfMonth para indicar de forma inequívoca una fecha, así como la era a la que pertenece. En el ejemplo siguiente se usa la JapaneseLunisolarCalendar clase para proporcionar una ilustración. Sin embargo, tenga en cuenta que incluir un nombre descriptivo o una abreviatura en lugar de un entero para la era en la cadena de resultado requiere que cree una instancia de un DateTimeFormatInfo objeto y haga JapaneseCalendar su calendario actual. (El JapaneseLunisolarCalendar calendario no puede ser el calendario actual de ninguna referencia cultural, pero en este caso los dos calendarios comparten las mismas eras).
using System;
using System.Globalization;
public class Example
{
public static void Main()
{
DateTime date1 = new DateTime(2011, 8, 28);
Calendar cal = new JapaneseLunisolarCalendar();
Console.WriteLine("{0} {1:d4}/{2:d2}/{3:d2}",
cal.GetEra(date1),
cal.GetYear(date1),
cal.GetMonth(date1),
cal.GetDayOfMonth(date1));
// Display eras
CultureInfo culture = CultureInfo.CreateSpecificCulture("ja-JP");
DateTimeFormatInfo dtfi = culture.DateTimeFormat;
dtfi.Calendar = new JapaneseCalendar();
Console.WriteLine("{0} {1:d4}/{2:d2}/{3:d2}",
dtfi.GetAbbreviatedEraName(cal.GetEra(date1)),
cal.GetYear(date1),
cal.GetMonth(date1),
cal.GetDayOfMonth(date1));
}
}
// The example displays the following output:
// 4 0023/07/29
// 平 0023/07/29
Imports System.Globalization
Module Example
Public Sub Main()
Dim date1 As Date = #8/28/2011#
Dim cal As New JapaneseLunisolarCalendar()
Console.WriteLine("{0} {1:d4}/{2:d2}/{3:d2}",
cal.GetEra(date1),
cal.GetYear(date1),
cal.GetMonth(date1),
cal.GetDayOfMonth(date1))
' Display eras
Dim culture As CultureInfo = CultureInfo.CreateSpecificCulture("ja-JP")
Dim dtfi As DateTimeFormatInfo = culture.DateTimeFormat
dtfi.Calendar = New JapaneseCalendar()
Console.WriteLine("{0} {1:d4}/{2:d2}/{3:d2}",
dtfi.GetAbbreviatedEraName(cal.GetEra(date1)),
cal.GetYear(date1),
cal.GetMonth(date1),
cal.GetDayOfMonth(date1))
End Sub
End Module
' The example displays the following output:
' 4 0023/07/29
' 平 0023/07/29
En los calendarios japoneses, el primer año de una era se denomina Gannen (元年). Por ejemplo, en lugar de Heisei 1, el primer año de la era Heisei se puede describir como Heisei Gannen. .NET adopta esta convención en las operaciones de formato de fechas y horas cuando se utilizan cadenas de formato de fecha y hora, estándar o personalizadas, con un objeto CultureInfo que representa la cultura Japanese-Japan ("ja-JP") utilizando la clase JapaneseCalendar.
- Patrón de fecha larga, indicado por la cadena de formato de fecha y hora estándar "D".
- Patrón completo de fecha y hora larga, indicado por la cadena de formato de fecha y hora estándar "F".
- Patrón completo de fecha y hora larga, indicado por la cadena de formato de fecha y hora estándar "f".
- Patrón de año/mes, indicado por la cadena de formato de fecha estándar "Y" o"y".
- La cadena de formato de fecha y hora personalizados "ggy'年'" o "ggy年".
Por ejemplo, en el ejemplo siguiente se muestra una fecha en el primer año de la era Heisei en JapaneseCalendar.
using System;
using System.Globalization;
public class Example
{
public static void Main()
{
var enUs = new CultureInfo("en-US");
var japaneseCal = new JapaneseCalendar();
var jaJp = new CultureInfo("ja-JP");
jaJp.DateTimeFormat.Calendar = japaneseCal;
string heiseiEra = "平成";
var date = japaneseCal.ToDateTime(1, 8, 18, 0, 0, 0, 0, GetEraIndex(heiseiEra));
FormattableString fmt = $"{date:D}";
Console.WriteLine($"Japanese calendar date: {fmt.ToString(jaJp)} (Gregorian: {fmt.ToString(enUs)})");
int GetEraIndex(string eraName)
{
foreach (var ctr in japaneseCal.Eras)
if (jaJp.DateTimeFormat.GetEraName(ctr) == eraName)
return ctr;
return 0;
}
}
}
// The example displays the following output:
// Japanese calendar date: 平成元年8月18日 (Gregorian: Friday, August 18, 1989)
Imports System.Globalization
Module Program
Dim jaJp As CultureInfo
Dim japaneseCal As Calendar
Sub Main()
Dim enUs = New CultureInfo("en-US")
japaneseCal = New JapaneseCalendar()
jaJp = New CultureInfo("ja-JP")
jaJp.DateTimeFormat.Calendar = japaneseCal
Dim heiseiEra = "平成"
Dim dat = japaneseCal.ToDateTime(1, 8, 18, 0, 0, 0, 0, GetEraIndex(heiseiEra))
Dim fmt As FormattableString = $"{dat:D}"
Console.WriteLine($"Japanese calendar date: {fmt.ToString(jaJp)} (Gregorian: {fmt.ToString(enUs)})")
End Sub
Private Function GetEraIndex(eraName As String) As Integer
For Each ctr In japaneseCal.Eras
If jaJp.DateTimeFormat.GetEraName(ctr) = eraName Then
Return ctr
End If
Next
Return 0
End Function
End Module
' The example displays the following output:
' Japanese calendar date: 平成元年8月18日 (Gregorian: Friday, August 18, 1989)
Si este comportamiento no es deseable en las operaciones de formato, puede restaurar el comportamiento anterior, que siempre representa el primer año de una era como "1" en lugar de "Gannen", haciendo lo siguiente, en función de la versión de .NET:
.NET Core: Agregue lo siguiente al archivo de configuración de.netcore.runtime.json :
"runtimeOptions": { "configProperties": { "Switch.System.Globalization.FormatJapaneseFirstYearAsANumber": true } }
.NET Framework 4.6 o posterior: Establezca el siguiente modificador AppContext en el archivo app.config :
<?xml version="1.0" encoding="utf-8"?> <configuration> <runtime> <AppContextSwitchOverrides value="Switch.System.Globalization.FormatJapaneseFirstYearAsANumber=true" /> </runtime> </configuration>
.NET Framework 4.5.2 o versiones anteriores: Establezca el siguiente valor del Registro:
Importancia clave HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\AppContext Entrada Switch.System.Globalization.FormatJapaneseFirstYearAsANumber Tipo REG_SZ Valor cierto
Con la compatibilidad con Gannen en las operaciones de formato deshabilitadas, en el ejemplo anterior se muestra la siguiente salida:
Japanese calendar date: 平成1年8月18日 (Gregorian: Friday, August 18, 1989)
.NET también se ha actualizado para que las operaciones de análisis de fecha y hora admitan cadenas que contienen el año representado como "1" o Gannen. Aunque no es necesario hacerlo, puede restaurar el comportamiento anterior para que solo reconozca "1" como primer año de una era. Puede hacerlo de la siguiente manera, en función de la versión de .NET:
.NET Core: Agregue lo siguiente al archivo de configuración de.netcore.runtime.json :
"runtimeOptions": { "configProperties": { "Switch.System.Globalization.EnforceLegacyJapaneseDateParsing": true } }
.NET Framework 4.6 o posterior: Establezca el siguiente modificador AppContext en el archivo app.config :
<?xml version="1.0" encoding="utf-8"?> <configuration> <runtime> <AppContextSwitchOverrides value="Switch.System.Globalization.EnforceLegacyJapaneseDateParsing=true" /> </runtime> </configuration>
.NET Framework 4.5.2 o versiones anteriores: Establezca el siguiente valor del Registro:
Importancia clave HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\AppContext Entrada Switch.System.Globalization.EnforceLegacyJapaneseDateParsing Tipo REG_SZ Valor cierto