On Sunday, July 4, 2021 at 1:09:10 PM UTC-7 [email protected] wrote:

> I have a filed that in a tiddler that has a date value, i would like to 
> have button to add one hour to the date value , is this possible ?
>

By "date value", do you actually mean a full "datetime" value, which in TW 
is stored as a 17-digit number (YYYYMMDDhhmmssXXX)?  Assuming that is the 
case, it can be done, but it's not as simple as it may seem.

For instance, if the stored datetime is 20210704133000000 (i.e., 1:30pm on 
July 4, 2021), then it is relatively easy (though not trivial) to add an 
hour, like this:
<$button> add an hour
<$vars
   before={{{ [{!!stored_datetime}split[]first[8]join[]] }}}
   hour={{{ [{!!stored_datetime}split[]rest[8]first[2]join[]] }}}
   after={{{ [{!!stored_datetime}split[]rest[10]join[]] }}}>
<$vars newhour={{{ [<hour>add[1]pad[2]] }}}>
<$action-setfield stored_datetime={{{ 
[<before>addsuffix<newhour>addsuffix<after>] }}} />
</$vars>
</$vars>
</$button>

* First, break the datetime value into parts to isolate the hour number:
** Use split[] to break the datetime value into individual digits, and join 
the first[8] digits to get the date portion.
** Use rest[8] to get the remaining digits and join the first[2] of those 
digits to get the hour number.
** Use rest[10] to get the digits following the hour number, and join those 
to get the minutes, seconds and millisecond portion.
* Next, add 1 to the hour number and apply pad[2] to the result to ensure 
it is 2 digits with a leading 0 if needed.
* Then, reassemble the parts to give the new datetime value and update the 
field value.

However... *this is not sufficient to handle all possible stored_datetime 
values*.

For example, suppose that the stored datetime is 20210704233000000 (i.e., 
11:30pm on July 4, 2021). Simply adding an hour as shown above would give 
20210704243000000. But that is not a valid datetime value, as the hours 
portion must be between 00 and 23.  The correct result would actually be 
20210705003000000 (i.e., 12:30am on July 5, 2021).  Thus, we need to handle 
"hour overflow" to set the hour number to 00 and add 1 to the day number.

But... even that is not enough.  Suppose the stored datetime is 
20210731233000000 (i.e., 11:30pm on July 31, 2021). Then adding 1 hour 
should result in 20210801003000000 (i.e., 12:30am on August 1, 2021). Thus, 
we not only need to handle "hour overflow" as above, but also "date 
overflow" to add 1 to the month number.

Complicating this is that the number of days per month varies, so the "date 
overflow" handling needs to take into account the specified month to know 
how many days it has.  Further complicating this is leap years, in which 
the number of days in February is 29 rather than 28, but only for years 
that are divisible by 4 but not divisible by 100, unless also divisible by 
400.

Lastly, we need also to handle "year overflow". If the stored datetime is 
20211231233000000 (i.e., 11:30pm on December 31, 2021).  Then adding 1 hour 
should result in 20220101003000000 (i.e., 12:30am on January 1, 2022).

Obviously, handling all of these issues requires some complex conditional 
calculations.  Fortunately, *I've already tackled this problem 
in http://tiddlytools.com/timer.html#TiddlyTools%2FTime%2FClocks*.  The 
clock_adjustForTimezone() macro takes the current datetime and adds or 
subtracts a "timezone offset" value to give a new datetime value.  For your 
purposes, rather than using the current datetime, you want to get the 
stored_datetime value, and instead of using a "timezone offset", you want 
to use a specified offset of 1 hour (i.e., "+01:00")

Here's a modified version of clock_adjustForTimezone() that does what you 
need:
\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,
-e

-- 
You received this message because you are subscribed to the Google Groups 
"TiddlyWiki" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/tiddlywiki/4e678e4a-3a94-4597-a347-210bf430d42cn%40googlegroups.com.

Reply via email to