Как вы храните «нечеткие даты» в базе данных?

125

Это проблема, с которой я столкнулся несколько раз. Представьте, что у вас есть запись, которую вы хотите сохранить в таблице базы данных. Эта таблица имеет столбец DateTime с именем «date_created». Эта конкретная запись была создана очень давно, и вы не совсем уверены в точной дате, но знаете год и месяц. Другие записи вы знаете только год. Другие записи вы знаете день, месяц и год.

Вы не можете использовать поле DateTime, потому что «май 1978» не является допустимой датой. Если вы разделите его на несколько столбцов, вы потеряете возможность запроса. Кто-нибудь еще сталкивался с этим, если так, как вы справились с этим?

Чтобы прояснить систему, которую я строю, это система, которая отслеживает архивы. Некоторый контент был создан давно, и все, что мы знаем, это «май 1978». Я мог бы хранить его как 1 мая 1978 года, но только с некоторым способом обозначить, что эта дата точна только для месяца. Таким образом, спустя несколько лет, когда я получаю этот архив, меня не смущает, когда даты не совпадают.

Для моих целей важно различать «неизвестный день в мае 1978 года» с «1 мая 1978 года». Кроме того, я не хотел бы хранить неизвестные как 0, как «0 мая 1978 года», потому что большинство систем баз данных отклонят это как недопустимое значение даты.

nbv4
источник
14
Важно ли дифференцировать «неизвестный день в мае 1978 года» с «1 мая 1978 года»?
5
@MichaelT: да, важно различать.
nbv4
6
@aslum: большинство систем баз данных отклонят это как недопустимое значение даты
nbv4
9
@JimmyHoffa - вы никогда не сталкивались с нечетким сценарием дат или с тем, где вам нужно было сравнивать даты? В любом случае, распространенным является история болезни: вы помните, что аппендэктомия была в прошлом году 1 апреля, но тонзилэктомия была где-то в 1975 году, и что-то еще произошло в мае и июне какого-то года. Что если вы хотите знать, было ли какое-либо медицинское событие до или после какого-то другого медицинского прорыва? Произошло ли это до или после того, как они проверяли запасы крови на ВИЧ?
thursdaysgeek

Ответы:

148

Сохраните все даты в обычном поле ДАТА в базе данных и получите дополнительное поле точности, насколько точным является поле ДАТА.

date_created DATE,
date_created_accuracy INTEGER, 

date_created_accuracy: 1 = точная дата, 2 = месяц, 3 = год.

Если ваша дата нечеткая (например, май 1980 г.), сохраните ее в начале периода (например, 1 мая 1980 г.). Или, если ваша дата соответствует году (например, 1980), сохраните ее как 1 января. 1980 с соответствующим значением точности.

Этот способ может легко запросить несколько естественным образом и по-прежнему иметь представление о точных датах. Например, это позволяет запрашивать даты между Jan 1st 1980и Feb 28th 1981и получать нечеткие даты 1980и May 1980.

Юха Сирьяля
источник
1
Вы все еще должны рассчитать дату окончания здесь из того, что я вижу, поэтому я думаю, что между запросами довольно уродливо, поскольку у вас есть вычисляемое поле, которое вы выбираете в лучшем случае.
Уайетт Барнетт
8
Хороший ответ, действительно умный. select * from mytable where date_created between "1980/1/1" and "1981/2/28" and date_created_accuracy <= 2;, Genius.
Нафтули Кей
58
Я бы посоветовал вам считать точность даты просто «днями». Если точный день равен 0. Таким образом, можно использовать более гибкие даты «Иногда летом», имеющие точность дат 90 дней, основанную на 1 июня, а не жестко закодированные конкретные диапазоны дат. Это также может справиться с многолетней точностью.
1
Возможно, вы должны представить это в качестве ответа,
MichaelT
1
+1: Еще одна приятная вещь в этом решении - вы можете добавить логику отображения на основе значения date_created_accuracyполя. Вы можете отобразить «May 1980» или просто «1980» в результатах или пользовательском интерфейсе, если это так точно, как указано в поле.
Kyralessa
27

