Just to mention it here, I use Typinator - a lot. Typinator is a text expansion utility. Its similar to TextExpander but as a user of TE for some years I am so very glad I switched to Typinator some years back.

Something that I like to do is track how much time has elapsed since I submitted something. Or, how much of an interval occurred between doing two things. When building a legal case as I am now doing, this comes in handy.

There are several Typinator scripts that come with Typinator. The developer has helped me in customizing some of the scripts as well. They are JavaScripts, I think - I am not a programmer more do I play a programer on TV. :wink:

I mention this here because it has been an important part of what I am now doing in my TaskPaper document. This is what some examples look like:

This is what I use when I want to see events from my calendar on my daily task list:
{Scripts/CalendarEvents_0_Days calendar}
{Scripts/CalendarEvents_1_Days calendar}
{Scripts/CalendarEvents_2_Days calendar}
{Scripts/CalendarEvents_3_Days calendar}

This is what I use when I put in a date to show me how long it has been since an event occurred. It is also something that will work to track how long it is until a deadline:
{Scripts/YearsDaysSinceUntil.scpt yyyy-mm-dd}

This is what I use when I want to track how long it took for a second event to transpire after another event:
{Scripts/DaysBetween.scpt yyyy-mm-dd yyyy-mm-dd}

And of course it all expands and does the calculations when I type a trigger - usually a semi colon and a few easy to remember letters or a word.


I notified the developer of Typinator of this post. He appreciated it but asked me to please clarify that the scripts that I was referencing - while all possible and wonderful, are not normally a part of his distribution. He has helped me quite a bit with his script help. I am happy to share any of the scripts that he has helped me tweak with anyone in this community.

So that we are all crystal clear about what Typinator does, here is an example.
First you place your scripts like the example I am posting below, in the Typinator “Includes” folder. The script title is ”YMDSinceUntil.scpt“

Then, you use the title of one of your scripts in the Typinator expansion.

Here is an example of a script that when you put in a date it will show the year months and days to an event, or after an event. Either way it is using the same date that you would put into the script.

Choose this script:
{Scripts/YMDSinceUntil.scpt yyyy-mm-dd}

Add a value you want to track.
{Scripts/YMDSinceUntil.scpt 2018-11-22}
{Scripts/YMDSinceUntil.scpt 2018-04-15}

Say something about it if you like.
{Scripts/YMDSinceUntil.scpt 2018-11-22} Thanksgiving (11/22/2018).
{Scripts/YMDSinceUntil.scpt 2018-04-15} Tax Filing Deadline (04/15/2018).

The expanded results looks like this
2 months and 12 days until Thanksgiving (11/22/2018).
4 months and 26 days since Tax Filing Deadline (04/15/2018).

The “Includes” script looks like this:

function expand(dateParameter, context, testDate) { // – parameter: yyyy-mm-dd
var refDate = “{{refDate=” + dateParameter + “}}”

var today = new Date()
if (testDate) {
today = new Date(testDate)


var eventDate = new Date(dateParameter)

var startDate = eventDate
var endDate = today
var sinceUntil = " since"
if (eventDate > today) { // future date; swap the dates
var startDate = today
var endDate = eventDate
var sinceUntil = " until"

var mSecPerDay=10006060*24
var diffDays = Math.round((endDate - startDate) / mSecPerDay)

if (diffDays <= 31) {
return refDate + multiple(“day”, diffDays) + sinceUntil

var diffMonths = 1
while (monthsInFuture(startDate, diffMonths) < endDate) {
diffMonths ++

// go back one month, so we have a date in the past
startDate = monthsInFuture(startDate, diffMonths)
diffDays = Math.round((endDate - startDate) / mSecPerDay)

// the calculations can cause subtle errors at the end of months.
// if the remaining days are not more than 3, we omit them
// if the remaining days are 28 or more, we assume that we have another month
if (diffDays <= 3) {
diffDays = 0
} else if (diffDays >= 28) {
diffDays = 0

var diffYears = 0
if (diffMonths >= 12) {
diffYears = Math.floor(diffMonths / 12)
diffMonths = diffMonths % 12

var result = “”

if (diffYears > 0) {
result = result + multiple(“year”, diffYears)

if (diffMonths > 0) {
if (result.length > 0) {
if (diffDays == 0) {
result = result + " and "
} else { // “and” will be inserted before the days
result = result + ", "
result = result + multiple(“month”, diffMonths)

if (diffDays > 0) {
if (result.length > 0) {
result = result + " and "
result = result + multiple(“day”, diffDays)

return “{{refDate=” + dateParameter + “}}” + result + sinceUntil

function multiple(unit, count)
if (count == 1) {
return "1 " + unit
} else {
return count + " " + unit + “s”

function monthsInFuture(date, months)
date = new Date(date.valueOf()) // create a copy of the date
date.setFullYear(date.getFullYear(), date.getMonth() + months)
return date

function testing(fromDate, nDays)
var d = new Date(fromDate)
for (var i=0; i<=nDays; i++) {
var d = new Date(fromDate)
d.setFullYear(d.getFullYear(), d.getMonth(), d.getDate()+i)
console.log(d + " – " + expand(“2016-01-01”, “”, d.valueOf()))
return “”

// testing(“2016-01-20”, 90)

expand(“2016-01-01”) // for testing in Script Editor