Análisis de cadenas de fecha y hora en .NET
El análisis de cadenas para convertirlas en objetos DateTime requiere que se especifique información sobre cómo se representan las fechas y horas en forma de texto. Las distintas referencias culturales usan distintos órdenes de día, mes y año. Algunas representaciones horarias usan el reloj de 24 horas y otras especifican "a. m." y "p. m.". Algunas aplicaciones solo necesitan la fecha. Otras solo necesitan la hora. Pero otras necesitan especificar la fecha y la hora. Los métodos que convierten cadenas a objeto DateTime permiten especificar información detallada sobre los formatos esperados y los elementos de fecha y hora que precisa la aplicación. Hay tres subtareas para convertir correctamente el texto en un objeto DateTime:
- Debe especificarse el formato esperado del texto que representa una fecha y hora.
- Puede especificar la referencia cultural del formato de fecha y hora.
- Puede especificarse cómo se establecen los componentes que faltan en la representación de texto en la fecha y hora.
Los métodos Parse y TryParse convierten varias representaciones comunes de fecha y hora. Los métodos ParseExact y TryParseExact convierten una representación de cadena que se ajusta al modelo especificado por una cadena de formato de fecha y hora. Para obtener más información, consulte los artículos sobre cadenas de formato de fecha y hora estándar y cadenas de formato de fecha y hora personalizadas.
El objeto DateTimeFormatInfo actual proporciona más control sobre la forma en que debe interpretarse el texto como fecha y hora. Las propiedades de un objeto DateTimeFormatInfo describen los separadores de fecha y hora, los nombres de los meses, días y eras y el formato de las designaciones "a. m." y "p. m.". El objeto CultureInfo devuelto por CultureInfo.CurrentCulture tiene una propiedad CultureInfo.DateTimeFormat que representa la referencia cultural actual. Si quiere una referencia cultural específica o una configuración personalizada, especifique el parámetro IFormatProvider de un método de análisis. Para el parámetro IFormatProvider, especifique un objeto CultureInfo, que representa una referencia cultural, o un objeto DateTimeFormatInfo.
Es posible que al texto que representa una fecha y hora le falte alguna información. Por ejemplo, la mayoría de los usuarios supondría que la fecha "12 de marzo" representa el año actual. Del mismo modo, "Marzo de 2018" representa el mes de marzo del año 2018. El texto que representa la hora a menudo solo incluye horas, minutos y una designación "a. m."/"p. m.". Los métodos de análisis controlan esta información que falta mediante valores predeterminados razonables:
- Cuando solo se indica la hora, la parte de fecha utiliza la fecha actual.
- Cuando solo se indica la fecha, la parte de hora es la medianoche.
- Cuando no se especifica el año en una fecha, se usa el año actual.
- Cuando no se especifica el día del mes, se usa el primero del mes.
Si la fecha se indica en la cadena, debe incluir el mes y uno de los dos valores, el día o el año. Si se indica la hora, debe incluir la hora y los minutos o el designador "a. m."/"p. m.".
Se puede especificar la constante NoCurrentDateDefault para invalidar los valores predeterminados. Cuando se usa esta constante, las propiedades de año, mes o día se establecen en el valor 1
. El último ejemplo con Parse muestra este comportamiento.
Además de un componente de fecha y hora, la representación de cadena de una fecha y hora puede incluir una diferencia horaria que indica cuánto difiere la hora respecto de la hora universal coordinada (UTC). Por ejemplo, la cadena "14/2/2007 5:32:00 -7:00" define una hora que es siete horas anterior a la hora UTC. Si se omite la diferencia horaria de la representación de cadena de una hora, el análisis devuelve un objeto DateTime con su propiedad Kind establecida en DateTimeKind.Unspecified. Si se especifica una diferencia horaria, el análisis devuelve un objeto DateTime con su propiedad Kind establecida en DateTimeKind.Local. Su valor también se ajusta a la zona horaria local de la máquina. Puede modificar este comportamiento usando un valor DateTimeStyles con el método de análisis.
El proveedor de formato también se usa para interpretar una fecha numérica ambigua. No queda claro qué componentes de la fecha representada por la cadena "02/03/04" son el mes, el día y el año. Los componentes se interpretan según el orden de formatos de fecha similares del proveedor de formato.
Parse
En el ejemplo siguiente se muestra el uso del método DateTime.Parse para convertir un objeto string
en un valor DateTime. En este ejemplo se usa la referencia cultural asociada al subproceso actual. Si el objeto CultureInfo asociado a la referencia cultural actual no puede analizar la cadena de entrada, se produce una excepción FormatException.
Sugerencia
Todos los ejemplos de C# en este artículo se ejecutan en el explorador. Presione el botón Ejecutar para ver el resultado. También puede modificarlos para experimentar.
Nota
Estos ejemplos están disponibles en el repositorio de documentos de GitHub para C# y Visual Basic.
string dateInput = "Jan 1, 2009";
var parsedDate = DateTime.Parse(dateInput);
Console.WriteLine(parsedDate);
// Displays the following output on a system whose culture is en-US:
// 1/1/2009 00:00:00
Dim MyString As String = "Jan 1, 2009"
Dim MyDateTime As DateTime = DateTime.Parse(MyString)
Console.WriteLine(MyDateTime)
' Displays the following output on a system whose culture is en-US:
' 1/1/2009 00:00:00
Además, puede definir explícitamente la referencia cultural cuyas convenciones de formato se utilizan cuando se analiza una cadena. Especifique uno de los objetos DateTimeFormatInfo estándar devueltos por la propiedad CultureInfo.DateTimeFormat. En el ejemplo siguiente se usa un proveedor de formato para analizar una cadena en alemán como valor DateTime. Crea un objeto CultureInfo que representa la referencia cultural de-DE
. El objeto CultureInfo
garantiza el análisis correcto de esta cadena concreta. Este proceso impide cualquier opción que se encuentre en CurrentCulture de CurrentThread.
var cultureInfo = new CultureInfo("de-DE");
string dateString = "12 Juni 2008";
var dateTime = DateTime.Parse(dateString, cultureInfo);
Console.WriteLine(dateTime);
// The example displays the following output:
// 6/12/2008 00:00:00
Dim MyCultureInfo As New CultureInfo("de-DE")
Dim MyString As String = "12 Juni 2008"
Dim MyDateTime As DateTime = DateTime.Parse(MyString, MyCultureInfo)
Console.WriteLine(MyDateTime)
' The example displays the following output:
' 6/12/2008 00:00:00
Sin embargo, puede usar sobrecargas del método Parse para especificar proveedores de formato personalizados. El método Parse no admite el análisis de formatos no estándar. Para analizar una fecha y hora expresadas en un formato no estándar, use en su lugar el método ParseExact.
En el ejemplo siguiente se usa la enumeración DateTimeStyles para especificar que no debe agregarse la información de fecha y hora actual al valor DateTime en los campos no especificados.
var cultureInfo = new CultureInfo("de-DE");
string dateString = "12 Juni 2008";
var dateTime = DateTime.Parse(dateString, cultureInfo,
DateTimeStyles.NoCurrentDateDefault);
Console.WriteLine(dateTime);
// The example displays the following output if the current culture is en-US:
// 6/12/2008 00:00:00
Dim MyCultureInfo As New CultureInfo("de-DE")
Dim MyString As String = "12 Juni 2008"
Dim MyDateTime As DateTime = DateTime.Parse(MyString, MyCultureInfo,
DateTimeStyles.NoCurrentDateDefault)
Console.WriteLine(MyDateTime)
' The example displays the following output if the current culture is en-US:
' 6/12/2008 00:00:00
ParseExact
Si se ajusta a uno de los patrones de cadena especificados, el método DateTime.ParseExact convierte una cadena en un objeto DateTime. Cuando se pasa a este método una cadena que no tiene uno de las formas especificadas, se genera una excepción FormatException. Puede definirse uno de los especificadores de formato de fecha y hora estándar o una combinación de los especificadores de formato de fecha y hora personalizados. Con el uso de especificadores de formato personalizados, es posible construir una cadena de reconocimiento personalizada. Para obtener una explicación de los especificadores, consulte los artículos sobre cadenas con formato de fecha y hora estándar y cadenas con formato de fecha y hora personalizado.
En el ejemplo siguiente, se pasa al método DateTime.ParseExact un objeto de cadena para que lo analice, seguido de un especificador de formato y luego de un objeto CultureInfo. Este método ParseExact solo puede analizar cadenas que sigan el patrón de fecha larga en la referencia cultural en-US
.
var cultureInfo = new CultureInfo("en-US");
string[] dateStrings = { " Friday, April 10, 2009", "Friday, April 10, 2009" };
foreach (string dateString in dateStrings)
{
try
{
var dateTime = DateTime.ParseExact(dateString, "D", cultureInfo);
Console.WriteLine(dateTime);
}
catch (FormatException)
{
Console.WriteLine("Unable to parse '{0}'", dateString);
}
}
// The example displays the following output:
// Unable to parse ' Friday, April 10, 2009'
// 4/10/2009 00:00:00
Dim MyCultureInfo As New CultureInfo("en-US")
Dim MyString() As String = {" Friday, April 10, 2009", "Friday, April 10, 2009"}
For Each dateString As String In MyString
Try
Dim MyDateTime As DateTime = DateTime.ParseExact(dateString, "D",
MyCultureInfo)
Console.WriteLine(MyDateTime)
Catch e As FormatException
Console.WriteLine("Unable to parse '{0}'", dateString)
End Try
Next
' The example displays the following output:
' Unable to parse ' Friday, April 10, 2009'
' 4/10/2009 00:00:00
Cada sobrecarga de los métodos Parse y ParseExact tiene también un parámetro IFormatProvider que proporciona información específica de la referencia cultural sobre el formato de la cadena. El objeto IFormatProvider es un objeto CultureInfo que representa una referencia cultural estándar o un objeto DateTimeFormatInfo devuelto por la propiedad CultureInfo.DateTimeFormat. ParseExact usa también una cadena o un argumento de matriz de cadena adicional que define uno o más formatos de fecha y hora personalizados.