Сторона SQL
Моя последняя идея по этому вопросу - использовать диапазон дат, которые являются неопределенными или могут иметь различную специфику. Дано два столбца:
DobFromDate (inclusive)
DobToDate (exclusive)
Вот как это будет работать с вашими сценариями:
Specificity DobFromDate DobToDate
----------- ----------- ----------
YMD 2006-05-05 2006-05-06
YM 2006-05-01 2006-06-01
Y 2006-01-01 2007-01-01
Unknown 0000-01-01 9999-12-31
-> MD, M, D not supported with this scheme
Обратите внимание, что нет причин, по которым это нельзя отнести к часам, минутам, секундам, миллисекундам и т. Д.
Тогда при запросе людей, родившихся в определенный день:
DECLARE @BornOnDay date = '2006-05-16'
-- Include lower specificity:
SELECT *
FROM TheTable
WHERE
DobFromDate <= @BornOnDay
AND @BornOnDay < DobToDate;
-- Exclude lower specificity:
SELECT *
FROM TheTable
WHERE
DobFromDate = @BornOnDay
AND DobToDate = DateAdd(Day, 1, @BornOnDay);
Для меня это лучшее сочетание удобства обслуживания, простоты использования и выразительной силы. Он не справится с потерей точности в более значимых значениях (например, вы знаете месяц и день, но не год), но если это можно обойти, то я думаю, что это победитель.
Если вы когда-нибудь будете делать запросы по дате, то в целом лучшими решениями (на мой взгляд) будут те, которые каким-то образом сохраняют элементы как даты на сервере.
Также обратите внимание, что если вы ищете диапазон дат, а не один день, с моим решением вам по-прежнему нужно только два условия, а не четыре:
DECLARE
@FromBornOnDay date = '2006-05-16',
@ToBornOnDay date = '2006-05-23';
-- Include lower specificity:
SELECT *
FROM TheTable
WHERE
DobFromDate < @ToBornOnDay
AND @FromBornOnDay < DobToDate;
Сторона C #
Я бы использовал пользовательский класс со всеми методами, необходимыми для сопоставления даты и математики. Вы знаете бизнес-требования, касающиеся того, как вы будете использовать неизвестные даты, и можете закодировать логику в классе. Если вам нужно что-то до определенной даты, будете ли вы использовать только известные или неизвестные предметы? Что вернет ToString()
? На мой взгляд, эти вещи лучше всего решать с помощью класса.