Если вам не нужно использовать этот тип данных в качестве обычной информации о дате и времени, подойдет любой простой формат строки.

Но если вам нужно сохранить все функциональные возможности, я могу придумать два обходных пути, оба из которых требуют дополнительной информации, хранящейся в базе данных:

  1. Создайте min dateи max dateполя, которые имеют разные значения для «неполных» данных, но будут совпадать для точных дат.
  2. Создайте типы для каждого типа неточной даты (нет _ 0, date_missing _ 1, month_missing _ 2, year_missing_4 и т. Д. _, Чтобы вы могли объединить их). Добавить typeполе в записи и сохранить, какая информация отсутствует.
оборота суперМ
источник
Поля минимальной и максимальной даты были моей первой мыслью.
Майкл Ицоэ
1
Долгое время назад нам пришлось решать точно такую ​​же проблему. Пользователи могли рассказывать истории о событиях, которые произошли в любое время в прошлом, поэтому мы должны были поддерживать нечеткие даты. После долгих перемоток решение, к которому мы пришли, больше всего похоже на предложение superM, где даты хранятся как минимальные и максимальные возможные моменты, которые будут содержать дату истории. При сообщении даты точность (т. Е. «Эта запись является точной по отношению к месяцу / году / дню») может быть извлечена из дельты между минимальной и максимальной датами. Нет необходимости хранить 3-е поле для точности.
meetamit
4
+1 за min dateи max dateполя. Я думаю, что это самое гибкое, но точное и простое в использовании решение.
Supr
1
Сначала я был против этой идеи. Но, понимая, что это самый гибкий подход, я голосую за это.
Анураг Калия
Это только естественно. Вы описываете не столько нечеткое свидание, сколько временные рамки ..... у которых есть начало и конец.
Питер B
20

Это на самом деле скорее определение требований, чем техническая проблема - вам нужно сосредоточиться на том, «как мы можем определить даты в прошлом», и техническое решение будет реализовано.

Времена, когда мне приходилось приближаться к чему-то подобному, обычно:

  • Определите, как отображать вещи - как предлагает MichaelT , решите, что все, что определено как Месяц / День, будет определено как полночь 1-го числа указанного месяца. Как правило, этого достаточно для большинства целей - если бы точная дата была настолько важной, у вас, вероятно, была бы запись об этом через 35 лет, верно?
  • Выясните, нужно ли это отслеживать - IE, нужен ли для записей со слегка вымышленными датами создания такой флаг? Или это просто вопрос обучения пользователей, чтобы люди знали и могли действовать соответственно.

Иногда нужно что-то сделать, например, сделать даты нечеткими - например, одна дата может понадобиться для ответа на запрос чего-либо в мае 1978 года. Это выполнимо - просто сделайте ваши поля create_date 2, старые записи получают 30 дни распределяются по мере необходимости, новые получают 2 одинаковых значения.

Wyatt Barnett
источник
1
+1 - я работал над формулировкой ответа с использованием двойного свидания. Ваш ответ попал сюда первым.
2
+1, это некрасиво и создает много бесполезной дополнительной информации для новых записей, которые не требуют этого, но с другой стороны это делает запросы намного проще, чем они были бы в противном случае. Мы уже некоторое время используем подобное решение для связанной проблемы.
Изката
3
@Izkata - Справедливо, но насколько изящно вы можете получить, когда вам нужно сделать что-то, что должно быть единичным моментом времени в месяце. Конечно, красивее, чем вычислять начало и конец запросов где-то на лету.
Уайетт Барнетт
1
+1 за возможность обозначать произвольную гранулярность без взрыва значений enum.
Дэн Нили,
18

Самый простой способ указать, является ли дата точной, состоит в том, чтобы создать поле точности INT (1) со значением по умолчанию NULL.

Если дата является точной, сохраните дату и время в «date_created» и оставьте точность NULL

Если дата является точной только для месяца, храните дату-время как 1-е число месяца со значением точности 1

Если дата является точной только для года, дата-время магазина 1 января со значением точности 2

