I changed the input for Local__SourceStr
to %SystemClipboard%
. Yes, thanks very much. I added an execute shell script to start the macro using the bash script to get the calendar list so I can drop Typinator completely from the solution. Set the results to the clipboard of course.
#!/bin/bash
#-- parameter: calendar
/usr/local/bin/icalBuddy -sd -nc -nrd -df " %a, %b %d" -eep "notes" -ic "VA" -ec "Repeating","US Holidays","Graphic","ProjectY", eventsFrom:Today-30 to:Today+365 2>/dev/null
This works great - with one caveat, this blows up midway through the list. I am not sure why yet.
Testing: Works with Feb dates. It blows up with March, April, May dates.
Result: Changing all months to Feb made no difference so - not the months blowing it up. What then?
Here are the last ones that are blowing up and what I mean by blowing up.
Try These:
Tue, Feb 26:
------------------------
• ✅ VA Sleep Adjustment
1:00 PM - 2:00 PM
Fri, Mar 01:
------------------------
• ✅ VA PT
2:00 PM - 3:00 PM
Thu, Mar 07:
------------------------
• ✅ Pendleton VA
1:00 PM - 2:00 PM
Mon, Mar 18:
------------------------
• ✅ VA OT
2:00 PM - 3:00 PM
Mon, Apr 08:
------------------------
• ✅ VA Dr. follow up
2:20 PM - 3:20 PM
These give The Following Result:
08 days until • ✅ VA Sleep Adjustment -Tue, Feb 26
-17
0:-,
1:1,
2:7,
length:3 days until • ✅ VA PT -Fri, Mar 01
-11
0:-,
1:1,
2:1,
length:3 days until • ✅ Pendleton VA -Thu, Mar 07
00 days until • ✅ VA OT -Mon, Mar 18
-10
0:-,
1:1,
2:0,
length:3 days until • ✅ VA Dr. follow up -Mon, Apr 08
ADDED: I realize that in the example I provided, all the dates are going forward from today. But, the script I was showing at the start of the thread is Since/Until because it will differentiate if an event is so many days, weeks months ahead (xx days until) - or, so many days weeks or months behind (xx days since)
This will become very important when tracking a Project on a calendar. By focusing the bash script on just the Project's calendar (Project xyz), then this macro would show me how long it was since I sent in the proposal, had the meeting, did the workshop, etc.. I would also want to know how far ahead is my next milestone, meeting, etc.
In the example that you provided (which I am very grateful for), when I add past dates, it still looks up the past dates as future "until" dates. Of course, it is still blowing up, so, perhaps when this is all sorted out, this part will work too? Thought it was worth mentioning.
Your script Since/Until and the Typinator version of the script since/Until:
Your version of Since/Until in KM script now:
————————————
String.prototype.lpad = function(padString, length) {
var str = this;
while (str.length < length)
str = padString + str;
return str;
}
'use strict';
var app = Application.currentApplication()
app.includeStandardAdditions = true
var kmInst = app.systemAttribute("KMINSTANCE");
var kmeApp = Application("Keyboard Maestro Engine")
var dateSource = kmeApp.getvariable("Local__Date", {instance: kmInst}) || 'Thu, Feb 19';
//--- Get First Capture Group ---
//var dateSource = 'Thu, Feb 19'
var monthDayStr = dateSource.match(/^\w+, (.+)/)[1];
//==>"May 09"
getDateDiff(monthDayStr).toString().lpad('0',2);
//==>"2019-05-09"
function getDateDiff(pMonthDay){
var yearStr = (new Date()).getFullYear().toString();
var dateUnix = Date.parse(pMonthDay + ", " + yearStr);
var oDate = new Date(dateUnix);
var today = new Date()
var dateDiff = oDate.getDate() - today.getDate();
return dateDiff;
}
function getISODate(pMonthDay){
var yearStr = (new Date()).getFullYear().toString();
var dateUnix = Date.parse(pMonthDay + ", " + yearStr);
var oDate = new Date(dateUnix);
var isoDateStr = oDate.getFullYear()
+ '-' + (oDate.getMonth()+1).toString().lpad('0',2)
+ '-' + (oDate.getDate()).toString().lpad('0',2);
return isoDateStr;
}
Version of Since/Until in Typinator script now:
————————————
function expand(dateParameter, context, testDate) { // -- parameter: yyyy-mm-dd
var refDate = "{{refDate=" + dateParameter + "}}"
var today = new Date()
if (testDate) {
today = new Date(testDate)
}
today.setHours(0)
today.setMinutes(0)
today.setSeconds(0)
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=1000*60*60*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
diffMonths--
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) {
diffMonths++
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