<< Hardwiring | Main | Dirges for Java >>

Dates and times, and specification examples

chris on 2007-Aug-16 12:33 AM

Scheduling is a big part of our kickass product for nursing homes (coming soon!). Generally there are:

  • appointments (Mrs. Slugworth has a beauty shop appointment on Tuesday at 4:30),
  • recurring appointments (Mr. Dahl has a dialysis treatment every other Wednesday at 1:30),
  • many types of scheduled care (record weight every Sunday at 3:00 and the last Wednesday of every month at 3:00; do not give fluids for eight hours starting at 2 AM on August 13th; offer fluids every two hours between 6 AM and 9 PM from August 2 to September 15; etc.)

One of my fundamendal tenets of software development is that anything dealing with dates and times sucks hard. You have to deal with weird measurements (leap years, inconsistent month lengths), timezones, synchronization, agreement on units of measurement, and it's one of the relatively few areas of ubiquitous low level computing that can be influenced by human politics. Fortunately many other people much smarter than me have come to the same conclusion and have developed libraries and specifications to deal with the suck.

The infantry library for us is Joda Time, which is in my top five open source Java libraries ever. Partially because what it replaces -- the datetime handling in the JDK -- is so awful. But it's also because it's designed by people who have actually used dates and times in the real world, and because it encourages good practices by using immutable objects as the default and making everything threadsafe.

But that only deals with dates and times, not recurrences. The 800-pound gorilla in the recurrence space is RFC 2445, "Internet Calendaring and Scheduling Core Object Specification" or "iCalendar". iCalendar deals with every aspect of scheduling I can think of, and one of the trickiest is recurring schedules. The formal definition for the 'RRULE' (section 4.3.10) is a page and a half, and that doesn't even scratch the surface of what it actually means. The description of each field fills up another two pages: more useful, but still a little abstract for practical use.

For me, the best part comes later, in section 4.8.5.4. It includes six pages of explicit examples, like these three:

   Every 10 days, 5 occurrences:
     DTSTART;TZID=US-Eastern:19970902T090000
     RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5
  
     ==> (1997 9:00 AM EDT)September 2,12,22;October 2,12
  
  
   The first Saturday that follows the first Sunday of the month,
    forever:
  
     DTSTART;TZID=US-Eastern:19970913T090000
     RRULE:FREQ=MONTHLY;BYDAY=SA;BYMONTHDAY=7,8,9,10,11,12,13
    
     ==> (1997 9:00 AM EDT)September 13;October 11
         (1997 9:00 AM EST)November 8;December 13
         (1998 9:00 AM EST)January 10;February 7;March 7
         (1998 9:00 AM EDT)April 11;May 9;June 13...
     ...
   
   
   Every 3 hours from 9:00 AM to 5:00 PM on a specific day:
   
     DTSTART;TZID=US-Eastern:19970902T090000
     RRULE:FREQ=HOURLY;INTERVAL=3;UNTIL=19970902T170000Z
   
     ==> (September 2, 1997 EDT)09:00,12:00,15:00

When writing any type of documentation it's easy to assume your reader consumes what you've written as carefully as you've produced it -- from front to back, paying attention to your highlights and thinking deeply about your assumptions and goals. But IME few people have the inclination or luxury of reading that way -- it's, "How can I do job X?" Examples are the best way to do this; if your library is good enough, they'll get to the other (still important) parts later.

