Return completed time Javascript


#1

I have a script running on text expander to pull all my completed tasks for the previous day. I know next to nothing about coding but am decent enough at googling that I was able to put together a mostly working script from pieces of others work. Using;

function lineForTask(task) {
return " ✓ " + task.name() + " " + task.completionDate() + “\n”;

I get the task name and date/time returned like so:

✓ Research Notion-Todo’s for the day Tue Dec 31 2019 20:51:47 GMT-0800 (PST)

My question is - is there a way to just return the time? Or the date+time but without the timezone? On a AppleScript I have ( set completedDate to completion date of currentTask
set completedTime to time string of completedDate)
and this works perfect - but me java dumb and can’t recreate it there.


#2

One approach in JavaScript (not Java, incidentally – that’s a very different language :-) is to do things like this:

(() => {
    'use strict';

    // iso8601Local :: Date -> String
    const iso8601Local = dte =>
        new Date(dte - (6E4 * dte.getTimezoneOffset()))
        .toISOString();
    
    const
        now = new Date(),
        strISO8601 = iso8601Local(now),
        strDate = strISO8601.slice(0, 10),
        strTime = strISO8601.slice(11, 16);
        
    return [strDate, strTime]
})();
// --> ["2020-01-03", "09:16"]

#3

You should also be able to do something like the following:

function lineForTask(task) {
return " ✓ " + task.name() + " " + task.completionDate.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) + “\n”;
}

I am an amateur myself and obviously don’t have the rest of the script to test (though it might be a good one to share–I’d love to see how you’re getting info out of OmniFocus into TextExpander as I haven’t played around with that at all). But give that a try and see if it does what you need?

If it just needs minor tweaking you might be able to get some answers from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString, as that covers all the different formatting options for toLocaleTimeString.


#4
var NoProjectMarker = "No Project";

getTaskSummary();

function getTaskSummary() {
var doc = Application('OmniFocus').defaultDocument;

var thisMorning = startOfDay();
var yesterdayMorning = new Date(new Date().setDate(new Date().getDate() - 1));

 var tasks = doc.flattenedTasks.whose({completionDate: {'>=':yesterdayMorning,'<':thisMorning} })();
if (tasks.length == 0) {
	return "No tasks completed. Do something without writing it down?";
}

// Group tasks by project, then extract progressed projects (projects with
// completed tasks) from allProjects. This gives us the list of projects
// in the same order as OmniFocus’s UI.
var groupedTasks = groupArrayByKey(tasks, function(v) {
	var proj = v.containingProject();
	if (proj) {
		return proj.id();
	}
	return NoProjectMarker;
});

var allProjects = doc.flattenedProjects();
var progressedProjects = allProjects.filter(function(p) {
	return p.id() in groupedTasks;
});

// Build the summary
var summary = progressedProjects.reduce(function(s,p){
	return s + summaryForProject(p);
}, "");

var tasksWithNoProject = groupedTasks[NoProjectMarker];
if (tasksWithNoProject) {
	summary += summaryForTasksWithTitle(tasksWithNoProject, "No Project\n");
}

return summary;

// This needs to be in this scope because it captures groupedTasks
function summaryForProject(p) {
	var projectID = p.id();
	var tasks = groupedTasks[projectID].filter(function(t) {
		return projectID != t.id(); // Don't include the project itself
	});
	return summaryForTasksWithTitle(tasks, projectSummaryLine(p));
}
function summaryForTasksWithTitle(tasks, title) {
	return title + tasks.reduce(summaryForTasks,"") + "\n";
}
}

 // Reducing function to summarize a list of tasks
function summaryForTasks(s,t) {
return s + lineForTask(t);
}

// Create a summary line for a project
function projectSummaryLine(project) {
var tokens = [];
tokens.push(project.name());

var remainingStatus = remainingStatusForProject(project);
if (remainingStatus != "") {
	tokens.push("(" + remainingStatus + ")");
}

return tokens.join(" ") + "\n";
}

// This is appended to the end of a project line
function remainingStatusForProject(project) {
if (!project.completedByChildren()) {
	return "";
}
var remainingCount = project.numberOfTasks() - project.numberOfCompletedTasks();
if (remainingCount == 0) {
	return "complete";
}

return remainingCount + " remaining";
}

function lineForTask(task) {
return " ✓ " + task.name() + " " + task.completionDate() + "\n";
}

// Group an array of items by the key returned by this function
function groupArrayByKey(array,keyForValue) {
var dict = {};
for (var i = 0; i < array.length; i++) {
	var value = array[i];
	var key = keyForValue(value);
	if (!(key in dict)) {
		dict[key] = [];
	}
	dict[key].push(value);
}
return dict;
}

function startOfDay() {
// The day started at midnight this morning
var d = new Date(now.getDate() +1);
d.setHours(4);
d.setMinutes(0);
d.setSeconds(0);
return d;
}

#5

So it had it working more or less, but changing the bottom to being +1 day then hour (4), and up top the crazy 5 nested statements I found to get it to yesterday but couldn’t figure out the last bit of 4am on that yesterday line.