As a historian I am constantly frustrated (but bemused) by how computers record time. They are so idealistically precise and hopelessly presentist in their default settings that creating intellectually honest digital history becomes impossible without some serious modifications.
In designing Project Quincy, my open-source software package for tracing historical networks through time and space, I quickly realized that how I handled dates would make or break my ability to design the kinds of interfaces and visualizations I needed to perform my analysis.
As a database designer, however, I balk at entering improperly formatted data into the database (I am firm in my belief that this will always come back to bite you in the end). So while MySQL lets me enter an unknown birth date as 1761-00-00, because it doesn’t require proper date formatting unless running in “NO_ZERO_DATE mode”, if I ever migrated the data to another database (say Postgres) I would be up to my eyebrows in errors. But I also don’t want to mislead my users into thinking that half the individuals in my database were born on January 1st.
So here are my solutions, drawn from the code of Project Quincy, which powers The Early American Foreign Service Database.
A relatively easy way to format partial dates in your frontend interface is to add 3 boolean flags to each date: year_known, month_known, and date_known. Then add the following method into your application helper (link to code here) to determine how you display each type of partial date.
For entering partial dates Project Quincy makes extensive use of ActiveScaffold, a Rails plugin that auto-generates an administrative backend. The nice thing about ActiveScaffold is that it is fully customizable. The problem with ActiveScaffold is that the defaults stink, so you basically end up customizing everything.
Matt Mitchell, former Head of R&D for the University of Virginia Scholars’ Lab came up with the following elegant solution to my problem:
Create a partial view in /app/views/activescaffold/_common_date_select.html.erb and populate it with the following code.
And activate that partial with a helper method in your application_helper (link here).
And you should be good to go.
If the pastie links go down, you can find the partial view and helper methods on Project Quincy at Github.
2 thoughts on “Partial Dates in Rails with Active Scaffold”
Thanks for writing this. I haven’t gotten a chance to play with the code yet, but I’m glad someone else has been thinking about the mismatch between computers’ demand for precision and the limited information historians have available from our sources.
I’m curious whether you’ve thought about how to represent other forms of uncertainty about dates: conflicts between two sources about the date of an event, uncertain date ranges (“X was probably born in 1863, but possibly as late as 1867”), or conjectures (“Based on the postmark, this was probably written between January 2 and January 4.”)
Since I work on histories of US women, gender, and sexuality, I’m often working with imprecise, limited, or heavily interpreted dates, and I’m frustrated with the amount of technical overhead required to represent dates I know for sure, dates I’ve extrapolated from available evidence, etc. I wish there were more venues for historians to discuss problems like this and document the best solutions we’ve found.
So glad you found the post useful. As you noted I only focused on Partial Dates as opposed to Fuzzy Dates, which are far more complex critters. [Just as a quick recap, partial dates are dates where one or more components of the date is missing while fuzzy dates represent a range of possible values for the date in question.]
TEI has some effective (if IMHO slightly clunky) terminology for defining date ranges, which would take care of most of your problems. If you wanted to use a Third Normal Form Database, I would suggest giving up on MySQL and building your own data type in Postgres, something I may end up doing down the road. Of course, that would break the Railsy convention of database agnosticism . . . but sometimes something has to give.
You can read about creating your own Postgres data type @ http://www.postgresql.org/docs/8.4/static/sql-createtype.html. As a sidebar, the Postgres date type documentation ends with this heart-breakingly hilarious line: “Date conventions before the 19th century make for interesting reading, but are not consistent enough to warrant coding into a date/time handler.”
The bigger question, though, is whether you need your database to perform calculations off fuzzy dates rather than partial dates and if the slight gain in precision is worth the additional effort. In my case, I record fuzzy dates as partial dates with the additional information in a VARCHAR notes field. For my data I haven’t found anything else worth it . . . yet.