(BTW, the library we're using for recurrences is Google's RFC 2445 implementation. It's okay (it has Joda Time integration!), but IMO needs some usability improvements. When I get a few minutes to breathe this fall I hope to try and contribute...)

Comments

No comments to display.

New comments are disabled.

From The Pragmatic Programmer
Tip 55
Design Using Services
Design in terms of services --- independent, concurrent objects behind well-defined, consistent interfaces.

Archives
4/2008 (2) 3/2008 (2) 2/2008 (4) 1/2008 (3) 12/2007 (2) 11/2007 (8) 10/2007 (3) 9/2007 (2) 8/2007 (8) 7/2007 (5) 6/2007 (19) 5/2007 (4) 4/2007 (2) 2/2007 (4) 1/2007 (4) 12/2006 (8) 11/2006 (7) 10/2006 (11) 9/2006 (6) 8/2006 (2) 7/2006 (3) 6/2006 (14) 5/2006 (1) 4/2006 (5) 3/2006 (12) 2/2006 (14) 1/2006 (18) 12/2005 (12) 11/2005 (10) 10/2005 (9) 9/2005 (3) 8/2005 (6) 7/2005 (18) 6/2005 (12) 4/2005 (6) 3/2005 (21) 2/2005 (13) 1/2005 (12) 12/2004 (14) 11/2004 (23) 10/2004 (23) 9/2004 (22) 8/2004 (7) 7/2004 (12) 6/2004 (23) 5/2004 (29) 4/2004 (24) 3/2004 (34) 2/2004 (21) 1/2004 (31) 12/2003 (16) 11/2003 (37) 10/2003 (32) 9/2003 (24) 8/2003 (21) 7/2003 (29) 6/2003 (27) 5/2003 (27) 4/2003 (26) 3/2003 (41) 2/2003 (29) 1/2003 (38) 12/2002 (46) 11/2002 (41) 10/2002 (45) 9/2002 (99) 8/2002 (111) 7/2002 (7) 6/2002 (19) 5/2002 (18) 4/2002 (7) 3/2002 (8) 2/2002 (22) 1/2002 (13) 12/2001 (4) 11/2001 (5) 10/2001 (5) 9/2001 (6) 8/2001 (6) 7/2001 (5) 6/2001 (5) 5/2001 (4) 4/2001 (4) 3/2001 (3) 2/2001 (6) 1/2001 (3) 12/2000 (1) 11/2000 (2) 10/2000 (7) 9/2000 (7) 8/2000 (6) 7/2000 (13) 6/2000 (6) 5/2000 (2) 4/2000 (3) 3/2000 (8) 2/2000 (4) 1/2000 (4)

All Tags
ada advertising aging aimeeman airlines ajax alcohol animals annoyances ant apache api astronomy attention baby badsoftware barackobama beauty bicycle bicycling birthday biz blog blogging books brain broadband browser build bureaucracy california cars cartoons cats charity chores classifieds clothes clown codegeneration coffee collaboration comics commercials communication community conference config corporate cpan css curmudgeon cwinters.com daily life dancing database datetime dating dc death debate design development distributed diy documentation dormont doublespeak driving dumb ebay ecommerce econ education ejb ella email embedded environment etech exercise expat family farming feed fiber fiction food fun furniture future gambling games geek gentoo geology gis government grammar greece groups gui hair hardware harrypotter hate health hiring history holiday house http ide identity illness imap ipod isp j2me jamming java javascript javaspaces jini job journalism kickass kids kinesis language lazy links linux lisp list lists living mac madison management map marriage maven media medical memory messaging meta military money movies moving ms150 music naked niagara nostalgia nyc oi2 opensource orm outsourcing parenting patent patterns pennsylvania perforce perl personal photography photos pinball pittsburgh planning politics postgres postgresql presentation privacy programming proliant proxy pseudoscience purity quiz quote race radio rant refactoring reflection relationship releases religion rest reunion review ricksantorum rules sandiego scatological science scm scripting security serendipity server servlet sex shell silly slang sleep soa soccer solaris specialization speech sports spring standards starwars steelers struts suburbs swing sysadmin tags team technology telecommuting terrorism testing thnkpad tradition transaction transportation travel traveling tutoring ui unix uptime usability usergroup vacation vc vocollect voice voting vpn walmart washingtondc weather web webservices wedding wiki win32 work writing xml yapc zeroconf