How to convert epoch timestamp back to TW default format

With the introduction of the new date format

support for Unix epoch timestamps in date format strings

  • We can display dates in this format, perhaps used to set a variable.
  • Once in this format we can add/subtract the correct number of Number of milliseconds to an existing date, including today.

Question

But how to we convert this back to a TiddlyWiki serial date to see the result in formats such as YYYY0MM0DD etc… ?

I suggest adding a new filter operator suffix: format:timestamp[dateformat], which takes an integer value as input, and outputs a date string using TWCore Date format codes.

I do this as part of https://tiddlytools.com/#TiddlyTools%2FTime%2FParseDate using the keyword “unixtime” (equivalent to the new TWCore “TIMESTAMP” keyword)

For example, the following takes the current tiddler’s modified field value (a UTC 17-digit TWCore serial date), and converts it to a unix epoch timestamp integer using {!!modified}parsedate[unixtime]. Then it takes that result and converts it back to a UTC 17-digit TWCore serial date using <epochtime>parsedate:unixtime[]

<$let epochtime={{{ [{!!modified}parsedate[unixtime]] }}}>
<$let coretime={{{ [<epochtime>parsedate:unixtime[]] }}}>
MODIFIED=<$text text={{!!modified}}/><br>
EPOCHTIME=<<epochtime>><br>
CORETIME=<<coretime>>

Note that the default filter parameter for <epochtime>parsedate:unixtime[] is [UTC]YYYY0MM0DD0hh0mm0ss0XXX (i.e., a standard UTC 17-digit TWCore serial date), but you could also specify any valid TWCore Date format codes you want, e.g.:

<$let coretime={{{ [<epochtime>parsedate:unixtime[DDD, MMM DDth YYYY at 0hh12:0mm:0ss]] }}}>

If handling for format:timestamp is added to the TWCore, the syntax equivalent to my custom parsedate filter operator would be something like this:

<$let epochtime={{{ [{!!modified}format:date[TIMESTAMP]] }}}>
<$let coretime={{{ [<epochtime>format:timestamp[DDD, MMM DDth YYYY at 0hh12:0mm:0ss]] }}}>

-e

2 Likes

Here’s some code that implements “format:timestamp[dateformat]” for converting an epoch timestamp value into a TWCore date formatted string.

  • First, it checks the input to make sure it is an integer value. Note that negative integer values are permitted and specify milliseconds BEFORE the beginning of the “Unix Epoch” start date (Jan 1, 1970 00:00:00.000)
  • Then, it applies the filter operand to format the output. If no operand is specified, it defaults to a 17-digit UTC TWCore serial date format ("[UTC]YYYY0MM0DD0hh0mm0ss0XXX").
  • If the input is not a valid signed integer, it returns “Invalid timestamp value”
/*\
title: $:/core/modules/filters/format/timestamp.js
type: application/javascript
module-type: formatfilteroperator
\*/
(function(){

/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";

/*
Export our filter function
*/
exports.timestamp = function(source,operand,options) {
	var results = [];
	source(function(tiddler,title) {
		if (title.match(/^-?\d+$/)) {
			var value = new Date(Number(title));
			results.push($tw.utils.formatDateString(value,operand || "[UTC]YYYY0MM0DD0hh0mm0ss0XXX"));
		} else{ 
			results.push("Invalid timestamp value");
		}
	});
	return results;
};
})();
4 Likes

@EricShulman thanks very much for this;

I have taken your formatfilteroperator timestamp and placed it in a tiddler and imported it into a copy of @pmario’s wiki which has PreSaveActions and it works well displaying the last saved time.

  • I am not sure where I found this published work by @pmario the improvement did not make it into TW 5.2.5

