\define adjust_time()
\whitespace trim
<!-- split time into parts -->
<$vars yyyy={{{ [<time>split[]first[4]join[]] }}}>
<$vars mm={{{ [<time>split[]first[6]last[2]join[]] }}}>
<$vars dd={{{ [<time>split[]first[8]last[2]join[]] }}}>
<$vars hh={{{ [<time>split[]first[10]last[2]join[]] }}}>
<$vars min={{{ [<time>split[]first[12]last[2]join[]] }}}>
<$vars ssxxx={{{ [<time>split[]last[5]join[]] }}}>
<!-- apply offset "+hh:mm" or "-hh:mm" -->
<$vars sign={{{ [<offset>split[]first[]] }}}>
<$vars offhh={{{ [<offset>split[]first[3]join[]] }}}>
<$vars offmin={{{ [<offset>split[]last[2]join[]addprefix<sign>] }}}>
<$vars hh={{{ [<hh>add<offhh>] }}}>
<$vars min={{{ [<min>add<offmin>] }}}>
<!-- adjust days per month for leap year -->
<$set name="leap" value={{{ [<yyyy>remainder[4]match[0]then[yes]] }}}>
<$set name="dpm" value="31 28 31 30 31 30 31 31 30 31 30 31"> <!-- days per month -->
<$set name="dpm" filter="[<leap>!match[]]" value="31 29 31 30 31 30 31 31 30 31 30 31" emptyValue=<<dpm>>>
<!-- adjust hours/minutes for minutes wraparound -->
<$set name="hh" filter="[<min>compare:integer:lt[0]]" value={{{ [<hh>subtract[1]] }}} emptyValue=<<hh>>>
<$set name="hh" filter="[<min>compare:integer:gteq[60]]" value={{{ [<hh>add[1]] }}} emptyValue=<<hh>>>
<$set name="min" filter="[<min>compare:integer:lt[0]]" value={{{ [<min>add[60]] }}} emptyValue=<<min>>>
<$set name="min" filter="[<min>compare:integer:gteq[60]]" value={{{ [<min>subtract[60]] }}} emptyValue=<<min>>>
<!-- adjust date/hours for hours wraparound -->
<$set name="dd" filter="[<hh>compare:integer:lt[0]]" value={{{ [<dd>subtract[1]] }}} emptyValue=<<dd>>>
<$set name="dd" filter="[<hh>compare:integer:gteq[24]]" value={{{ [<dd>add[1]] }}} emptyValue=<<dd>>>
<$set name="hh" filter="[<hh>compare:integer:lt[0]]" value={{{ [<hh>add[24]] }}} emptyValue=<<hh>>>
<$set name="hh" filter="[<hh>compare:integer:gteq[24]]" value={{{ [<hh>subtract[24]] }}} emptyValue=<<hh>>>
<!-- adjust month/date for date wraparound -->
<$set name="dm" value={{{ [<dpm>split[ ]nth<mm>] }}}> <!-- days in this month -->
<$set name="mm" filter="[<dd>compare:integer:lteq[0]]" value={{{ [<mm>subtract[1]] }}} emptyValue=<<mm>>>
<$set name="mm" filter="[<dd>compare:integer:gt<dm>]" value={{{ [<mm>add[1]] }}} emptyValue=<<mm>>>
<$set name="dd" filter="[<dd>compare:integer:lteq[0]]" value={{{ [<dpm>split[ ]nth<mm>] }}} emptyValue=<<dd>>>
<$set name="dd" filter="[<dd>compare:integer:gt<dm>]" value={{{ [[1]] }}} emptyValue=<<dd>>>
<!-- adjust year/date/month for month wraparound -->
<$set name="yyyy" filter="[<mm>compare:integer:lteq[0]]" value={{{ [<yyyy>subtract[1]] }}} emptyValue=<<yyyy>>>
<$set name="yyyy" filter="[<mm>compare:integer:gt[12]]" value={{{ [<yyyy>add[1]] }}} emptyValue=<<yyyy>>>
<$set name="dd" filter="[<mm>compare:integer:lteq[0]]" value={{{ [[31]] }}} emptyValue=<<dd>>>
<$set name="dd" filter="[<mm>compare:integer:gt[12]]" value={{{ [[1]] }}} emptyValue=<<dd>>>
<$set name="mm" filter="[<mm>compare:integer:lteq[0]]" value={{{ [[12]] }}} emptyValue=<<mm>>>
<$set name="mm" filter="[<mm>compare:integer:gt[12]]" value={{{ [[1]] }}} emptyValue=<<mm>>>
<!-- zero-pad and assemble new time -->
<$vars mm={{{ [<mm>pad[2]] }}} dd={{{ [<dd>pad[2]] }}} hh={{{ [<hh>pad[2]] }}} min={{{ [<min>pad[2]] }}}>
{{{ [<yyyy>addsuffix<mm>addsuffix<dd>addsuffix<hh>addsuffix<min>addsuffix<ssxxx>] }}}
\end
and here's a button that invokes the above to update the stored_datetime field value:
<$button> add an hour
<$vars time={{!!stored_datetime}} offset="+01:00">
<$wikify name="newtime" text=<<adjust_time>>>
<$action-setfield stored_datetime=<<newtime>> />
</$wikify>
</$vars>
</$button>
enjoy,