Tuesday, September 27, 2016

Fuzzy Dates

I can remember Fuzzy Logic being quite the thing in the nascent computer based AI projects in the late 70’s and early 80’s. The idea being that you might not have precise values for a given data or that a set of rules might be more or less applicable within a given process – things could be fuzzy but you could still hope to obtain a near optimal output for a given system. If I recall correctly then some of the Expert Systems development work relied upon classes of input that were often akin to broad estimates (at least ranges) rather than precise values.

Anyone who has developed software that deals with scheduling or calendars or some such has run into issues relating to the human cognitive imprecision with dates and times. Often there is an intention to get something done “that evening” or by “Thursday week” and mostly software ends up forcing the user to plump for some measure of precision and carry the fuzziness of that intention in their heads which is suboptimal.

Entering dates to a computer based system has always been a programming challenge. In far off pre-GUI days we built a callable routine for date entry on Vax/VMS that was pretty liberal in what it would accept and attempt to convert into a precise date. Among a number of date formats this also included short-hand like t (today) and t-1 (yesterday) etc.. GUIs have brought us clickable calendar like objects but these can be remarkably clumsy to use and do little to help with the issues around imprecision.

App outputs need to do more to be human sensible. “Tomorrow” or “next week” might communicate a date more effectively to a user than 02/11/2016 (which in any case might be in November or February – you choose). A while back we prototyped some software that converted a date of birth to an age and, within the context of young children, that needed to output values like “3 days old” or “4 weeks” or “9 months” or “4 years” as the date receded into the past and our human expression of age changed accordingly.

The iOS NSDateFormatter has a doesRelativeDateFormatting option that can manage yesterday, today and tomorrow (at least) and Rails has a more extensive distance_of_time_in_words function and I believe that John Resig wrote pretty.js for JavaScript. I do not doubt a great many programmers have knocked up something along these lines over the years. These are all fine but are based upon a specific date or date/time. Being a little less sure about when (“next week” is a nice example) makes things a little more interesting.

The Chrono project in GitHub is a nice introduction to the challenges of parsing a date time string as precise as Sat Aug 17 2013 18:40:39 GMT+0900 or as fuzzy as “last Friday” but that in turn raises the implementation issue of how precisely will a given user supply their date as well as reminding us that in many contexts the time zone might be extremely relevant. There is also some discussion with code samples on StackExchange

Storing an imprecise date or date time is probably best accomplished with a maximum and minimum value. One might consider storing a single value with a precision indicator but I suspect that code would inevitably be required to convert that precision into a range for comparison purposes and so you might as well settle for twin values from get go. There are some interesting StackExchange discussions on this topic as well.

A satisfactory solution on the input side would need to take account of semantics. The shorthand for today plus one week (T+1w perhaps) is not the same as “next week” which is also not the same as “in the next week”. A humanised output is probably simpler but it looks like this would have to be heavily influenced by context so a standardised class might need some alternate output vocabulary options (age and “elapsed time” being two obvious examples).

This is a DRAFT version of a class that will accept a range of strings and convert those in turn into a date range representing a fuzzy date. The class steals happily from some of the sources mentioned above. Input can include things like:

The output of human sensible dates based upon a given DateTime is rather simpler with the details being rather dependent upon the context. In my working examples of “elapsed time” and “age” the output is dependent upon the difference between a given date and the current one. This is normally expressed in the .NET environment as a TimeSpan object. However the TimeSpan class lacks a few features that would make life much simpler when dealing with time spans that represent more than just a few days. I have therefore explored the potential for a custom DateTimeSpan class that could probably be collapsed and simplified into a set of extensions for the .NET supplied standard. So please treat this as another draft idea.

It is very likely that any application with a requirement to process dates in the manner suggested here would need substantial code changes to match the working context. I may well return to this topic to explore the usage of dates stored as a range rather than as a single value.

No comments:

About Me

I am a software developer and consultant with more than a quarter of a century of technology change and challenges to draw experience from. While I maintain and exercise some skills from the dark ages of computing I also enjoy taming the new technologies as they turn up – always looking for ways to deliver truly effective software systems to my customers.