The compare operator should be added to the Mathematics section of the Filter 
Operators <https://tiddlywiki.com/#Filter%20Operators> table, I had no idea 
it existed until I saw Eric's answer above.

On Sunday, July 4, 2021 at 2:57:05 PM UTC-7 Eric Shulman wrote:

> 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 
> <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/125e6acd-f10f-46d4-b155-8044e571eab6n%40googlegroups.com.

Reply via email to