¿Cómo se almacenan las "fechas difusas" en una base de datos?


125

Este es un problema con el que me he encontrado algunas veces. Imagine que tiene un registro que desea almacenar en una tabla de base de datos. Esta tabla tiene una columna DateTime llamada "date_created". Este registro en particular fue creado hace mucho tiempo, y no estás realmente seguro de la fecha exacta, pero sabes el año y el mes. Otros registros que conoces solo el año. Otros registros que conoces el día, mes y año.

No puede usar un campo DateTime, porque "mayo de 1978" no es una fecha válida. Si lo divide en varias columnas, pierde la capacidad de consultar. ¿Alguien más se ha encontrado con esto? De ser así, ¿cómo lo manejaste?

Para aclarar el sistema que estoy construyendo, es un sistema que rastrea archivos. Algunos contenidos se produjeron hace mucho tiempo, y todo lo que sabemos es "mayo de 1978". Podría almacenarlo el 1 de mayo de 1978, pero solo con alguna forma de denotar que esta fecha solo es precisa para el mes. De esa manera, algunos años después, cuando estoy recuperando ese archivo, no me confundo cuando las fechas no coinciden.

Para mis propósitos, es importante diferenciar "día desconocido en mayo de 1978" con "1 de mayo de 1978". Además, no quisiera almacenar las incógnitas como 0, como "0 de mayo de 1978" porque la mayoría de los sistemas de bases de datos lo rechazarán como un valor de fecha no válido.


14
¿Es importante diferenciar "día desconocido en mayo de 1978" con "1 de mayo de 1978"?

55
@MichaelT: sí, es importante diferenciar.
nbv4


66
@aslum: la mayoría de los sistemas de bases de datos lo rechazarán como un valor de fecha no válido
nbv4

99
@JimmyHoffa: ¿nunca te has topado con un escenario de fechas borrosas o uno en el que necesitabas comparar fechas? En cualquier caso, uno común es un historial médico: recuerda que la apendicectomía fue el año pasado el 1 de abril, pero la amigdactomía fue en algún momento de 1975, y algo más sucedió durante mayo y junio de algún año. ¿Qué sucede si desea saber si algún evento médico fue antes o después de algún otro avance médico? ¿Ocurrió esto antes o después de que estuvieran revisando los suministros de sangre para el VIH?
jueves

Respuestas:


148

Almacene todas las fechas en el campo DATE normal en la base de datos y tenga un campo de precisión adicional de la precisión del campo DATE en realidad.

date_created DATE,
date_created_accuracy INTEGER, 

date_created_accuracy: 1 = fecha exacta, 2 = mes, 3 = año.

Si su fecha es confusa (por ejemplo, mayo de 1980) guárdela al inicio del período (por ejemplo, 1 de mayo de 1980). O si su fecha es exacta al año (por ejemplo, 1980), guárdela como el 1 de enero. 1980 con el correspondiente valor de precisión.

De esta manera, puede consultar fácilmente de una manera algo natural y aún tener noción de cuán precisas son las fechas. Por ejemplo, esto le permite consultar fechas entre Jan 1st 1980y Feb 28th 1981, y obtener fechas difusas 1980y May 1980.


1
Todavía tiene que calcular el final de la fecha aquí a partir de lo que puedo ver, así que creo que entre consultas es bastante feo ya que tiene un campo calculado que está seleccionando en el mejor de los casos.
Wyatt Barnett

8
Buena respuesta, muy inteligente. select * from mytable where date_created between "1980/1/1" and "1981/2/28" and date_created_accuracy <= 2;. Genio.
Naftuli Kay

58
Le animo a que considere la precisión de la fecha como simplemente "días". Donde un día exacto es 0. De esta manera, se pueden usar fechas más flexibles "En algún momento del verano" con una precisión de fecha de 90 días a partir del 1 de junio en lugar de rangos de fechas específicas codificadas. También podría manejar la precisión de varios años.

1
Tal vez deberías enviar eso como respuesta, MichaelT
Supr

