today - ¿Hay una forma estándar de representar fechas inciertas en C#?
formato fecha datetime c# (8)
Estoy jugando con algunos datos históricos donde algunas fechas que conozco con precisión (es decir, dd / mm / aaaa), mientras que otras son solo yyyy y otras son yyyy? (Es decir, el año es incierto). Incluso me he encontrado con fl, que aparentemente significa "floreció".
En este momento estoy usando la clase DateTime que no parece admitir el marcado / representación de tal incertidumbre. ¿Hay una manera estándar de abordar este problema?
Consideraría crear una clase que incluya un DateTime (o DateTimeOffset) y tenga campos adicionales para representar qué partes de la fecha son ciertas y cuáles no.
A continuación, puede exponer los campos de mes, día y año como valores anulables para reflejar qué partes de la fecha se conocen.
Hay varios trabajos académicos sobre formas de representar el tiempo aproximado, por ejemplo, http://www.musiccog.ohio-state.edu/Humdrum/representations/date.rep.html
Si desea manejar el alcance completo de los documentos históricos y el conocimiento aproximado que tendrá para cualquiera de ellos, no es una simple operación de bool / nullable con valores de fecha y hora.
No he visto una biblioteca de C # para manejar esto todavía. Mi propio Natural Language Engine para C # puede comprender todo tipo de frases de fecha y hora, pero fue diseñado para un problema diferente: puede aceptar una pregunta imprecisa y consultar una base de datos de valores exactos.
Tiene clases para una fecha específica, un rango de fechas, un año conocido (pero no mes / día), un año conocido + mes (pero sin fecha), un rango medio infinito (por ejemplo, antes o después de una fecha determinada), ... y al usarlos, puede construir consultas contra bases de datos o puede enumerar todos los rangos posibles de fechas que podrían significar. por ejemplo, puede preguntarle "quién llamó el año pasado el viernes después de las 4 pm" y puede generar la consulta SQL adecuada.
¡Si quieres hacer esto bien no es fácil! Si yo fuera usted, capturaría un valor de cadena con el texto original junto con cualquier representación que elija para los valores de Fecha y hora. De esa manera, puede hacer que la representación sea más inteligente con el tiempo para cubrir más casos, y finalmente podrá manejar algo como "en algún momento entre 1940 y el 16 de septiembre de 1945.
Inicialmente, es posible que desee almacenar solo la representación de cadena y dos valores DateTime: la fecha más antigua posible y la fecha más reciente. Eso cubre la mayoría de los casos que verá y es muy fácil consultarlos. Puede dejar el valor de fecha y hora nulo o quizás establecerlo en el valor máximo o mínimo para representar rangos infinitos como "después de 1900".
La datación por radio carbono sería un ejemplo típico de esto. Necesitas una clase con dos miembros. La fecha estimada y la estimación de error. Este último generalmente se expresa en años, pero usted es libre de elegir cualquier unidad. Tenga en cuenta que DateTime no puede expresar una fecha antes del 0 a. C., así que conviértalo en un int simple para el año. Evite hacerlo más sofisticado que eso, adivinar el mes correcto no tiene sentido para ninguna fecha anterior al año 1000.
Mi preferencia por tal situación sería crear un objeto de rango de fechas con un grado de propiedad de certeza.
Algo como:
public struct HistorialDateRange
{
public DateTime StartDate { get; }
public DateTime EndDate { get; }
public double Confidence { get; } /* range [0.0, 1.0] */
}
Luego tendría una serie de constructores que me permitían establecer un año, un rango de mes o una sola fecha, cada uno con un valor de confianza. La confianza me da un número "elástico" para las comparaciones difusas.
Si configuro un solo día, la fecha de inicio y la fecha de finalización deben abarcar esa fecha.
Entonces depende de sus necesidades cómo determinar las comparaciones entre los objetos de HistorialDateRange
. Espero métodos que me permitan preguntar si son distintos, superpuestos, etc.
Espero que ayude.
No hay tal clase en .Net, por lo que lo mejor es crear su propia clase con propiedades que puedan contener nulos que representen todos los campos de fecha necesarios.
Esto le dará mayor flexibilidad en el futuro y le permitirá manejar cualquier escenario que pueda tener (de lo contrario, simplemente refactorice su clase y el compilador lo ayudará a encontrar lugares donde debe hacerse una corrección).
Si la incertidumbre es binaria (es decir, la fecha es conocida o desconocida), me gustaría ir con un tipo de fecha y hora que pueda contener nulos. De lo contrario, consideraría crear una estructura de envoltorio con una propiedad de enumeración adicional:
public enum DateConfidence
{
Certain,
Unknown,
YearOnly,
ApproximateYearOnly
}
Un poco fuera de la caja responde a su problema.
Si está tratando con datos históricos no estructurados como los describe, realmente los capturaré como una cadena, tal como es. El significado real de los datos proviene del contexto en el que se utilizan. Puede argumentar que estamos perdiendo el significado, pero de hecho, el hecho de forzar tales datos con muchos valores nulables / arbitrarios para el objeto DateTime no es tan significativo. Toma esto como ejemplo:
- 1910 - 1929
- <1960 o antes de 1960
Julio de 1950 o después de julio de 1950
- 1950 - Presente o 1950 - Ahora
A menos que pueda satisfacer todas las posibilidades, la asignación temprana del texto del período en un objeto de estructura como DateTime, puede potencialmente perder datos. Tome ahora / presente como ejemplo, es un valor relativo que solo debe sustituirse cuando no se utiliza cuando se analiza o convierte el valor. ¿Cómo almacenarías antes y después de cierta fecha? Por supuesto, con una gran cantidad de trabajos de modelado, puede capturar toda esta información de una manera estructurada para todas las posibilidades.
El texto del período se debe interpretar en el contexto de cuándo y cómo se está utilizando, y puede emplear el método de análisis o el lenguaje natural que le convenga. Si el análisis falla, siempre puede mejorarlo, pero no debe perder el significado semántico de los datos desde el principio al leerlos o migrarlos.
DateTime?
es anulable Esa podría ser tu mejor apuesta. La otra alternativa es DateTime.MinValue
(o MaxValue
).
[Editar] En realidad, releyendo tu pregunta, creo que lo mejor que puedes hacer es diseñar una clase personalizada que sirva a tu propósito exacto.