Formatter.Date (Date Formatter)
At some point, your scripts may need to display or request date information to or from a user. Using the properties and functions of the Formatter.Date class you can control the formatting of dates, and can even parse “natural language” date/time descriptors to return new JavaScript date objects.
Class Properties
iso8601 (Formatter.Date) • Return a date formatter that produces ISO–8601 formatted dates, using the Gregorian calendar and the UTC time zone.
Current Date in ISO8601 Format
var fmtr = Formatter.Date.iso8601
fmtr.stringFromDate(new Date())
The resulting ISO8601 Format date string for today is:
Class Functions
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.
withFormat(format: String) → (Formatter.Date) • Returns a formatter with a specific ICU date format and the user’s current locale, calendar, and timeZone. See http://userguide.icu-project.org/formatparse/datetime/ for details on date format strings.
Instance Properties
calendar (Calendar) • The calendar used by the formatter instance.
dateFormat (String r/o) • The date format string used by the formatter instance.
locale (Locale) • The locale used by the formatter instance.
timeZone (TimeZone) • The time zone used by the formater instance.
Instance Functions
stringFromDate(date: Date) → (String) • A function that returns a text string formatted using the formatter’s settings.
dateFromString(string: String) → (Date or null) • A function that returns a date object determined by parsing the provided text string.
Time Format
var fmtr = Formatter.Date.withFormat('h:mm a')
fmtr.stringFromDate(new Date())
//--> 5:19 AM
This example uses the Speech classes to vocalize the current time and date:
Vocalizing the Current Time and Date
dateString = Formatter.Date.withFormat('h:mma, EEEE, LLLL d').stringFromDate(new Date())
//--> "12:07AM, Wednesday, March 2"
utterance = new Speech.Utterance(`It is ${dateString}`)
speakerVoice = Speech.Voice.allVoices.find(voice => voice.name.startsWith("Alex"))
utterance.voice = speakerVoice
new Speech.Synthesizer().speakUtterance(utterance)
Other examples of format strings:
'K:mm a, z' --> "7:48 AM, PDT"
"h 'o''clock' a, zzzz" --> "7 o'clock AM, Pacific Daylight Time"
"yyyy.MM.dd G 'at' HH:mm:ss zzz" --> "2020.08.07 AD at 07:56:23 PDT"
"yyyy/MM/dd '@' HH:mm a" --> "2020/08/07 @ 07:58 AM"
Setting Time Zone for Formatter
var fmtr = Formatter.Date.withFormat("K:mm a, zzzz")
fmtr.timeZone = new TimeZone("EST")
fmtr.stringFromDate(new Date())
//--> "3:15 PM, Eastern Daylight Time"
There are also options for using standard date formatting styles:
Formatter Date Style
var fmtrShortStyle = Formatter.Date.Style.Short
var fmtrLongStyle = Formatter.Date.Style.Long
var fmtr = Formatter.Date.withStyle(fmtrLongStyle,fmtrShortStyle)
fmtr.stringFromDate(new Date())
//--> "August 7, 2021 at 1:42 PM"
Formatter.Date.Style
Full (Formatter.Date.Style r/o) • Use the user’s “full” format as selected in system settings.
Long (Formatter.Date.Style r/o) • Use the user’s “long” format as selected in system settings.
Medium (Formatter.Date.Style r/o) • Use the user’s “medium” format as selected in system settings.
Short (Formatter.Date.Style r/o) • Use the user’s “short” format as selected in system settings.
all (Array of Formatter.Date.Style r/o) • An array of all items of this enumeration. This property is often used when creating action forms.
Here are some of the possible combinations of date/time formatting.
NOTE: including time is optional, and time and date formats are not required to be the same.
Date Formatter Style Options
Formatter.Date.withStyle(Formatter.Date.Style.Full)
//--> Sunday, October 1, 2017
Formatter.Date.withStyle(Formatter.Date.Style.Full, Formatter.Date.Style.Full)
//--> Sunday, October 1, 2017 at 5:21:07 PM Pacific Daylight Time
Formatter.Date.withStyle(Formatter.Date.Style.Long)
//--> October 1, 2017
Formatter.Date.withStyle(Formatter.Date.Style.Long, Formatter.Date.Style.Long)
//--> October 1, 2017 at 5:26:51 PM PDT
Formatter.Date.withStyle(Formatter.Date.Style.Medium)
//--> Oct 1, 2017
Formatter.Date.withStyle(Formatter.Date.Style.Medium, Formatter.Date.Style.Medium)
//--> Oct 1, 2017, 5:29:41 PM
Formatter.Date.withStyle(Formatter.Date.Style.Short)
//--> 10/1/17
Formatter.Date.withStyle(Formatter.Date.Style.Short, Formatter.Date.Style.Short)
//--> 10/1/17, 5:24 PM
Here’s an example plug-in that will place a date/time stamp in the chosen format on the pasteboard.