1
+1: Otra cosa buena de esta solución es que puede agregar lógica de visualización en función del valor del date_created_accuracycampo. Puede mostrar "mayo de 1980" o simplemente "1980" en los resultados o la interfaz de usuario si eso es tan preciso como lo indica el campo.
Kyralessa

27

Si no necesita usar este tipo de datos como información regular de fecha y hora, cualquier formato de cadena simple lo haría.

Pero si necesita mantener toda la funcionalidad, se me ocurren dos soluciones alternativas, ambas requieren información adicional almacenada en la base de datos:

  1. Crear min datey max datecampos, que tienen valores diferentes para datos "incompletos", pero coincidirán para fechas precisas.
  2. Cree tipos para cada tipo de fecha imprecisa (ninguno _ 0, fecha_mision _ 1, mes_missing _ 2, year_missing_4, etc _ para que pueda combinarlos). Agregue un typecampo a los registros y guarde qué información falta.

Los campos de fecha mínima y máxima también fueron mi primer pensamiento.
Michael Itzoe

1
Hace mucho tiempo, tuvimos que resolver el mismo problema. Los usuarios podían contar historias sobre eventos que ocurrieron en cualquier momento en el pasado, por lo que tuvimos que admitir fechas difusas. Después de mucho ir y venir, la solución a la que llegamos es muy similar a la sugerencia de superM aquí, donde las fechas se almacenan como los instantes mínimos y máximos posibles que contendrían la fecha de la historia. Al informar la fecha, la precisión (es decir, "este registro es exacto para el mes / año / día") se puede extraer del delta entre las fechas mínimas y máximas. No es necesario almacenar un tercer campo para mayor precisión.
meetamit

44
+1 para min datey max datecampos. Creo que es la solución más flexible, precisa y fácil de usar.
Supr

1
Al principio era antagónico con esta idea. Pero al darme cuenta de que es el enfoque más flexible, voto por esto.
Anurag Kalia

Solo es natural. No estás describiendo tanto una fecha difusa como un marco de tiempo ... que tiene un comienzo y un final.
Pieter B

20

Esta es realmente más una definición de requisitos que un problema técnico: en lo que debe centrarse es en "cómo podemos definir las fechas en el pasado" y la solución técnica fluirá.

Las veces que he tenido que acercarme a algo como esto, típicamente:

  • Defina cómo mapear cosas: como sugiere MichaelT , decida que todo lo que se define como Mes / Día se define como medianoche el 1 de dicho mes. Esto suele ser lo suficientemente bueno para la mayoría de los propósitos: si la fecha exacta fuera tan importante, probablemente tendría un registro de eso 35 años después, ¿verdad?
  • Averigüe si necesita rastrear esto: IE, ¿los registros con fechas de creación ligeramente inventadas necesitan una bandera que lo diga? ¿O es solo un problema de capacitación del usuario para que la gente sepa y pueda actuar en consecuencia?

A veces, uno debe hacer algo como hacer que las fechas sean difusas, por ejemplo, que una fecha deba responder a una consulta para cualquier cosa en mayo de 1978. Esto es factible: solo haga sus campos create_date 2, los registros antiguos obtienen un 30 los días se extienden según corresponda, los nuevos obtienen 2 valores idénticos.


1
+1 - Estaba trabajando en formular una respuesta con el enfoque de doble fecha. Tu respuesta llegó aquí primero.

2
+1, es feo y crea una gran cantidad de información adicional inútil para las nuevas entradas que no lo requieren, pero por otro lado mantiene las consultas mucho más simples de lo que serían de otra manera. Llevamos un tiempo utilizando una solución similar para un problema relacionado.
Izkata

3
@Izkata: punto justo, pero qué tan elegante puede ser cuando necesita hacer algo que debería ser un solo punto en el lapso de un mes. Ciertamente más bonito que tener que calcular el inicio y el final de consultas sobre la marcha en algún lugar.
Wyatt Barnett

1
+1 por poder denotar granularidad arbitraria sin una explosión de valores de enumeración.
Dan Neely

18