Вы можете использовать разные числа для хранения разных значений, таких как первый квартал и т. Д.

оборота Дэвид Страчан
источник
Запросы становятся действительно волосатыми, когда вы делаете это.
Blrfl
3
Это затрудняет работу с данными, которые не находятся на границе чистого месяца, например, «Q2 1991» и «Winter 1978-1979».
1
ОП хочет каким-то образом обозначить, что эта дата точна только для месяца.
Дэвид Страчан
7
Вы злоупотребляете значением NULL здесь. NULL означает «неизвестно», поэтому, если дата является точной, точность не может быть NULL. Это может быть «1».
Конерак
@ Konerak Семантически, да. Но поскольку большинство дат являются точными, необходимо определить только особые случаи и использовать NULL здесь по умолчанию.
Дэвид Страчан
17

В прошлом я хранил точные даты как дату начала и дату окончания. День 21, 2102 будет представлен как начало = 12 часов, может 21,2012 и конец = 12 часов, может быть 22,2012. 2012 год будет представлен как начало = 12 часов утра; январь 1,2012; конец = 12 часов утра; январь 1,2013.

Я не уверен, рекомендую ли я такой подход. При отображении информации пользователю необходимо правильно определить, что диапазон дат точно охватывает день, чтобы показать «25 мая» вместо двух сверхконкретных конечных точек (что означает работу с переходом на летнее время и т. Д.).

Однако, когда вы не пытаетесь перевести на человека, программирование с конечными точками намного проще, чем с точностью + центр. Вы не заканчиваете большим количеством случаев. Это довольно мило.

Крейг Гидни
источник
На самом деле, не нужно быть таким хитрым, чтобы определить, как представить диапазон, если диапазон всегда хранится как UTC. В качестве меток времени UTC каждый день, неделя, месяц, год - даже сезоны и кварталы - будут иметь два постоянных, глобальных, различимых и легко определяемых числа, представляющих начало и конец периода. Логика просто превращается в несколько операторов if, чтобы увидеть, находятся ли две даты в начале и в конце какого-либо периода. Никакой сложной математики или часовых поясов не требуется :)
Supr
@Supr Определение того, находится ли конкретная секунда на границе определенного периода человека, само по себе является трудной проблемой. Особенно в долгосрочной перспективе, когда вращение Земли замедляется и происходят бесконечные небольшие изменения в определении человеком местного времени.
Крейг Гидни
14

Почему бы не хранить две даты.

Created_After и Created_Before. Фактическая семантика, которая «создается в или после» и «создается в или до»

Так что если вы знаете точную дату, то Created_After и Created_Before будут одной и той же датой.

Если вы знаете, что это была первая неделя мая 2000 года, то Created_After = '2000-05-01' и Created_Before = '2000-05-07'.

Если вы просто знаете май 1999 года, тогда значения будут «1999-05-01» и «1999-05-30».

Если это «лето 42 года», то значения будут «1942-06-01» и «1942-08-31».

Эта схема проста для запроса с помощью обычного SQL и довольно проста для пользователя, не являющегося техническим специалистом.

Например, чтобы найти все документы, которые могли быть созданы в мае 2001 года:

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

Наоборот, чтобы найти все документы, которые были определенно созданы в мае 2001 года:

SELECT * FROM DOCTAB WHERE Created_After > '2001-05-01' And Created_Before < 2001-05-31;
Джеймс Андерсон
источник
1
Я думаю, что это самое элегантное решение.
Питер Б
Это то же самое, что ответы SuperM и Strilanc. +1, хотя для того, чтобы объяснить более четко и показать, как просто было бы сделать запрос.
Supr
9

Формат даты и времени ISO 8601 поставляется с определением продолжительности, например

2012-01-01P1M (читай: 2012, 1 января, период: 1 месяц) - это то, что должно быть «в январе 2012».

Я бы использовал это для хранения данных. Для этого вам может потребоваться поле базы данных типа String. Это другая тема, как провести разумный поиск по этому вопросу.