Put Date/Time Stamp on Clipboard
/*{
"type": "action",
"targets": ["omnifocus","omnigraffle",
"omniplan", "omnioutliner"], "author": "Otto Automator",
"identifier": "com.omni-automation.all.date-time-stamp-on-clipboard",
"version": "1.0",
"description": "Puts the chosen formatted date/time stamp on the pasteboard.",
"label": "Date-Time Stamp",
"shortLabel": "Date-Time Stamp",
"paletteLabel": "Date-Time Stamp",
"image": "cursorarrow.click.badge.clock"
}*/
(() => {
let preferences = new Preferences() // NO ID = PLUG-IN ID
function generateMenuItems(){
let now = new Date()
let fullStyle = Formatter.Date.Style.Full
let longStyle = Formatter.Date.Style.Long
let mediumStyle = Formatter.Date.Style.Medium
let shortStyle = Formatter.Date.Style.Short
// DATE ONLY
let opt0 = Formatter.Date.withStyle(fullStyle).stringFromDate(now)
// "Thursday, June 17, 2021"
let opt1 = Formatter.Date.withStyle(longStyle).stringFromDate(now)
// "June 17, 2021"
let opt2 = Formatter.Date.withStyle(mediumStyle).stringFromDate(now)
// "Jun 17, 2021"
let opt3 = Formatter.Date.withStyle(shortStyle).stringFromDate(now)
// "6/17/21"
// FULL DATE AND VARIOUS TIME
let opt4 = Formatter.Date.withStyle(fullStyle, fullStyle).stringFromDate(now)
// "Thursday, June 17, 2021 at 2:10:50 PM Pacific Daylight Time"
let opt5 = Formatter.Date.withStyle(fullStyle, longStyle).stringFromDate(now)
// "Thursday, June 17, 2021 at 2:10:50 PM PDT"
let opt6 = Formatter.Date.withStyle(fullStyle, mediumStyle).stringFromDate(now)
// "Thursday, June 17, 2021 at 2:10:50 PM"
let opt7 = Formatter.Date.withStyle(fullStyle, shortStyle).stringFromDate(now)
// "Thursday, June 17, 2021 at 2:10 PM"
// LONG DATE AND VARIOUS TIME
let opt8 = Formatter.Date.withStyle(longStyle, fullStyle).stringFromDate(now)
// "June 17, 2021 at 2:24:16 PM Pacific Daylight Time"
let opt9 = Formatter.Date.withStyle(longStyle, longStyle).stringFromDate(now)
// "June 17, 2021 at 2:25:07 PM PDT"
let opt10 = Formatter.Date.withStyle(longStyle, mediumStyle).stringFromDate(now)
// "June 17, 2021 at 2:25:44 PM"
let opt11 = Formatter.Date.withStyle(longStyle, shortStyle).stringFromDate(now)
// "June 17, 2021 at 2:26 PM"
// MEDIUM DATE AND VARIOUS TIME
let opt12 = Formatter.Date.withStyle(mediumStyle, fullStyle).stringFromDate(now)
// "Jun 17, 2021 at 2:10:50 PM Pacific Daylight Time"
let opt13 = Formatter.Date.withStyle(mediumStyle, longStyle).stringFromDate(now)
// "Jun 17, 2021 at 2:10:50 PM PDT"
let opt14 = Formatter.Date.withStyle(mediumStyle, mediumStyle).stringFromDate(now)
// "Jun 17, 2021 at 2:10:50 PM"
let opt15 = Formatter.Date.withStyle(mediumStyle, shortStyle).stringFromDate(now)
// "Jun 17, 2021 at 2:10 PM"
// SHORT DATE AND VARIOUS TIME
let opt16 = Formatter.Date.withStyle(shortStyle, fullStyle).stringFromDate(now)
// "6/17/21, 2:10:50 PM Pacific Daylight Time"
let opt17 = Formatter.Date.withStyle(shortStyle, longStyle).stringFromDate(now)
// "6/17/21, 2:10:50 PM PDT"
let opt18 = Formatter.Date.withStyle(shortStyle, mediumStyle).stringFromDate(now)
// "6/17/21, 2:10:50 PM"
let opt19 = Formatter.Date.withStyle(shortStyle, shortStyle).stringFromDate(now)
// "6/17/21, 2:10 PM"
return [opt0, opt1, opt2, opt3, opt4, opt5, opt6, opt7, opt8, opt9, opt10, opt11, opt12, opt13, opt14, opt15, opt16, opt17, opt18, opt19]
}
const action = new PlugIn.Action(function(selection, sender){
let defaultMenuIndex = 0
let menuIndex = preferences.readNumber("optionsMenuIndex")
if(!menuIndex){
menuIndex = defaultMenuIndex
preferences.write("optionsMenuIndex", defaultMenuIndex)
}
var menuItems = generateMenuItems()
let menuIndexes = menuItems.map((item, index) => index)
let formattedDateOptions = new Form.Field.Option(
"chosenStyle",
"Format",
menuIndexes,
generateMenuItems(),
menuIndex
)
var inputForm = new Form()
inputForm.addField(formattedDateOptions)
var formPrompt = "Choose a style:"
var buttonTitle = "Continue"
var formPromise = inputForm.show(formPrompt,buttonTitle)
formPromise.then(function(formObject){
var index = formObject.values["chosenStyle"]
var chosenStyle = menuItems[index]
preferences.write("optionsMenuIndex", index)
console.log(chosenStyle)
Pasteboard.general.string = chosenStyle
})
});
action.validate = function(selection, sender){
return true
};
return action;
})();
TIP: For speed, in the Automation Configuration dialog assign the plug-in a keyboard shortcut. Then it can be called and completed via two quick keyboard commands!