I then created a tiddler tagged $:/tags/SideBarSegment containing
Last Saved <$text text={{{ [{$:/state/saving/timestamp}format:timestamp[DDth MMM YYYY 0hh:0mm:0ss]] }}}/>

  • This displays the last save date in the sidebar
  • It works as advertised, both manual and autosave work
  • I expect now we can explore other advanced uses by combining these, and your “ticker”
    • Allow timeouts since last saved etc…

Questions for @EricShulman

  • Will/have you considered submitting “format:timestamp[dateformat]" and / or parsedate for inclusion in the core? Or at least provide a tiddler on tiddlytools?
  • Can I do anything to support or promote this?
  • Perhaps a UNIX time ticker makes sense as well for a simple greater than test?

Questions for @pmario

  • Thanks Mario PreSaveActions works well, can you point me to where you published it, or a plugin?
    • I cant find where the code is that implements it, such that I can package and install elsewhere.
  • Will/have you considered submitting “PreSaveActions" for inclusion in the core?
    • Or at least provide a Plugin in the wikilabs library
  • Can I do anything to support or promote this?

Thank you Gentlemen in advance.

It’s a GitHub Pull Request Record state saving timestamp by pmario · Pull Request #7131 · Jermolene/TiddlyWiki5 · GitHub It contains a link to “more detailed documentation”, that points to a wiki, which is automatically created for every PR since some weeks now.

This makes it easier for us to let the community test new PRs before they are merged to the main repository.

At the end of every PR there is a message and a link from the “Vercel” robot, that creates the preview.

I have already submitted the code to the GitHub “Issues” as an “IDEA”. You can add a comment there to support/promote this addition to the TWCore.

It’s also already included in https://tiddlytools.com/#TiddlyTools%2FTime%2FParseDate, syntax=unixtime[outputformat] or parsedate:unixtime[outputformat]

I have tried to get htis noticed in GitHub for the next release. It is a gap.

I found https://tiddlytools.com/timer.html##TiddlyTools/Time/ParseDate quite useful.

I use it to auto assign -15min to alarm default time:

(modified Alarm soucecode from TimeTools)

\define alarms_form_time()
<$edit-text
  tag="input"
  class="alarmEdit"
  tiddler=<<alarms_input>>
  field="hour"
  default={{{[<currentTiddler>get[startDate]format:date[TIMESTAMP]subtract[900000]parsedate:number[0hh]]}}}
  placeholder="hh"
/>
<$edit-text
  tag="input"
  class="alarmEdit"
  tiddler=<<alarms_input>>
  field="min"
  default={{{[<currentTiddler>get[startDate]format:date[TIMESTAMP]subtract[900000]parsedate:number[0mm]]}}}
  placeholder="mm"
/>
<$edit-text
  tag="input"
  class="alarmEdit"
  tiddler=<<alarms_input>>
  field="sec"
  default="00"
  placeholder="ss"
/>
\end

Note that this parsedate:number usage is undocumented @EricShulman , I found it in the JS source code.

You should see in the source code:

if (format=="unixtime")    results.push(dt.getTime().toString());
else if (format=="number") results.push(dt.getTime().toString());

Thus, the undocumented:number” filter suffix keyword performs exactly the same action as the documented:unixtime” filter suffix keyword.

While developing the parsetime filter functionality, I took an informal poll (here on TiddlyTalk) to help me decide what the filter suffix keyword should be. Both “unixtime” and “number” got favorable responses, with “unixtime” being preferred and “number” coming in a close second.

As a result, I decided to recognize both keywords for the exact same purpose, so that either keyword could be used, depending upon individual preference.

You should also note that this functionality (converting a “unixtime” value to a TWDate formatted string) has been merged into the TWCore source using the format:timestamp[...] filter operator syntax (see Add the timestamp suffix to the format operator by yaisog · Pull Request #7292 · Jermolene/TiddlyWiki5 · GitHub) , and will be included in the next release (v5.3.0), which is currently scheduled for 26th June 2023 (see Planning for the release of v5.3.0 · Issue #7279 · Jermolene/TiddlyWiki5 · GitHub).