Due and Repeat
OmniFocus is the premier tool for personal time management. In JavaScript and Omni Automation, date and time intervals are represented through the use of JavaScript date objects. This section of the OmniFocus tutorial will be focused on the use of date objects with tasks.
Specifically, in this section of the OmniFocus tutorial you’ll learn how to:
Create tasks with specific due dates
Create tasks that repeat at specified intervals
Tasks with Due Dates
OmniFocus is designed to provide an organized structure to your schedule. To do so, tasks are often associated with both specific and relative moments in time. This section will examine how to create and apply date/time references to tasks.
To begin, let’s create a new task and store the resulting task object reference in the script variable: task
DO THIS ► | Enter and run the following script to create a new task in the Inbox:
|
A new task titled “Staff Meeting” will be created at the end of the list of tasks in the Inbox.
Next, we’ll set a due date for the created task by assigning a value to the task’s dueDate property. Here is the entry for the dueDate task property from Omni Automation scripting API:
dueDate (Date or null) • If set, the Task should be completed by this date.
Note that the value for the dueDate property can be no date (null) or an instance of the JavaScript Date class. The JavaScript language has built-in methods for creating and manipulating instances of its Date class (date objects).
A date object is generated by using the new date class constructor, which returns an instance of the JavaScript Date class (date object) representing the current time and date:
new Date()
//-->
There are four ways to use the JavaScript date constructor to instantiate a date object:
Create New Date Object
var d = new Date()
var d = new Date(milliseconds)
var d = new Date(dateString)
var d = new Date(year, month, day, hours, minutes, seconds, milliseconds)
For our examples, we’ll use variation 4 with the new Date constructor to generate a JavaScript date object for the 20th of next month at 1:30PM.
Quite often you will generate dates that are in relation to a specific starting date, like today. Therefore, our example script will begin by getting and storing the current date, and then using that information with the new date constructor to create the target date object.
DO THIS ► | Copy, paste, and run the following two-line script: |
Next Month on the 20th at 1:30PM
var d = new Date()
var dateObj = new Date(d.getFullYear(), d.getMonth() + 1, 20, 13, 30)
The resulting date object, which is also stored in the variable dateObj, will be displayed in the console looking something like this:
//-->
With the target data object created and stored, you can now assign it to the previously created task by setting the value of the task’s dueDate property to the stored date object. Remember that the variable task still contains an object reference to the previously created task.
DO THIS ► | Enter and run this script:
|
The “Staff Meeting” task will now have a due date assigned to it:
Repeating Tasks
So you’ve created a new task that is due on the 20th of next month at 1:30PM. But circumstances change and the “Staff Meeting” task needs to be re-scheduled to occur every Tuesday at 10:30AM. Let’s examine how to alter the existing task to become one that repeats.
As with the prior task we’ll need to create a date object that represents next Tuesday. To do this we’ll take advantage of the built-in date parsing abilities of OmniFocus.
In OmniFocus, date input fields accept a value that can written using any syntax supported by an OmniOutliner date field. For example:
- 2d, –3w, 1h, 1y1m, and so on • Relative dates and times put the date at a certain amount of time from right now. Negative numbers represent times in the past.
- 2 days, –3 weeks, 1 hour, 1 year 1 month, and so on • You can use the full names of units too.
- yesterday, tomorrow, tonight, next thursday, last month, this friday, and so on • You can refer to relative dates using common words. “This”, “next”, and “last” have specific meanings: this friday always means the Friday in this week, next friday always means the Friday in the next week, and last friday always means the Friday in last week, regardless of what day today is. Other units work in the same way.
- september, fri, 2019, and so on • If you enter the name of a specific time period, the date will be at its beginning. So september means September first.
- 5/23/08 10a, 9.30.09 2:00 PM, and so on • You can use the short date format as defined in your Language & Region system preferences.
- 2w sat, 4d @ 5p, mon 6a, aug 6 tue 5p, and so on • Mix the available formats however you like.
- now, 9, 14:00, tom, and so on • Omni’s date parser makes its best guess at things like bare numbers, times, and word fragments.
Accordingly, to generate a date object representing next Tuesday at 10:30AM you could simply enter the text string “tuesday @ 10:30AM” (without quotes) into the due date field and OmniFocus would automatically convert it into the appropriate date object for you.
The Omni Automation support in OmniFocus provides access to the built-in Omni date parsing frameworks through the use of Formatter class, essentially enabling you to create date objects without interacting directly with JavaScript date objects — and with no math or calculations are required!
In order to update the due date of the existing task, we’ll need to create and store a new date object representing next Tuesday at 10:30AM. To accomplish this, we’ll create an instance of the Formatter.Date class that we can use to translate the “tuesday @ 10:30AM” text string into a date object.
According to the OmniFocus Omni Automation scripting API, the Formatter.Date class has the following function for generating a formatted date:
withStyle(dateStyle: Formatter.Date.Style, timeStyle: Formatter.Date.Style or null) → (Formatter.Date) • A formatter that will display dates according to the specified date and time formats selected in system settings.
The following script will use the withStyle(…) function of the Formatter.Date class to create a new date formatter instance and then have it translate the provided text string into a date object:
Generate Date from Shorthand String
var formatter = Formatter.Date.withStyle(Formatter.Date.Style.Short)
var dateObj = formatter.dateFromString('tuesday @ 10:30AM')
The result of this script will be a date object referencing the next occurring Tuesday:
//-->
TIP: You can use this short script to generate relative date objects in all of your scripts.
DO THIS ► | Copy and paste the previous short script into the console and run it. |
DO THIS ► | With the date object created, it can be assigned as the value for the task’s dueDate property. Enter and run the following script that set the dueDate property of the fourth task in the Inbox (Reminder: the first item in a JavaScript array has an index of 0):
|
The due date of the “Staff Meeting” task will now be the upcoming Tuesday at 10:30AM.
Now that the due date of the task has been set to the day and time to be used for the repeating event, the task can be set to repeat.
Tasks are set to be repeating by setting the value of the task’s repetitionRule property to a created instance of the Task.RepetitionRule class. Here is the scripting API entery for the repetitionRule property:
repetitionRule (Task.RepetitionRule or null) • If repetition is enabled for the task, the value of this task property is an instance of the Task.RepetitionRule class.
And here is the API entry for constructing an instance of the Task.RepetitionRule class:
new Task.RepetitionRule(ruleString: String, method: Task.RepetitionMethod) → (Task.RepetitionRule) • Returns a new Task.RepetitionRule with the specified ICS rule string and repetition method. The the rule string is not valid, or combination with the method is not supported, an error will be thrown.
As the API entry details, a “rule string” will be needed to indicate the schedule of repetition. A rule string (ICS formatted recurrence string) is a text string written in a specific format detailed on the iCalendar.org website. Fortunately, the RRULE Tool at iCalendar.org, is the simplest and easiest way to derive a correct ICS rule string.
Using the tool, the ICS formatted rule string for a weekly repeating occurence is:
FREQ=WEEKLY;INTERVAL=1
(TIP: Be sure to remove any superfluous punctuation from the end of the rule string, such as a trailing semi-colon.)
The following script creates a new Task.RepetitionRule instance using the ICS rule string and then assigns the created Task.RepetitionRule as the value of the task’s repetitionRule property:
Generating & Assigning a Repetition Rule
var ruleString = "FREQ=WEEKLY;INTERVAL=1"
var repMethod = Task.RepetitionMethod.DueDate
var repRule = new Task.RepetitionRule(ruleString, repMethod)
inbox[3].repetitionRule = repRule
DO THIS ► | Copy, paste, and run the script in the console window. |
The “Staff Meeting” task will now be set to repeat every Tuesday at 10:30AM.
TIP: to make a task non-repeating, set the value of the repetitionRule property to null
Stop Task Repetition
inbox[3].repetitionRule = null
Notifications
With busy schedules, receiving a notification prior to a meeting can be useful. Let’s examine how to assign a notification to the “Staff Meeting” task.
Notification-related properties and functions of the Task class:
notifications (Array of Task.Notification r/o) • An array of the notifications that are active for this task.
addNotification(info: Number or Date) → (Task.Notification) • Add a notification from the specification in info. Supplying a Date creates an absolute notification that will fire at that date. Supplying a Double (number) will create a due-relative notification. Specifying a due relative notification when this task’s effectiveDueDate is not set will result in an error.
removeNotification(notification:Task.Notification) → ( ) • Remove an active notification for this task. Supplying a notification that is not in this task’s notifications array, or a notification that has task to something other than this task results in an error.
These properties and functions are used in conjunction with properties of the Notification class to assign and remove notifications to and from tasks.
The value for a task notification can be either of two types:
- A Date object indicating the exact time and date the notification should occur, or…
- A negative Number indicating the time period (in seconds) prior to the event the notification should occur.
Add Notification to Task
taskNamed("Staff Meeting").addNotification(-3600)
DO THIS ► | Set a notification to the “Staff Meeting” task for an hour before the meeting occurs. Copy, paste, and run the script in the console window. |
A notification will be added to the task.
Summary
In this section you learned:
How to generate JavaScript date objects using the new Date( ) constructor and the Omni Automation date formatters.
How to assign a due date to a task by assigning a date object as the value for the task’s dueDate property.
How to make a task a repeating task by creating a repetition rule object and assign it as the value for the task’s repetitionRule property.
How to add a notification to the repeating task.
In the next section, you will learn how to create and apply tags to tasks.