Background: https://xkcd.com/1179/
(As used in TaskPaper etc text formats)
Snippets in AppleScript, JavaScript for Automation (JXA) , omniJS:
(the latter two in (Sierra-onwards) ES6 Javascript - for pre-Sierra (ES5) versions, paste into the Babel JS REPL at https://babeljs.io/repl)
Assuming a selected row like:
[details=AppleScript]```AppleScript
on run
tell application “OmniOutliner”
tell first selected row of front document
my iso8601Local(value of cell named "Dates")
end tell
end tell
--> e.g. "2017-08-16 16:15"
end run
– GENERIC FUNCTIONS ---------------------------------------------------------
– curry :: (Script|Handler) -> Script
on curry(f)
script
on |λ|(a)
script
on |λ|(b)
|λ|(a, b) of mReturn(f)
end |λ|
end script
end |λ|
end script
end curry
– intercalate :: Text -> [Text] -> Text
on intercalate(strText, lstText)
set {dlm, my text item delimiters} to {my text item delimiters, strText}
set strJoined to lstText as text
set my text item delimiters to dlm
return strJoined
end intercalate
– iso8601Local :: Date -> String
on iso8601Local(dte)
tell (dte) to set {y, m, d, t} to {its year, its month as integer, its day, its time}
intercalate("-", {y, zeroPad(2, m), zeroPad(2, d)}) & " " & ¬
intercalate(":", map(|λ|(2) of curry(my zeroPad), ¬
{t div 3600, (t mod 3600) div 60}))
end iso8601Local
– map :: (a -> b) -> [a] -> [b]
on map(f, xs)
tell mReturn(f)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, i, xs)
end repeat
return lst
end tell
end map
– Lift 2nd class handler function into 1st class script wrapper
– mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end mReturn
– replicate :: Int -> String -> String
on replicate(n, s)
set out to “”
if n < 1 then return out
set dbl to s
repeat while (n > 1)
if (n mod 2) > 0 then set out to out & dbl
set n to (n div 2)
set dbl to (dbl & dbl)
end repeat
return out & dbl
end replicate
– zeroPad :: Int -> String -> String
on zeroPad(n, e)
set s to e as string
set d to n - (length of s)
if d > 0 then
intercalate("", replicate(d, “0”) & s)
else
s
end if
end zeroPad
[details=JavaScript for Automation (JXA)]```JavaScript
(() => {
'use strict';
// iso8601Local :: Date -> String
const iso8601Local = dte => {
const xs = ['FullYear', 'Month', 'Date',
'Hours', 'Minutes' //, 'Seconds', 'Milliseconds'
]
.map((k, i) => {
const s = (dte['get' + k]() + (i === 1 ? 1 : 0))
.toString();
return (s.length === 1 ? '0' : '') + s;
});
return xs.slice(0, 3)
.join('-') + ((xs[3] !== '00' || xs[4] !== '00') ? (
' ' + xs.slice(3)
.join(':')
) : '');
};
return iso8601Local(
Application('OmniOutliner')
.documents[0].selectedRows[0].cells.byName("Dates")
.value()
);
})();
```[/details]
[details=omniJS]```JavaScript
(() => {
'use strict';
// isoLocal :: Date -> String
const isoLocal = dte => {
const xs = ['FullYear', 'Month', 'Date',
'Hours', 'Minutes' //, 'Seconds', 'Milliseconds'
]
.map((k, i) => {
const s = (dte['get' + k]() + (i === 1 ? 1 : 0))
.toString();
return (s.length === 1 ? '0' : '') + s;
});
return xs.slice(0, 3)
.join('-') + ((xs[3] !== '00' || xs[4] !== '00') ? (
' ' + xs.slice(3)
.join(':')
) : '');
};
return isoLocal(
document.editors[0] // -> Editor
.selectedNodes[0] // -> TreeNode
.object // -> Item (outline row)
.valueForColumn( // -> Date
document.outline // -> Outline
.columns // -> [Column] (array of columns)
.byTitle('Dates') // -> Column
)
);
})();
```[/details]