La forma más sencilla de indicar si la fecha es precisa es crear un campo de precisión INT (1) con NULL predeterminado

Si la fecha es precisa, guarde la fecha y hora en "date_created" y deje la precisión NULL

Si la fecha solo es exacta al mes, guarde la fecha y hora como el 1er mes con un valor de precisión 1

Si la fecha solo es precisa para la fecha y hora de la tienda del año 1 de enero con un valor de precisión 2

Puede usar diferentes números para mantener diferentes valores, como el primer trimestre, etc.


Las consultas se vuelven realmente complicadas cuando haces eso.
Blrfl

3
Esto tiene dificultades con los datos que no están en un límite de mes limpio como "Q2 1991" y "Invierno 1978-1979".

1
OP quiere alguna forma de denotar que esta fecha solo es precisa para el mes.
David Strachan

77
Estás abusando del significado de NULL aquí. NULL significa "desconocido", por lo que si la fecha es precisa, la precisión no puede ser NULL. Puede ser '1'.
Konerak

@Konerak Semánticamente sí. Pero como la mayoría de las fechas son exactas, solo es necesario identificar los casos especiales y utilizar NULL aquí de forma predeterminada.
David Strachan

17

En el pasado, he almacenado fechas con precisión como una fecha de inicio y una fecha de finalización. El día may21,2012 se representaría como start = 12 am, may21,2012 y end = 12 am,may22,2012. El año 2012 se representaría como inicio = 12 a.m., enero1,2012 final = 12 a.m., enero1,2013.

No estoy seguro si recomendaría este enfoque. Al mostrar la información al usuario, debe detectar correctamente que un rango de fechas cubre exactamente un día para mostrar "25 de mayo" en lugar de dos puntos finales demasiado específicos (lo que significa lidiar con el horario de verano, etc.).

Sin embargo, cuando no está tratando de traducir a humanos, la programación con los puntos finales es mucho más fácil que con la precisión central +. No terminas con muchos casos. Eso es muy lindo.


En realidad, no tiene que ser tan complicado determinar cómo presentar un rango si el rango siempre se almacena como UTC. Como marcas de tiempo UTC, cada día, semana, mes, año, incluso estaciones y trimestres, tendrán dos números constantes, globales, distintos y fácilmente determinables que representan el inicio y el final del período. La lógica simplemente se convierte en unas pocas declaraciones if para ver si las dos fechas están al principio y al final de algún tipo de período. No se necesitan cosas complicadas de matemática o zona horaria :)
Supr

@Supr Determinar si un segundo en particular está en el límite de un período humano en particular es, en sí mismo, un problema difícil. Especialmente a largo plazo, con la rotación de la Tierra disminuyendo e interminables pequeños cambios en la definición humana de hora local.
Craig Gidney

14

¿Por qué no guardar dos fechas?

Created_After y Created_Before. La semántica real es "creada en o después" y "creada en o antes"

Entonces, si conoce la fecha exacta, Created_After y Created_Before serán la misma fecha.

Si sabe que fue la primera semana de mayo de 2000, Created_After = '2000-05-01' y Created_Before = '2000-05-07'.

Si conoce mayo de 1999, los valores serán '1999-05-01' y '1999-05-30'.

Si es "Verano de '42", entonces los valores serían '1942-06-01' y '1942-08-31'.

Este esquema es simple de consultar con SQL normal, y bastante fácil de seguir para un usuario no técnico.

Por ejemplo, para encontrar todos los documentos que podrían haberse creado en mayo de 2001:

SELECT * FROM DOCTAB WHERE Created_After < '2001-05-31' And Created_Before > 2001-05-01;

Por el contrario, para encontrar todos los documentos que se crearon definitivamente en mayo de 2001:

SELECT * FROM DOCTAB WHERE Created_After > '2001-05-01' And Created_Before < 2001-05-31;

1
Creo que esta es la solución más elegante.
Pieter B

Esto es lo mismo que las respuestas de superM y Strilanc. Sin embargo, hace +1 por explicar más claramente y mostrar cuán simple sería consultar.
Supr

9

