5

Working on an application where we would like the user to be able to enter incomplete dates.

In some cases there will only be a year - say 1854, or there might be a year and a month, for example March 1983, or there may be a complete date - 11 June 2001.

We'd like a single 'date' attribute/column - and to be able to sort on date.

Any suggestions?

Blue Waters
  • 725
  • 1
  • 4
  • 17

6 Answers6

8

Store the date as an integer -- yyyymmdd.

You can then zero out any month or day component that has not been entered

Year only: 1954 => 19540000
Year & Month: April 2004 => 20040400
January 1st, 2011 => 20110101

Of course I am assuming that you do not need to store any time of day information.

You could then create a struct to encapsulate this logic with useful properties indicating which level of granularity has been set, the relevant System.DateTime, etc

Edit: sorting should then work nicely as well

cordialgerm
  • 8,403
  • 5
  • 31
  • 47
1

I can't think of a good way of using a single date field.

A problem you would get if you used January as the default month and 1 as the default day like others have suggested is, what happens when they actually pick January? How would you track if it's a selected January or a defaulted January.

I think you're going to have to store a mask along with the date. You would only need a bit per part of the date, which would only be 6 bits of data.

M|D|Y|H|Min|S

Month Only 1|0|0|0|0|0 = 32

Year Only 0|0|1|0|0|0 = 8

Month+Year 1|0|1|0|0|0 = 40

AllButMinSec 1|1|1|1|0|0 = 60

You could put this into a Flag Enum to make it easier to use in code.

jamiegs
  • 1,761
  • 2
  • 15
  • 23
0

Well, you could do it via a single column and field that says 'IsDateComplete'.

If you only have the date field, then you'll need to encode the "incompleteness" in the date format itself, such that if the date is, say, < 1900, it's considered "Incomplete".

Personally, I'd go with an field on the side, that marks it as such. Easier to follow, easier to make decisions on, and allows for any dates.

It goes without saying, perhaps, that you can just create a date from DateTime.MinValue and then set what you "know".

Of course, my approach doesn't allow you to "know" what you don't know. (That is, you don't know that they've set the month). You could perhaps use a date-format specifier to mask that, and store it alongside as well, but it's potentially getting cumbersome.

Anyway, some thoughts for you.

Noon Silk
  • 54,084
  • 6
  • 88
  • 105
0

One option is to use January as the default month, 1 as the default day, and 1900 or something like that as the default year. Incomplete dates would get padded out with those defaults, and incomplete dates would sort before complete ones in the same year.

Another, slightly more complex option is to use -1 for default day and year, and -1, 'NoMonth', or some such as the default month. Pad incomplete dates as above. This may make sorting a little hard depending on how you do it, but it gives you a way of telling which parts of the date are valid.

DGH
  • 11,189
  • 2
  • 23
  • 24
0

I know you'd rather have 1 column but, Instead of a single column one can always have a separate column for day, month and year. Not very difficult to do queries against, and it allways any of the components to be null.

Smehow encoding these states in the datetime itself will be harder to query.

Toad
  • 15,593
  • 16
  • 82
  • 128
0

What I did when last solving this problem, was to create a custom date type that kept track of which date parts was actually set and provided conversions to and from a DateTime. For storing in database i used one date field and then one boolean/bit to keep track of which date components that were actually set by the user.

PHeiberg
  • 29,411
  • 6
  • 59
  • 81