Матиас Ронге
источник
+1 для идеи, но -1 для того, чтобы не использовать поле даты по причине, как искать и / или находить
user151019
Зависит от базы данных. Однако это может быть основой для расширения, но вопрос заключается в следующем: находится ли документ в наборе результатов при поиске, в данном случае, всех документов, более новых, чем 12 января, или нет? Это не тривиально. Здесь вопрос заключался в том, как хранить нечеткие даты.
Матиас Ронге
3

Как правило, я все еще сохраняю их, так как даты общего бизнеса запросов все еще возможны, даже если они немного менее точны.

Если важно знать точность, которую я имел в прошлом, то либо сохранял «окно» точности либо в виде +/- десятичной дроби, либо в виде поиска (день, месяц, год и т. Д.). В других случаях вместо окна я просто сохраняю исходное значение даты в виде строки и преобразую все, что я могу, в datetime, возможно, 1978-05-01 00:00:00 и «май 1978» для вашего данного примера.

Билл
источник
3

Если вы разделите его на несколько столбцов, вы потеряете возможность запроса.

Говорит кто? Вот что вы делаете:

  1. Имеет 3 столбца: День, Месяц, Год, каждый из типа int и четвертый столбец TheDate типа DateTime.
  2. Имейте триггер, который использует 3 столбца День, Месяц, Год, чтобы построить TheDate, если TheDate оставлено нулевым, но одно или несколько полей Day, Month, Year имеют значение.
  3. Имейте триггер, который заполняет поля Day, Month, Year, когда TheDate предоставлен, но эти поля не.

Поэтому, если я сделаю вставку вроде: insert into thistable (Day, Month, Year) values (-1, 2, 2012);тогда TheDate станет 1 февраля 2013 года, но я буду знать, что это действительно неопределенная дата 2 марта 2012 года из-за -1 в поле Day.

Если я insert into thistable (TheDate) values ('2/5/2012');тогда Днем будет 5, Месяцем будет 2, а Годом будет 2012, и поскольку ни один из них не равен -1, я буду знать, что это точная дата.

Я не теряю возможность запроса, потому что триггер вставки / обновления гарантирует, что мои 3 поля (День, Месяц, Год) всегда производят значение DateTime в TheDate, к которому можно обращаться.

мусора
источник
3

Другой вариант - хранить даты как целые числа в форме YYYYMMDD.

  • Вы знаете только, что это 1951 год: Store as 19510000
  • Вы знаете, что месяц и год - март 1951 года. Хранить как 19510300
  • Вы знаете, что полная дата 14 марта 1951 года: Store as 19510314
  • Совершенно неизвестная дата: Хранить как 0

Выгоды

Вы можете хранить нечеткую дату в одном поле вместо двух полей даты или даты и точности, как предполагают многие другие ответы.

Запросы все еще просты:

  • все записи за 1951 год - SELECT * FROM table WHERE thedate>=19510000 and thedate<19520000
  • все записи за март 1951 г. - SELECT * FROM table where thedate>=19510300 and thedate<19510400
  • все записи за 14 марта 1951 г. - SELECT * FROM table where thedate=19510314

ПРИМЕЧАНИЯ

  • Ваш графический интерфейс должен быть GetDateString(int fuzzyDate)довольно простым для реализации.
  • Сортировка легко с форматом INT. Вы должны знать, что неизвестные даты придут первыми. Вы можете изменить это, используя 99вместо «padding» 00месяц или день.
Рик
источник
Как вы представляете нечеткую дату «зима 1941-1942»? Это может быть декабрь 1941 года или январь 1942 года.
1
Ваш вопрос связан с общим решением проблемы. Оригинальный вопрос не перечисляет это как проблему. На основании заданного вопроса иногда известна полная дата, иногда только год и месяц, а иногда только год. Никакая проблема нечеткого диапазона дат не упоминается как требование. Я согласен, что вам нужно две даты, если вам нужно решить эту проблему (хотя сохранение диапазона в виде двух «нечетких целочисленных дат» может обеспечить большую гибкость, чем сохранение двух «жестких» дат).
Рик
1