El formato de fecha y hora ISO 8601 viene con definición de duración, p. Ej.

2012-01-01P1M (léase: 2012, 1 de enero, período: 1 mes) es lo que debería ser "en enero de 2012".

Lo usaría para almacenar los datos. Es posible que necesite un campo de base de datos de tipo Cadena para hacerlo. Es un tema diferente cómo realizar una búsqueda sensata sobre eso.


1 de la idea, pero -1 para no usar un campo de fecha por la razón de cómo buscar y / o encontrar
user151019

Depende de la base de datos. Sin embargo, esto puede ser base para la expansión, pero la pregunta es: ¿está el documento en el resultado establecido si busca, en este caso, todos los documentos más nuevos que el 12 de enero, o no? No es trivial Aquí, la pregunta era cómo almacenar fechas difusas.
Matthias Ronge

3

En general, todavía los almaceno como fechas para consultas generales, aún es posible aunque sea un poco menos preciso.

Si es importante saber la precisión que tengo en el pasado, o bien almacené una "ventana" de precisión como un decimal +/- o como una búsqueda (día, mes, año, etc.). En otros casos, en lugar de la ventana, simplemente almaceno el valor de la fecha original como una cadena y convierto lo que puedo a una fecha y hora, posiblemente 1978-05-01 00:00:00 y "mayo de 1978" para su ejemplo dado.


3

Si lo divide en varias columnas, pierde la capacidad de consultar.

¿Dice quién? Esto es lo que haces:

  1. Tiene 3 columnas, Día, Mes, Año, cada una de tipo int, y una cuarta columna de tipo TheDate of DateTime.
  2. Tenga un activador que use las 3 columnas Día, Mes, Año para construir TheDate si TheDate se deja nulo pero uno o más de los campos Día, Mes, Año tienen un valor.
  3. Tenga un activador que complete los campos Día, Mes, Año cuando se suministre TheDate pero estos campos no.

Entonces, si hago una inserción como: insert into thistable (Day, Month, Year) values (-1, 2, 2012);entonces TheDate se convertirá en 2/1/2013, pero sabré que realmente es una fecha indeterminada en 2/2012 debido al -1 en el campo Día.

Si insert into thistable (TheDate) values ('2/5/2012');entonces el día será 5, el mes será 2 y el año será 2012, y debido a que ninguno de ellos es -1, sabré que esta es la fecha exacta.

No pierdo la capacidad de consultar porque el activador de inserción / actualización se asegura de que mis 3 campos (Día, Mes, Año) siempre produzcan un valor DateTime en TheDate que se puede consultar.


3

Otra opción sería almacenar las fechas como enteros del formulario YYYYMMDD.

  • Solo sabes que el año es 1951: almacenar como 19510000
  • Usted sabe que el mes y el año es marzo de 1951: almacenar como 19510300
  • Sabes que la fecha completa es el 14 de marzo de 1951: almacenar como 19510314
  • Una fecha completamente desconocida: almacenar como 0

Beneficios

Puede almacenar su fecha difusa en un campo en lugar de dos campos de fecha o una fecha y una precisión como sugieren muchas de las otras respuestas.

Las consultas siguen siendo fáciles:

  • todos los registros para el año 1951 - SELECT * FROM table WHERE thedate>=19510000 and thedate<19520000
  • todos los registros de marzo de 1951 - SELECT * FROM table where thedate>=19510300 and thedate<19510400
  • todos los registros del 14 de marzo de 1951 - SELECT * FROM table where thedate=19510314

NOTAS

  • Su GUI necesitaría una GetDateString(int fuzzyDate)que sea bastante fácil de implementar.
  • Ordenar es fácil con el formato int. Debes saber que las fechas desconocidas vendrán primero. Puede revertir esto utilizando 99el 'relleno' en lugar del 00mes o día.

¿Cómo representas la fecha difusa del "invierno de 1941-1942"? Podría ser diciembre de 1941 o enero de 1942.

