Natural language dates for TextExpander

[Tweet : nvALT]

I had a strong urge to make a new TextExpander snippet this morning. I think the Date Math features of TextExpander that Donald Curtis turned me on to with his Date Time group got me thinking.

I find my OS X Service for natural language date conversion pretty handy. I think TextExpander could make it handier, though, with the form fill feature and a little more flexibility.

I’ve added the new snippet to the Tools group in the TextExpander Project, so TextExpander users can grab the download or self-updating URL and play with it.

Of note

It accepts most basic date language. “today”, “tomorrow”, “3 days”, “2 days ago”, “next tue”, “last fri”, etc.

I added a couple of checks. If you use a plus (+) or minus (-) sign followed immediately by a number and that’s all, it will just add or subtract that many days from the current date. The plus sign is optional, it will work with just “3” to give you the date 3 days from now.

If the words “am”, “pm”, “noon”, “midnight”, “hours” or “minutes” are in your string, it will add the time string to the formatted output.


This one runs on PHP, so it’s ready to use with your built-in tools and has no additional dependencies. There are a few things you can edit (and probably should) once you have it open in TextExpander.

First, set the timezone correctly for your location in the third line. The next line has the primary date format, which defaults to “l, M jS, Y”, like this: Saturday, Oct 15th, 2011. The line after that is the string that’s appended if you use a phrase that triggers a time for the output, defaulting to “ \a\t g:ia” which comes out as “at 3:00pm”.

The $debug parameter can be set to 0, 1 or 2. At zero, if your string fails to translate it will fail silently. At 1, it will return the phrase “Derp” where you meant to paste the date. I figure some feedback is better than none… at 3 it will give you the “Derp” and a Growl notification if you have growlnotify installed.

The code

You can just install this from the project page, but here’s the code if your curious. This looks a little different than what you see in the snippet, I’ll show you why in a second.

#!/usr/bin/env php
$dateformat = "l, M jS, Y";
$timeformat = " \a\\t g:ia";
$debug = 2;

$input="%fill:Date string%";

if ( preg_match( "/^([+-])?(\d+)$/", trim($input), $matches ) )
  $input = $matches[2] . " days";
  if ($matches[1] == "-") $input .= " ago";
else if ( preg_match("/([ap]m|noon|midnight|hours|minutes)/i",trim($input),$matches) )
  $dateformat .= $timeformat;

if (($timestamp = strtotime("$input")) === false)
  if($debug > 1)
    `/usr/local/bin/growlnotify -a TextExpander -t "Natural language FAIL" -m "I can't understand you when you mumble"`;
  if ($debug > 0)
  echo date($dateformat,$timestamp);

Because we’re using the newly-shell-script-friendly Fill feature, normally the entire script would show up in the fill box. That’s ugly. If we add some spacing before and after the Fill placeholder, we can clear most of the excess out. Like so:


				"%fill:Date string%";
				// mon, tue, next fri, tomorrow 3pm...
				// 1, 3, -2 (days), 30 minutes...
				// avoid "on" and "at", keep it simple.

if ( preg_match( "/^([+-])?(\d+)$/", trim($input), $matches ) )

Looks like this now:

Fill dialog cleaned up

Hopefully this will be useful for some of you!