Adjusting Tiddler subtitle timestamps to support internet .beat time

Hello Tiddlyfriends.

I have been looking for a way to store some thoughts and notes for wiki style back linking and organization. TiddlyWiki really hits all the right notes for me and as a novice with java/css/html I feel it’s the right technical level for my desire to customize while still providing practical function.

I am new to the community and have searched on this topic to discover if anyone has solved this previously. I did find some older threads from 2009 referencing incorporating a NewEarthTime clock. The discussion got relatively philosophic and I love it, but I’m having trouble trying to extrapolate what was done here to incorporate into my own Tiddlyverse.

https://www.mail-archive.com/tiddlywiki@googlegroups.com/msg06069.html
http://tw-net-trial.tiddlyspot.com/index.html

My objective is to simply adjust my Tiddler Created/Modified subtitle display times from "16th September HH:MM:SS’ to ‘16th September @XXX.beat.’ The example I fished out above is intended to display the running clock, and I think there must be a simpler solution for static time stamp display. Of course the running clock would be fun too, but I can’t seem to get either working.

I attempted to do this myself with some assistance from the internets and reversing how others have added Java to Tiddlywiki.

Tiddlywiki 5.3.5
TiddlyDesktop for Mac

title: $:/plugins/custom/beat-time
type: application/javascript
tiddlerType: text/vnd.tiddlywiki

(function(){
    function getBeatTime() {
        var now = new Date();
        var totalSeconds = (now.getUTCHours() * 3600) + (now.getUTCMinutes() * 60) + now.getUTCSeconds();
        var bmtSeconds = totalSeconds + (1 * 3600);
        var beats = Math.floor((bmtSeconds % 86400) / 86.4);
        return ("000" + beats).slice(-3); 
    }
    exports.name = "beatTime";  
    exports.params = [];        
    exports.run = function() {  
        return '@' + getBeatTime(); 
    };
})();

I updated $:/language/Tiddler/DateFormat which I think controls the subtitle date formatting.

DDth MMM YYYY at hh12:0mmam <<beatTime>>

The result is my subtitles just now show" 14th September 2024 at 9:41pm << beatTime >>" and not the beat time itself. I don’t see any Javascript errors when viewing the console. I am certain there is more to it that I need to set up to use the as the date-stamp time display.

Would I need to create a custom ViewTemplate and perform HH:MM:SS conversions on all timestamps?

The learning curve is a little steep and I really am enjoying the configurability, I think I just need a little guidance on my implementation of javascript for the plugin.

Thank you kindly for your view and assistance in advance!

Edited to incorporate the concept of Internet .beat Time

What is Internet .beat Time?

Swatch Internet Beat Time, introduced by the Swiss watch company Swatch in 1998, is a unique timekeeping system that divides the day into 1,000 equal parts called “beats.” Each beat lasts 1 minute and 26.4 seconds, replacing the traditional hours and minutes format. This system uses Biel Mean Time (BMT) as its reference, which is based on the time in Biel, Switzerland, where Swatch is headquartered.

Unlike conventional time zones, Internet Beat time operates on a single, universal standard, eliminating the need for time conversions. The time is expressed in a format “@500.beats,” which would indicate 500 beats after midnight BMT.

The primary goal of Swatch Internet Beat is to simplify global communication and coordination. By using a unified time standard, people from different parts of the world can easily synchronize their activities without worrying about time zone differences. Though innovative, this system has remained a niche concept and has not achieved widespread adoption beyond specific communities.

I found personal use with beatTime in recording events for a global audience and community. It has been helpful to adjust my perspective on global coordination and communication styles. It is not without its imperfections.

Welcome @GaryGaryGary to the forums.

I am not exactly sure what this “beat time” is, but I would recommend introducing it in another fieldname, rather than touch this critical field “created” you can always include the new field where needed, even replace created in the tiddler subtitle.

  • You beat time could also access the created or other fields.
  • Also look at the recent format:date[] filter operator.

Have a look at erics timer tools for a lot of date and time tools.

  • To display a clock you will need a continuous interrupt process to refresh the time as it changes, erics tools include this.
  • We now have both UTC / Unix time formats available, but sticking to the tiddlywiki timestamp is important for compatibility issues.

@TW_Tones thank you kindly for the prompt reply. I am not sure how I missed the “It’s All About Time” Titddlywiki, I have some reading to do!

Thank you for the guidance I knew I was approaching this incorrectly trying to modify the language templates to allow a custom time format to be represented globally.

