2011-03-01 14 views
14

Estoy usando fechas de forma libre como parte de una sintaxis de búsqueda. Necesito analizar las fechas de las cadenas, pero solo conservar las partes de la fecha que están realmente especificadas. Por ejemplo, "1 de noviembre de 2010" es una fecha específica, pero "noviembre de 2010" es el rango de fechas "1 de noviembre de 2010" a "30 de noviembre de 2010".Fechas de análisis sin todos los valores especificados

Desafortunadamente, DateTime.Parse y amigos PARSE estas fechas para la misma DateTime:

DateTime.Parse("November 1, 2010") // == {11/1/2010 12:00:00 AM} 
DateTime.Parse("November, 2010") // == {11/1/2010 12:00:00 AM} 

Necesito saber qué partes de la realidad DateTime se analizan y que se han adivinado por el analizador. Esencialmente, necesito DateTime.Parse("November, 2010") == {11/-1/2010 -1:-1:-1}; Luego puedo ver que falta la porción del día y calcular el rango de fechas que cubre todo el mes.

(Internamente, C# tiene las DateTimeParse y DateTimeResult clases que analizan la fecha y preservan la información que necesito exactamente, pero en el momento de la fecha vuelve a las interfaces públicas que ha sido despojado de. Prefiero evitar la reflexión en estas clases, a menos que esa sea realmente la única ruta.)

¿Hay alguna forma de obtener DateTime.Parse para decirme qué formato usó para analizar la fecha? ¿O puede el DateTime devuelto tener marcadores de posición para piezas no especificadas? También estoy abierto a usar otro analizador de fechas, pero me gustaría que fuera tan confiable y flexible como el interno. Gracias por adelantado.

EDITAR: También he intentado ParseExact, pero enumerar todos los formatos que puede manejar Parse parece casi imposible. Parse realmente acepta más formatos que los devueltos por DateTimeFormatInfo.GetAllDateTimePatterns, que es una fuente tan canónica como puedo encontrar.

Respuesta

2

Puede intentar usar TryParseExact(), que fallará si la cadena de datos no está en el formato exacto especificado. Pruebe varias combinaciones diferentes, y cuando tenga éxito, conozca el formato en que se encontraba la fecha, y así sabrá las partes de la fecha que no estaban allí y para las cuales el analizador ingresó los valores predeterminados. La desventaja es que debes anticipar cómo el usuario querrá ingresar las fechas, por lo que puedes esperar eso exactamente.

También podría usar un Regex para digerir la cadena de fecha usted mismo. Nuevamente, necesitarás diferentes expresiones regulares (o una muy REALMENTE compleja), pero también es posible separar la cadena de esta manera; entonces sabes lo que realmente tienes.

+0

Consulte mi edición anterior. ParseExact parece ser insuficiente para el análisis de fecha general. – kevingessner

0

Esencialmente, necesito DateTime.Parse ("de noviembre de 2010") == {11/-1/2010 -1: -1: -1}; Entonces puedo ver que falta la porción del día y calcular el rango de fechas que cubre durante todo el mes.

Lo que quiere es un DateTime ilegal porque no puede tener valores negativos de horas/segundos/minutos/día. Si desea devolver otra cosa que no sea un DateTime legal, debe escribir su propio método que NO devuelve un DateTime.

¿Hay alguna manera de conseguir DateTime.Parse me diga qué formato se utiliza para analizar la fecha? ¿O puede el devuelto DateTime tener marcadores de posición para piezas no especificadas?También estoy abierto para utilizar otro analizador de fechas, pero me gustaría me gusta que sea tan confiable y locale-flexible como el interno.

Echa un vistazo aquí http://msdn.microsoft.com/en-us/library/w2sa9yss.aspx

Usted va a tener que mantener manualmente un registro de lo que se ingresa para realizar esta tarea. La única solución es asegurarse de que la entrada esté en el formato correcto.

+3

Creo que el especificador -1 fue solo un ejemplo para decir 'Necesito un método que indique qué partes del DateTime adivinó' no literalmente que quería un DateTime con -1 valores ahí. –

+1

Michael Pryor es correcto, quise decir -1 como solo un marcador de posición para partes no especificadas. – kevingessner

2

Parse analiza un montón de cosas que ninguna persona en su sano juicio ingresaría como una fecha, como "January/2010 - 21 12: 00 :2". Creo que tendrá que escribir su propio analizador de fecha si quiere saber exactamente qué escribió el usuario.

Personalmente, lo haría como sugirió KeithS: Analice la cadena con Parse y llame solo a su propia función de análisis si hay un 0 en uno de los campos del objeto DateTime. No existen esas posibilidades que debe verificar, porque si el día es 0, el tiempo será 0 también. Así que comience a verificar año, mes, día, etc.

O simplemente solicite al usuario que use formatos específicos que usted reconoce.

+1

"Analice la cadena con Parse y solo llame a su propia función de análisis si hay un 0 en uno de los campos del objeto DateTime". - Tristemente, la parte del día de DateTime nunca puede ser 0. Se establece en 1 si no se especifica, que no se puede distinguir de que se especifique como 1. – kevingessner

0

He utilizado este método que se remonta a la cadena original con el fin de comprobar la existencia del día y el año:

  • Para días, la cadena original debe contener un 1 como entero si el día fue especificado. Por lo tanto, divida la cadena y busque un 1. La única excepción se produce cuando el mes es enero (mes # 1), por lo que debe verificar dos 1 o 1 y "enero" o "enero" en la cadena original.
  • Para años, la cadena original debe contener un número que puede ser de un año (por ejemplo, de 1900 a 2100). Otras posibilidades pueden ser el uso de un apóstrofo, o cosas como 02-10-16, que puede reconocer por el hecho de que hay exactamente tres números.

Sé que esto es bastante heurístico, pero es una solución rápida y simple que funciona en la mayoría de los casos. Codifiqué este algoritmo en C# en los métodos DateFinder.DayExists() y DateFinder.YearExists() en la biblioteca sharp-datefinder.

Cuestiones relacionadas