ISO 8601 также определяет синтаксис для «нечетких дат». 12 февраля 2012 года в 3 часа дня будет «2012-02-12T15», а февраля 2012 года может быть просто «2012-02». Это расширяется, используя стандартную лексикографическую сортировку:

$ (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

Вот мой взгляд на это:

Переход от нечеткой даты к объекту даты и времени (который будет помещаться в базу данных)

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

И затем функция, которая берет объект datetime и перемещает его обратно в нечеткую дату.

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()

А потом юнит тест. Я пропустил какие-либо дела?

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'

Существует угловой случай, когда событие, которое точно произошло, 2001-01-01T00:00:00.333333но система будет интерпретироваться как «только 2001 год», но это кажется маловероятным.

nbv4
источник
0

Я работаю в издательской компании, которая занимается множеством старых книг, где мы часто не можем получить точные даты вещей. У нас обычно есть два поля для данной записи даты, дата и около логического:

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

Мы используем поле даты, чтобы указать дату какого-либо события или дату, которая является «достаточно близкой» в случае, когда мы не знаем истинную дату. В случае, если мы не знаем истинную дату, мы помечаем dateCircaполе как Yи назначаем достаточно близкую дату, которая помечена как «1-я», например

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
user7007
источник
0

обзор

Существует много возможных представлений и, следовательно, схем баз данных для хранения нечетких дат (или даже просто нечетких дат):

  1. Дата-время и код, указывающий его точность или достоверность
  2. Дата-время и интервал, где есть несколько возможностей для представления интервала:
    1. Представьте все интервалы в виде целого (или другого числового) количества некоторой фиксированной единицы, например, дней, минут, наносекунд.
    2. Представьте интервал как целое (или другое числовое) количество и код, указывающий его единицы.
  3. Время начала и окончания
  4. строка
  5. Распределение вероятностей:
    1. Десятичные числа или числа с плавающей запятой для параметров, которые определяют конкретное распределение в определенном семействе, например, среднее значение и стандартное отклонение нормального распределения.
    2. Функция распределения вероятностей, например, в виде (поискового) кода (потенциально с параметрами конкретных значений) или в виде выражения на достаточно выразительном языке, формате или представлении.

[1], [2] и [3] - все (неявно) однородные интервалы, то есть набор (одинаково) возможных моментов времени.

[4] является наиболее выразительным, т. Е. Когда допускаются любые возможные (или, по крайней мере, произвольно длинные) письменные предложения или фразы на языке. Но с этим труднее всего работать. В пределе ИИ на уровне человека должен был бы обрабатывать произвольные значения. Практически, диапазон возможных значений должен быть строго ограничен, и альтернативные «структурированные» значения, вероятно, предпочтительнее для многих операций, например, сортировки, поиска.

[5], вероятно, является наиболее общим компактным представлением, которое (несколько) практично.

Единые интервалы

Унифицированные интервалы - это самый простой и компактный способ представления набора (возможных) значений даты и времени.

Для [1] части значения даты и времени игнорируются, то есть части, соответствующие единицам, более точным, чем указанная точность или точность; в противном случае это эквивалентно [2], а код точности / точности эквивалентен интервалу с теми же единицами (и подразумеваемой величиной 1).

[2] и [3] выразительно эквивалентны. [1] строго менее выразителен, чем любой, поскольку существуют эффективные интервалы, которые не могут быть представлены [1], напр. нечеткая дата-время, эквивалентная 12-часовому интервалу, который охватывает границу даты.

[1] проще для пользователей, чем любое другое представление, и, как правило, требует (хотя бы немного) меньшего ввода текста. Если даты и время можно вводить в различных текстовых представлениях, например, «2013», «2014-3», «2015-5-2», «30.07.2016, 11p», «2016-07-31 18:15» Точность или точность также может быть выведена автоматически из входных данных.

Точность или точность [1] также проще всего преобразовать в форму, которая будет передаваться пользователям, например, «2015-5 с точностью до месяца» в «май 2015», по сравнению с «13 мая 2015, 2р, плюс или минус 13,5 дней» (обратите внимание, что последний в любом случае не может быть представлен [1]).

Струны

Практически, строковые значения необходимо преобразовывать в другие представления для запроса, сортировки или иного сравнения нескольких значений. Таким образом, хотя любой письменный естественный (человеческий) язык строго более выразителен, чем [1], [2], [3] или [5], у нас пока нет средств для обработки чего-то большего, чем стандартные текстовые представления или форматы. Учитывая это, это, вероятно, наименее полезное представление само по себе .

Одним из преимуществ этого представления является то, что на практике значения должны быть презентабельными для пользователей как есть и не требовать преобразования, чтобы их было легко понять.

Распределение вероятностей

Распределения вероятностей обобщают представления равномерных интервалов [1], [2], [3] и (возможно) эквивалентны (общему) строковому представлению [4].

Одним из преимуществ распределения вероятностей над строками является то, что первое является однозначным.

[5-1] будет подходить для значений, которые (в основном) соответствуют существующему распределению, например, значение даты-времени, выводимое из устройства, для которого известно (или считается), что измерения соответствуют определенному распределению.

[5-2], вероятно, является лучшим (несколько) практичным способом компактного представления произвольных значений «нечеткой даты-времени». Конечно, вычислимость конкретных распределений вероятностей имела значение, и существуют определенные интересные (и, возможно, невозможные) проблемы, которые необходимо решить при запросе, сортировке или сравнении различных значений, но многое из этого, вероятно, уже известно или решено где-то в существующих математическая и статистическая литература, так что это определенно предельно общее и однозначное представление.

Кенни Эвитт
источник
-1

Мне очень нравится решение Джеймса Андерсона - точное определение даты - это способ получить наиболее гибкую структуру запроса. Другим способом достижения того же является использование начала, конца или даже центра dateплюс плюс interval(доступно по крайней мере в PostgreSQL , Oracle и SQLAlchemy ).

оборота l0b0
источник
-2

В вашем случае вам нужен только год, месяц и день. Требуется год и месяц, день необязательный. Я бы использовал что-то вроде этого:

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

Кроме того, вы все еще можете очень эффективно использовать индексы. (Крошечный = минус, очереди становятся немного более «сложными» (более длинными).

Дунайский моряк
источник
1
Но это означает, что если нечеткость также поглощает месячную часть, такой подход не работает.
Анураг Калия
1
@AnuragKalia - так сделайте поле месяца обнуляемым. Нет причин, чтобы это не могло быть перенастроено на более поздний срок.
JeffO
Это был просто пример. Решение должно быть достаточно общим, чтобы учесть будущие проблемы. Если указанный диапазон - с 15 марта 2013 г. по 22 марта 2013 г., этот подход не работает. Мин-макс ответ выше является наиболее общим из всех.
Анураг Калия
1
Вы нашли такое требование в постах ОП или это просто ваша фантазия?
Дунайский моряк
Если сделать месяц обнуляемым, можно указать день, но не месяц. Также не имеет смысла. Когда был 1978-??-31?
MSalters
-2

Я просто сохраню точное время для обычных дат и сделаю часть времени нечеткой даты общей, например, 00:00:00. Затем я бы сделал все нечеткие даты 1-го числа месяца.

Когда вы запрашиваете, вы

  1. проверить диапазоны дат, где время также равно 00:00:00 (нечетко)
  2. проверить диапазоны дат, где время НЕ равно 00:00:00 (реальное)
  3. проверять диапазоны дат, но игнорировать временную часть (вместе)

Есть лучшие решения, чем это, но я лично ненавижу метаданные (данные о моих данных). У него просто есть привычка выходить из-под контроля через некоторое время.

Капитан кенпачи
источник
2
как бы это иметь дело с реальной датой, имеющей время 00:00:00?
комнат
Хотя теоретически можно добавить реальную дату с этим временем, этого не произойдет. Я видел таблицы с миллионами строк, и ни одна из них не имела значения datetime, где время было 00:00:00. Прагматизм превосходит конвенцию.
Капитан Кенпачи