Will read up and ask additional questions if I’m stumped and reply when I find a solution too :slight_smile:

You’re welcome,

Please do present a summary here of the concept behind “beat time” so others can contribute without doing their own research.

Please note that It's About Time! — TiddlyTools: "Small Tools for Big Ideas!" (tm) has not been updated since Sept 28, 2022.

The current versions of all TiddlyTools Time add-ons, including numerous feature enhancements, performance improvements, and bug fixes (gasp!) can be found on my main TiddlyTools.com site.

Please visit TiddlyTools/Time/Info for all documentation and installation instructions.

enjoy,
-e

1 Like

@EricShulman, what an absolutely astonishing set of tiddlywiki tools! Thank you for directing me the right way I am not sure how I missed your comprehensive coverage of all things time. Honored to engage with you in this way.

I’m diving through some of the configurations that you have presented in this guide and while the Time related tools are extensive I can’t find any specific reference to use of Beat time as a time output. I believe I can leverage the ParseDate function to forward the date to a .beat time conversion javascript to render as the desired format of @XXX.beats.

I found a historical example of v.2.5 Tiddlywiki using NET Time, which is similar to Swatch Beat Internet Time. Similar to this NET Time that was demonstrated, Beat Time divides the day into 1000 ‘beats’ starting at UTC+1 for Biel Switzerland.

http://twhelp.tiddlyspot.com/#NETTime

Robert West also achieved display of .beat time in his legacy Tiddlywiki:

https://web.archive.org/web/20160508080031/http://roberttwest.com/personal.html

I’m having difficulty translating what was achieved with this older Tiddlywiki into the version that I am using.

Could I work with you to incorporate Beat time into Tiddlywiki tools for use by others as well?

I have attempted to learn from these examples however I am just very green in the Tiddlywiki space and feel I must be missing something. I will try TW_Tones suggestion of introducing a new field for [beat] to ensure I don’t break other critical fields and functions. Would you believe this to be the best solution to achieve the desired .beat timestamps?

Thank you for the consideration,

Gary

@GaryGaryGary please provide some links to some independent from tiddlywiki resources on what beat time is, and how its used. Unix time is milliseconds from a particular date and I would have thought it enough.

@TW_Tones, certainly! I updated the original post to include a brief description of beat time, however I realize it is not a technical explanation.

https://beats.wiki Is a great resource for some specifics on how beat time can be utilized.

I personally use beat time with a handful of online friends to coordinate game nights across time zones and locales, and I wanted to incorporate this into my tiddlers and tiddlywiki experience.

The history of Swatch Beat Time is a little obscure but fascinating and supported by Nicholas Negroponte who created amongst other things MIT’s Media Lab and Architecture Machine Group. I believe although this time keeping method is obscure, and somewhat commercialized by Swatch, it bears even more significance today with the perpetual state of the ‘always online’ experience.

1 Like

A Vice article describing some of the history behind Beats where Negroponte is specifically quoted.

I personally run this menubar widget for BeatTime as well as beatTime widgets on my mobile devices:

I assume, you want to convert the tiddler “modified” timestamp into <<beattime>> – right?

TW uses a DateFormat configuration in the view-widget to show this info.

The DateFormat does not know anything about beats. We would need to add that format, if we would want a generic solution.

It would also be possible to create a javascript macro similar to your code. – You where close, but not quite right. Your code does create a new Date with the actual time and then converts it to beats.

  • You only forgot to set the field: module-type: macro
  • Save the wik
  • Reload – and your macro should work.

The tiddler to modify the subtitle is: $:/core/ui/ViewTemplate/subtitle/modified – but as I wrote you will need a macro that reads the “modified” or “created” field.

Your code shows the actual time, whenever the macro is rendered. That’s probably not what is intended.

Am I right?

Also internally TW stores the modified and the created date as UTC time. So that needs to be taken into account too.

1 Like

You nailed it. I set the field type to module-type: macro, reloaded, and my <<beatTime>> variable now renders beat time!

You are also absolutely correct in that I’m only part of the way to the solution. My intention is to replace the current 12/24hr timestamp in the subtitle with beat time and not just display the current beat time as the macro is rendered.

Can I create a macro which will simply convert the saved unix time to beat when rendering subtitle created/modified times? I will try approaching it from that angle to see if I can achieve the desired results.

\define unixToBeatTime(unixTime)
<$set name="utcOffset" value={{{ [+3600] }}} /> <!-- UTC+1  -->
<$set name="adjustedTime" value={{{ [<unixTime>add<utcOffset>] }}} />
<$set name="beats" value={{{ [<adjustedTime>divide[86.4]] }}}>
@<$text text={{{ [<beats>floor[]] }}} />
\end