1
Su pregunta está relacionada con un caso de solución general. La pregunta original no enumera esto como un problema. Según la pregunta publicada, a veces se conoce la fecha completa, a veces solo el año y el mes, y a veces solo el año. No se menciona ningún requisito de un intervalo de fechas difuso como requisito. Estoy de acuerdo en que necesita dos fechas si necesita resolver este problema (aunque, almacenar el rango como dos "entradas de fecha difusa" podría proporcionar más flexibilidad que almacenar dos fechas "difíciles").
Rick

1

ISO 8601 también especifica una sintaxis para "fechas difusas". El 12 de febrero de 2012 a las 3pm sería "2012-02-12T15" y febrero de 2012 podría ser simplemente "2012-02". Esto se extiende muy bien usando la clasificación lexicográfica estándar:

$ (echo "2013-03"; echo "2013-03"; echo "2012-02-12T15"; echo "2012-02"; echo "2011") | sort
2011
2012
2012-02
2012-02-12T15
2013-03

0

Aquí está mi opinión sobre esto:

Ir de la fecha difusa al objeto datetime (que se ajustará a una base de datos)

import datetime
import iso8601

def fuzzy_to_datetime(fuzzy):
    flen = len(fuzzy)
    if flen == 4 and fuzzy.isdigit():
        dt = datetime.datetime(year=int(fuzzy), month=1, day=1, microsecond=111111)

    elif flen == 7:
        y, m = fuzzy.split('-')
        dt = datetime.datetime(year=int(y), month=int(m), day=1, microsecond=222222)

    elif flen == 10:
        y, m, d = fuzzy.split('-')
        dt = datetime.datetime(year=int(y), month=int(m), day=int(d), microsecond=333333)

    elif flen >= 19:
        dt = iso8601.parse_date(fuzzy)

    else:
        raise ValueError("Unable to parse fuzzy date: %s" % fuzzy)

    return dt

Y luego una función que toma el objeto datetime y lo mueve de nuevo a una fecha difusa.

def datetime_to_fuzzy(dt):
    ms = str(dt.microsecond)
    flag1 = ms == '111111'
    flag2 = ms == '222222'
    flag3 = ms == '333333'

    is_first = dt.day == 1
    is_jan1 = dt.month == 1 and is_first

    if flag1 and is_jan1:
        return str(dt.year)

    if flag2 and is_first:
        return dt.strftime("%Y-%m")

    if flag3:
        return dt.strftime("%Y-%m-%d")

    return dt.isoformat()

Y luego una prueba unitaria. ¿Me perdí algún caso?

if __name__ == '__main__':
    assert fuzzy_to_datetime('2001').isoformat() == '2001-01-01T00:00:00.111111'
    assert fuzzy_to_datetime('1981-05').isoformat() == '1981-05-01T00:00:00.222222'
    assert fuzzy_to_datetime('2012-02-04').isoformat() == '2012-02-04T00:00:00.333333'
    assert fuzzy_to_datetime('2010-11-11T03:12:03Z').isoformat() == '2010-11-11T03:12:03+00:00'

    exact = datetime.datetime(year=2001, month=1, day=1, microsecond=231)
    assert datetime_to_fuzzy(exact) == exact.isoformat()

    assert datetime_to_fuzzy(datetime.datetime(year=2001, month=1, day=1, microsecond=111111)) == '2001'
    assert datetime_to_fuzzy(datetime.datetime(year=2001, month=3, day=1, microsecond=222222)) == '2001-03'
    assert datetime_to_fuzzy(datetime.datetime(year=2001, month=6, day=6, microsecond=333333)) == '2001-06-06'

    assert datetime_to_fuzzy(fuzzy_to_datetime('2002')) == '2002'
    assert datetime_to_fuzzy(fuzzy_to_datetime('2002-05')) == '2002-05'
    assert datetime_to_fuzzy(fuzzy_to_datetime('2002-02-13')) == '2002-02-13'
    assert datetime_to_fuzzy(fuzzy_to_datetime('2010-11-11T03:12:03.293856+00:00')) == '2010-11-11T03:12:03.293856+00:00'