Shorthand Language
In Omni applications, date entry fields support the entering of shortcut date terminology, such as the words: “today” or “tomorrow” or shorthand values like: “+3d” or “3 days”
The value for a date input field 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.
Using an instance of the shared Formatter.Date class, you can convert those supported shorthand terms into date objects for use in scripts!
For example, the following script shows how to create a date object for three days from today at 9:30AM
Generate Date Object from Shorthand
// in three days at 9:30AM
var fmatr = Formatter.Date.withStyle(Formatter.Date.Style.Short)
var dateObj = fmatr.dateFromString('3d @ 9:30a')
Here's an OmniFocus example where the script locates all tasks whose deferment date/time occurs sometime tomorrow:
All Tasks Whose Deferment Occurs Tomorrow
var fmatr = Formatter.Date.withStyle(Formatter.Date.Style.Short)
var tomorrow = fmatr.dateFromString('tomorrow')
var dayAfterTomorrow = fmatr.dateFromString('2 days')
var deferredTasks = flattenedTasks.filter(task => {
return task.deferDate > tomorrow && task.deferDate < dayAfterTomorrow
})
For more commonly used date comparison functions, see the Date class documentation.
JavaScript Date Format Functions
The JavaScript language has numerous built-in date formatting functions that are demonstrated in the following plug-in that displays the indicated date in a variety of standard formats:

JavaScript Date Format Functions
/*{
"type": "action",
"targets": ["omnifocus","omnigraffle","omniplan","omnioutliner"],
"author": "Otto Automator",
"identifier": "com.omni-automation.all.date-formats-for-date",
"version": "1.0",
"description": "This action will display a dialog containing various formatted date string for the provided date.",
"label": "Date Formats for Date",
"shortLabel": "Date Formats"
}*/
(() => {
var action = new PlugIn.Action(function(selection, sender){
// action code
dateInputField = new Form.Field.Date(
"dateInput",
null,
new Date()
)
inputForm = new Form()
inputForm.addField(dateInputField)
formPrompt = "Enter a date:"
buttonTitle = "Continue"
formPromise = inputForm.show(formPrompt, buttonTitle)
inputForm.validate = function(formObject){
dateInput = formObject.values["dateInput"]
return (!dateInput) ? false : true
}
formPromise.then(function(formObject){
var dateObj = formObject.values["dateInput"]
var dateObjStr = dateObj.toString()
var dateStr = dateObj.toDateString()
var timeStr = dateObj.toTimeString()
var ISOStr = dateObj.toISOString()
var GMTStr = dateObj.toGMTString()
var JSONDate = dateObj.toJSON()
var locString = dateObj.toLocaleString()
var locDateStr = dateObj.toLocaleDateString()
var locTimeStr = dateObj.toLocaleTimeString()
var results = [
"Date:", dateObjStr,
"ISO8601:" , ISOStr,
"GMT:", GMTStr,
"JSON:", JSONDate,
"LOCALIZED:", locString
].join("\n")
console.log(results)
var message = [
dateObjStr,
"\nISO8601:" , ISOStr,
"\nGMT:", GMTStr,
"\nJSON:", JSONDate,
"\nLOCALIZED:", locString
].join("\n")
new Alert("Date Formats", message).show()
})
formPromise.catch(function(error){
console.log("form cancelled", error.message)
})
});
action.validate = function(selection, sender){
// validation code
return true
};
return action;
})();