Thank you for your assistance!

Ok, so this may not be THE solution, but it’s A solution that works for me :slight_smile:

I did this with a bit of help from chatGPT.

Setup my beatTime.js to evaluate unix date/timestamps, write some output to console so I can track where it’s going wrong:

(function(){

'use strict';

exports.name = "beatTime";
exports.params = [
    {name: "timestamp"}
];

exports.run = function(timestamp) {
    var ts = String(timestamp).trim();

    console.log("BeatTime Macro Input Timestamp:", ts);

    if (ts.length !== 17) {
        console.log("Invalid timestamp length:", ts.length);
        return "@000 beats";
    }

    // Parse TiddlyWiki timestamp format YYYYMMDDHHMMSSMMM
    var year = parseInt(ts.substr(0, 4), 10);
    var month = parseInt(ts.substr(4, 2), 10) - 1; // Months are zero-based
    var day = parseInt(ts.substr(6, 2), 10);
    var hour = parseInt(ts.substr(8, 2), 10);
    var minute = parseInt(ts.substr(10, 2), 10);
    var second = parseInt(ts.substr(12, 2), 10);
    var millisecond = parseInt(ts.substr(14, 3), 10);

    var date = new Date(Date.UTC(year, month, day, hour, minute, second, millisecond));

    // Check if the date is valid
    if (isNaN(date.getTime())) {
        console.log("Invalid date parsed from timestamp:", ts);
        return "@000 beats";
    }

    console.log("Parsed Date:", date.toUTCString());

    // Convert to Biel Mean Time (UTC+1)
    var bmtTime = date.getTime() + 3600000; // Add 1 hour in milliseconds
    var bmtDate = new Date(bmtTime);

    // Calculate seconds since midnight BMT
    var bmtHours = bmtDate.getUTCHours();
    var bmtMinutes = bmtDate.getUTCMinutes();
    var bmtSeconds = bmtDate.getUTCSeconds();

    console.log("BMT Time:", bmtHours + ":" + bmtMinutes + ":" + bmtSeconds);

    var secondsSinceMidnight = (bmtHours * 3600) + (bmtMinutes * 60) + bmtSeconds;

    // Calculate beats
    var beats = Math.floor(secondsSinceMidnight / 86.4);

    // Ensure beats are within 0-999
    beats = (beats + 1000) % 1000;

    console.log("Calculated Beats:", beats);

    return "@" + ("000" + beats).slice(-3) + ".beats";
};

})();

Using the <$view field> option to identify the modified date, adjust the format to raw, and finally convert the modified time on the current tiddler.

Last modified on: <$view field="modified" format="date"/>
Modified Timestamp: <$view field="modified" format="raw"/>
Internet Beat Timestamp: <$macrocall $name="beatTime" timestamp={{{ [<currentTiddler>get[modified]] }}} />

I then added the one $macrocall for beatTime line for the calculated Beat Time based on Modified timestamp to the $:/core/ui/ViewTemplate/subtitle/modified template

<$view field="modified" format="date" template={{$:/language/Tiddler/DateFormat}}/>
<$macrocall $name="beatTime" timestamp={{{ [<currentTiddler>get[modified]] }}} />

Lastly, I did modify the $:/language/Tiddler/DateFormat template to remove the normal " at hh12:0mmam" from the view. So far, this hasn’t broken anything else catastrophically from what I can tell.

But the end result is the desired outcome! My Tiddlers now display subtitle created/modified timestamps as DD MONTH YYYY @XXX.beats!

22nd September 2024 @952.beats

Thanks for your guidance. I am open to any changes or fixes that may be necessary as my skill level is relatively novice. I do hope that Internet Beat Time may be considered for future enhancement to the Tiddlywiki experience.

-Gary

Very clever thinking.

Note that substr is no longer recommended. I personally would use slice, and skip all the intermediate variables, with something like:

  var date = new Date(Date.UTC(
    ts.slice(0, 4), ts.slice(4, 6), ts.slice(6, 8),                        // Y M D
    ts.slice(8, 10), ts.slice(10, 12), ts.slice(12, 14), ts.slice(14, 17)  // H m s ms
  ))
1 Like

Thank you kindly for the guidance. I have updated my code with the suggestion and the time/date converter is working as expected. Checked against my log entries and all is smooth.

Thank you @Scott_Sauyet !