2010-03-06 10 views
19

Estoy jugando con algunos datos históricos en los que algunas fechas sé con precisión (es decir, dd/mm/aaaa), mientras que otros son aaaa y otros son aaaa? (es decir, el año es incierto). Incluso me encontré con fl, lo que aparentemente significa "floreció".¿Existe una forma estándar de representar fechas inciertas en C#?

Por el momento estoy usando la clase DateTime que no parece ser compatible con el marcado/representación de dicha incertidumbre. ¿Hay una forma estándar de abordar este problema?

+2

Las fechas inciertas están codificadas en cualquier plataforma que use eHarmony. –

Respuesta

6

Hay varios artículos académicos sobre formas de representar la hora aproximada, 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 bool/nullable con valores DateTime.

No he visto una biblioteca C# para manejar esto todavía. Mi propio motor de lenguaje natural 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 un mes/día), un año + mes conocido (pero ninguna fecha), un rango medio infinito (por ejemplo, antes o después de fecha dada), ... y al usarlos puede construir consultas contra bases de datos o puede enumerar todos los posibles rangos de fechas que podrían significar. p.ej. puede preguntar "quién llamó el año pasado el viernes después de las 4 p.m." y puede generar la consulta SQL adecuada.

¡Si quiere hacer esto bien, no es fácil! Si yo fuera usted, capturaría un valor de cadena con el texto original junto con la representación que eligiera para los valores de DateTime. De esta forma, puede hacer que la representación sea más inteligente a lo largo del tiempo para abarcar más casos; en última instancia, puede manejar algo como "entre 1940 y el 16 de septiembre de 1945.

Inicialmente es posible que desee almacenar solo la representación de cadena y dos valores de DateTime: lo más pronto posible y la última fecha posible. Eso cubre la mayoría de los casos que verá y es muy fácil consultar en contra. Puede dejar el valor de Datetime nulo o quizás establecerlo en un valor máximo o mínimo para representar rangos medios infinitos como "after 1900 ".

+0

+1 Acepta que implica el análisis de lenguaje natural. –

+0

Me gusta la idea de capturar la representación de cadena original, y gracias por la ref. –

1

DateTime? es nulable. Esa podría ser tu mejor apuesta. La otra alternativa es DateTime.MinValue (o MaxValue).

[Editar] En realidad, releyendo su pregunta, creo que su mejor opción es diseñar una clase personalizada que sirva para su propósito exacto.

11

Consideraría crear una clase que ajuste un DateTime (o DateTimeOffset) y tenga campos adicionales para representar qué partes de la fecha son ciertas y cuáles no.

Podría exponer los campos de mes, día y año como valores que aceptan valores nulos para reflejar qué partes de la fecha se conocen.

+0

No solo lo consideraría. Yo haría esto. La incertidumbre es información adicional que necesita ser modelada o representada de alguna manera, y DateTime no hace eso. – Cheeso

+0

Este enfoque no es tan bueno para muchas de las fechas históricas comunes que obtienes en documentos antiguos o fotos como "circa 1950" o "después de junio de 1945". Circa 1950 se asignaría a? /? /? si todo lo que modela es un DateTime con incertidumbre en las partes de la fecha. –

2

Si la incertidumbre es binaria (es decir, la fecha es conocida o desconocida), iría con un tipo de fecha y hora anulable. De lo contrario, me gustaría considerar la creación de una estructura de envoltura con una propiedad de enumeración adicional:

public enum DateConfidence 
{ 
    Certain, 
    Unknown, 
    YearOnly, 
    ApproximateYearOnly 
} 
0

No existe dicha clase en .Net, por lo que lo mejor es crear su propia clase con propiedades que admitan nulos que representen todos los campos de fecha necesarios.

Esto le dará la mayor flexibilidad en el futuro y le permitirá manejar cualquier situación que pueda tener (si no, simplemente refactorizará su clase y el compilador lo ayudará a encontrar los lugares donde se debe hacer la corrección).

1

La datación por radio de carbono sería un ejemplo típico de esto. Necesitas una clase con dos miembros. La fecha adivinada y la estimación de error. Este último generalmente se expresa en años, pero puedes elegir cualquier unidad. Tenga en cuenta que DateTime no puede expresar una fecha anterior a 0 BCE, por lo que conviértalo en una int simple para el año. Evite hacer que sea más elegante que eso, adivinar que el mes correcto no tiene sentido para cualquier fecha anterior al año 1000.

+0

Gracias por la propina en el límite de 0 BCE, quedé atrapado por el límite de 1900 en Excel ... –

0

Mi preferencia para dicha 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] */ 
} 

Entonces tendría una serie de constructores que Vamos a poner un año, gama mes o una sola fecha, cada uno con un valor de confianza. La confianza me da un número "gomoso" para las comparaciones difusas.

Si configuro un solo día, el StartDate & EndDate debe abarcar esa fecha.

Depende de sus necesidades la forma de determinar las comparaciones entre los objetos HistorialDateRange. Esperaría métodos que me permitan preguntar si son distintos, superpuestos, etc.

Espero que ayude.

0

A ligeramente 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, como lo es. El significado real de los datos proviene del contexto donde se usa. Puede argumentar que estamos perdiendo el significado, pero de hecho forzar esos datos con muchos valores anulables/arbitrarios para el objeto DateTime es igual de irrelevante. Toma esto como ejemplo:

  • 1910 - 1929
  • < 1960 o antes 1960
  • Jul 1950 o después Jul 1950

  • 1950 - Presente o 1950 - Ahora

A menos que pueda satisfacer todas las posibilidades, el mapeo temprano del período xt en un objeto de estructura como DateTime, puede perder datos. Tome Now/Present como ejemplo, es un valor relativo que solo debe ser sustituido cuando no se usa cuando analiza o convierte el valor. ¿Cómo almacenarías antes y después de cierta fecha? Por supuesto, con un montón de trabajo de modelado, puede capturar toda esta información de forma estructurada para todas las posibilidades.

El texto del período debe interpretarse en el contexto de cuándo y cómo se está utilizando y puede utilizar cualquier método de análisis o análisis de 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.

Cuestiones relacionadas