Hay un caso de esquina en el que ocurrió un evento que ocurrió con precisión 2001-01-01T00:00:00.333333pero que el sistema interpretará como solo "2001", pero eso parece muy poco probable.


0

Trabajo para una editorial que se ocupa de muchos libros antiguos donde a menudo no podemos obtener las fechas exactas de las cosas. Normalmente tenemos dos campos para una entrada de fecha dada, la fecha y un booleano circa :

date date
dateCirca enum('Y', 'N')

Usamos el campo de fecha para indicar la fecha de algún evento, o una fecha que está "lo suficientemente cerca" en el caso de que no sepamos la fecha verdadera. En el caso de que no sepamos la fecha verdadera, marcamos el dateCircacampo como Yy damos una fecha lo suficientemente cercana, que está marcada como "1ra", como

1st March, 2013  // We don't know the day of the month
1st January, 2013  // We don't know the month/day of the year
1st January, 2000  // We don't know the month/day/year, we only know the century

0

Visión de conjunto

Hay muchas representaciones posibles, y por lo tanto esquemas de bases de datos, para almacenar fechas y horas difusas (o incluso solo fechas difusas):

  1. Fecha-hora y código que indica su precisión o exactitud
  2. Fecha-hora e intervalo donde hay varias posibilidades para representar un intervalo:
    1. Representar todos los intervalos como una cantidad entera (u otra cantidad numérica) de alguna unidad fija, por ejemplo, días, minutos, nanosegundos.
    2. Representa un intervalo como una cantidad entera (u otra cantidad numérica) y un código que indica sus unidades.
  3. Fecha y hora de inicio y finalización
  4. Cuerda
  5. Distribución de probabilidad:
    1. Cantidades decimales o de coma flotante para los parámetros que especifican una distribución específica en una familia particular, por ejemplo, la media y la desviación estándar de una distribución normal.
    2. Función de distribución de probabilidad, por ejemplo, como un código (de búsqueda) (potencialmente con parámetros de valores específicos), o como una expresión en un lenguaje, formato o representación suficientemente expresivo.

[1], [2] y [3] son ​​todos (implícitamente) intervalos uniformes, es decir, un conjunto de puntos (igualmente) posibles en el tiempo.

[4] es el más expresivo, es decir, cuando permite oraciones o frases escritas posibles (o al menos arbitrariamente largas). Pero también es el más difícil de trabajar. En el límite, se requeriría una IA de nivel humano para manejar valores arbitrarios. Prácticamente, el rango de valores posibles necesitaría restringirse severamente, y probablemente se preferirían valores 'estructurados' alternativos para muchas operaciones, por ejemplo, ordenar, buscar.

[5] es probablemente la representación compacta más general que es (algo) práctica.

Intervalos uniformes

Los intervalos uniformes son la forma compacta más simple de representar un conjunto de valores (posibles) de fecha y hora.

Para [1], se ignoran porciones del valor de fecha y hora, es decir, las porciones correspondientes a unidades más finas que la precisión o exactitud indicada; de lo contrario, esto es equivalente a [2] y el código de precisión / exactitud es equivalente a un intervalo con las mismas unidades (y una cantidad implícita de 1).

[2] y [3] son ​​expresamente equivalentes. [1] es estrictamente menos expresivo que cualquiera de los dos, ya que existen intervalos efectivos que no pueden representarse por [1], ej. una fecha y hora difusa equivalente a un intervalo de 12 horas que abarca un límite de fecha.

[1] es más fácil de ingresar para los usuarios que cualquier otra representación y generalmente debería requerir (al menos un poco) menos tipeo. Si se pueden ingresar fechas y horas en varias representaciones de texto, por ejemplo, "2013", "2014-3", "2015-5-2", "30/7/2016 11p", "2016-07-31 18:15" , la precisión o exactitud también podría inferirse automáticamente de la entrada.

La precisión o precisión de [1] también es más fácil de convertir a un formulario para ser transmitido a los usuarios, por ejemplo, '2015-5 con precisión de mes' a "mayo de 2015", frente a "13 de mayo de 2015 2p, más o menos 13.5 días" (aunque tenga en cuenta que este último no puede ser representado por [1] de todos modos).

