Date Duration Calculator Macro Not Working

Can someone help me figure out why this macro isn't working? I think it's somewhere in one of the variables, maybe?


Date Duration Calculator.kmmacros (4.2 KB)
image

I didn't mean to forget the actual Macro.

:slight_smile: but I think you've still only exported one of the actions. (You need to make sure that the selection is a macro rather than just one of its actions, before you export)


The AppleScript date constructor was not designed to recognise and correctly interpret ISO-8601 date strings.

For example, in AppleScript:

date "2023-05-16"

is evaluated (on the system and locale here) to:

date "Saturday, 13 November 2021 at 00:00:00"

One option would be to use an Execute JavaScript for Automation action instead.

In JavaScript,

new Date("2023-05-16")

evaluates correctly.


For a rough example:

Difference between two ISO8601 date strings.kmmacros (2.5 KB)


Expand disclosure triangle to view JS source
(() => {
    "use strict";

    const dayMilliSeconds = 24 * 60 * 60 * 1000;

    const
        kme = Application("Keyboard Maestro Engine"),

        [from, to] = [
            "STARTiso8601",
            "ENDiso8601"
        ]
        .map(s => new Date(kme.getvariable(s)));

    return `${(to - from) / dayMilliSeconds} days`;
})();


You could use the Search using Regular Expression action with regex (\d+)-(\d+)-(\d+) to break the dates in to year,month,day variables, and then the MJD function to turn that in to a number of days, and then subtract the two of them to get the difference in days.

2 Likes

Problems in your macro:

  • Text tokens like %Variable%Start Date% are only expanded in text fields – they can't work in Execute Script actions
  • In AppleScript, an expression like date "2023-05-16" doesn't mean what you hope it does (see my earlier post)
  • The variable names which you are binding in the prompt are srtdate, endate, and don't match the names from which you are apparently trying to obtain values: Start Date, End Date

Using Custom Array Delimiters

( see: manual:Variables [Keyboard Maestro Wiki] )

you can segment the ISO8601 date strings by "-" and pick out their parts with (one-based) index numbers.

The Y, M and D components can be passed to the Keyboard Maestro TIME() function which returns a number of seconds since the start of a fixed epoch.

Then, breaking it down into steps in the hope of legibility, perhaps something like:

Date Duration Calculator (Fixed in steps).kmmacros (7.4 KB)

But you can create a date and then set the year, month and day:

set startDate to (get current date)
set startString to "2024-02-03"
set AppleScript's text item delimiters to "-"
set {year of startDate, month of startDate, day of startDate} to {text item 1 of startString, text item 2 of startString, text item 3 of startString}
return startDate
--> date "Saturday, 3 February 2024 at 15:13:47"

Using that in OP's macro (along with clearing out unnecessary actions and changing variables to be local):

Date Duration Calculator.kmmacros (3.7 KB)

Image

1 Like

and we can dispense with both scripting languages and regular expressions by replacing hyphens with commas:

Date Duration Calculator (replacing hyphens with commas).kmmacros (5.4 KB)

And we can skip the replacing by using a Filter! And Filter the result!

Date Duration Calculator (Filters).kmmacros (4.4 KB)

Image

Definitely retrograde -- I much prefer the readability of your S'n'R version -- but I'm trying to get my head round tokens in Calculations, Filters, etc at the moment. Plus -- funsies!

1 Like

Thanks – good to be reminded of the more map-like potential of filter actions.


Incidentally, on persistent ⇄ local variables, middle ground always seems good, and I notice that in experimenting here, I often wanted to retain (rather than re-type) either the start date or the end date between two successive uses.

Memory of previous values in prompts can be one quite helpful use of persistent variables:

Number of days between two ISO8601 dates.kmmacros (12 KB)

Oh, that's a very nice idea.

Not having messed with prompts much I hadn't really grokked that the default value field is a text field, and can be treated like any other -- I can see %ICUDateTime% and its variants being useful, eg to put in the today's date.

1 Like

Good thought – I've updated the version above to default to today on first use.

1 Like