Picking complex dates or times on a website has never been particularly pleasant. Booking flights will normally involve selecting the days you want to depart to (or arrive from) your destination, and will later provide a list of possible flights and times on your selected day(s). Providing your date of birth will generally involve three dropdowns, maybe a calendar if the developers were feeling particularly ambitious.

How would you approach a situation where your users might need to specify a DateTime value down to the minute? What if we want to select an entire month? Or even any time within a particular week?

The jQuery DateTimePicker handles selecting a specific Date/Time value using two separate controls — a calendar for the Date and a list for the Time. The month and year also serve as a dropdown to allow larger movements across time.

This is a situation we found ourselves in recently when working on a project called Spectacle — a web-based tool for visualising geographic data across time. Users can add a collection of datasets, filter them down to what they’re interested in, and change how they’re represented on the map. We can freely pan around the map to understand the spatial nature of our visualisation, but understanding when a particular incident occurred is just as important as where it happened.

In particular, we might want to group certain data in a commonly defined period. “Show me all data points that were recorded in June 2018” or even “Show me how the data looked during the week [important city activity] occurred, and compare it to the previous and following few weeks as well” are really interesting use cases that require a really intuitive UI.

So we re-invented .

Well, not really. Turns out the iOS UIDatePicker shares a lot of similarities with our solution… but we still think we came up with something that was fairly unique and well-suited to our use case.

Final implementation with animations that show the wheels spinning whenever the datetime changes.

Our DateTime picker consists of five wheels — year, month, week/day, hour, and minute. Each wheel “rotates” so that the selected option is always in the centre, which in turn exposes the previous three and following three options. Clicking any visible option will select that option, causing the wheel to spin so that it’s correctly centred. Although we haven’t yet implemented it due to time constraints, using the mouse wheel or quick movements on a touch device would ideally spin the wheel without needing to click anything.

The buttons at the top act not only as a heading for each column, but also as a way to jump between intervals. For example, while Week is selected, selecting the week of July 2nd, 2018 will set the interval to July 2nd, 2018 - July 8th, 2018. If, instead, we want a much more granular view of our data, we can select the Minute interval and specify a five minute period on any day, in any month, in any year, just by spinning each wheel accordingly.

Some whiteboard scribbles that occurred before we settled on the wheels.

A huge advantage to using wheels is that small jumps are easy, but larger jumps are still possible. Jumping forward or backward within three intervals, which is the most likely scenario when inspecting a particular event or timeframe, can be done in a single click. Larger jumps can be made in stages, or (in theory) by using the scroll-wheel or rapidly spinning the wheel on a touch device. The latter option is obviously much more natural, and easier than clicking the same button a bunch of times.

We also love how intuitive it is. While it might seem like a lot on first glance, we’ve found during our limited user testing that — after using it for a couple of minutes — users just get it, especially if the selected date is shown by changes elsewhere in the UI (like the accompanying timeline shown below). Each wheel is still rendered when not in use to maintain a sense of familiarity and to keep the UI from changing dramatically when jumping between different intervals, but each active wheel is still clearly defined and fits together to form the different sections of the whole.

It’s also worth mentioning that because we built this feature in the Elm architecture, the entire component is rendered from a single DateTime value (not including the selected interval) kept on the model. The positions of the wheel are inferred from this value, and simple CSS transitions were used to move the wheels between states. So, whenever the focal DateTime was changed anywhere in the UI, the wheels would spin to reflect that change. Overall, the wheels didn’t actually add that much technical complexity to our app.

If you have any questions about the DateTime picker, or any feedback regarding this write-up, feel free to hit me up on Twitter or check out my portfolio for other stuff I’ve worked on.

Thanks for reading. 👌

Dev, design, and everything in between.