Instrumentos de cuerda

Prácticamente, los valores de cadena deberán convertirse a otras representaciones para consultar, ordenar o comparar valores múltiples. Entonces, si bien cualquier lenguaje natural (humano) escrito es estrictamente más expresivo que [1], [2], [3] o [5], todavía no tenemos los medios para manejar mucho más allá de las representaciones o formatos de texto estándar. Dado eso, esta es probablemente la representación menos útil por sí misma .

Una ventaja de esta representación es que, en la práctica, los valores deben ser presentables a los usuarios tal cual y no requieren transformación para ser fácilmente comprensibles.

Distribuciones de probabilidad

Las distribuciones de probabilidad generalizan las representaciones de intervalo uniformes [1], [2], [3] y (posiblemente) son equivalentes a la representación de cadena (general) [4].

Una ventaja de las distribuciones de probabilidad sobre las cadenas es que la primera es inequívoca.

[5-1] sería apropiado para valores que (en su mayoría) se ajustan a una distribución existente, por ejemplo, una salida de valor de fecha y hora de un dispositivo para el que se sabe (o se piensa) que las mediciones se ajustan a una distribución específica.

[5-2] es probablemente la mejor forma (algo) práctica de representar de forma compacta los valores arbitrarios de 'fecha y hora difusa'. Por supuesto, la computabilidad de las distribuciones de probabilidad específicas utilizadas es importante y definitivamente hay problemas interesantes (y tal vez imposibles) que se deben resolver al consultar, ordenar o comparar diferentes valores, pero es probable que mucho de esto ya se conozca o se resuelva en algún lugar de los existentes. literatura matemática y estadística, por lo que definitivamente es una representación extremadamente general y poco ambigua.



-2

En su caso solo necesita año, mes y día. Se requieren año y mes, el día es opcional. Yo usaría algo así:

year smallint not null,
month smallint not null,
day smallint

Además, aún puede usar índices de manera muy efectiva. Las (minúsculas = menos, colas se vuelven un poco más "complicadas" (más largas).


1
Pero esto significa que si la confusión también engulle la parte del mes, este enfoque falla.
Anurag Kalia

1
@AnuragKalia: haga que el campo de mes sea anulable. No hay razón para que esto no pueda reconfigurarse en una fecha posterior.
JeffO

Eso fue solo un ejemplo. La solución debe ser lo suficientemente general como para acomodar problemas futuros. Si el rango que especifica es del 15 de marzo de 2013 al 22 de marzo de 2013, este enfoque no funciona. La respuesta min-max anterior es la más general hasta ahora.
Anurag Kalia

1
¿Has encontrado ese requisito en la publicación de OP o es solo tu fantasía?
Danubian Sailor

Hacer que el mes sea anulable le permite especificar un día pero ningún mes. No tiene sentido tampoco. Cuando fue 1978-??-31?
MSalters

-2

Simplemente almacenaría la hora exacta para las fechas normales y haría que la parte de la fecha difusa sea genérica como 00:00:00. Luego haría todas las fechas difusas el 1 de cada mes.

Cuando consulta, usted

  1. verifique los rangos de fechas donde el tiempo también es igual a 00:00:00 (difuso)
  2. verifique los rangos de fechas donde el tiempo NO es igual a 00:00:00 (real)
  3. verifique los rangos de fechas pero ignore la porción de tiempo (combinado)

Hay mejores soluciones que esta, pero personalmente odio los metadatos (datos sobre mis datos). Simplemente tiene la costumbre de salirse de control después de un tiempo.


2
¿Cómo trataría esto con una fecha real teniendo tiempo 00:00:00?
mosquito

Si bien es teóricamente posible agregar una fecha real con ese tiempo, no sucederá. He visto tablas con millones de filas y ninguna de ellas tenía un valor de fecha y hora donde la hora era 00:00:00. El pragmatismo triunfa sobre la convención.
Capitán Kenpachi
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.