Dates are messy. The calendar is weird, for one thing: days of the week don't fall on the same days every year, there are leap years, there used to be the Julian calendar. Then time zones get in the way. Then we have a zillion different ways of writing the same dates and times.
All this is to say, don't expect TiddlyWiki to work miracles here: dates are hard no matter what, and TiddlyWiki doesn't work that hard for us to make them easier. But if you understand a few things, you should be able to avoid getting entirely defeated by dates and times.
Timestamp format
As we learned in Meeting Tiddlers, TiddlyWiki uses an awkward format for dates and times: the four-digit year, the two-digit month, the two-digit day, the two-digit 24-hour hour, the two-digit minute, the two-digit second, and the three-digit milliseconds, all run together, in the UTC timezone (colloquially known as Greenwich Mean Time). So if it's 8:31:41 PM my time on May 30, 2024 right now, Central Daylight Time (UTC-5), the time according to TiddlyWiki is 20240531013141000 (it's on the 31st at 1am because I have to add 5 hours to get to UTC).
This format, sometimes called a timestamp, is used for storing dates in the built-in created
and modified
dates. You should normally use this same format for any date fields that you create, so that you can take advantage of all the other date tools described below.
It's possible to leave some digits of precision off, for instance, the milliseconds. Any missing digits are assumed to be zero (if this produces an invalid date, the result is relatively meaningless but will be an earlier day than the remaining digits would suggest).
Beware of leaving the time off entirely. If you do that, it will be midnight UTC, and if you live in the Western Hemisphere, your timezone has a negative UTC offset. This will cause dates at midnight UTC to roll over to the previous day when converted to your local time (so if you say 20200602
, it will display as June 1, 2020). It's safer to specify a time of 12:00 noon if you don't care about the time – this will always work right almost everywhere in the world (there are a handful of locations around the Pacific that have a +12 or higher offset, so if you live there you might need to bring it back a couple of hours).
Displaying dates
Way back in Meeting Tiddlers, you were given the following mysterious magic snippet to check your work writing a date field:
<$view field="at" format="date" template="DD MMM YYYY hh12:0mm:0ss pm"/>
This ought to be easier to understand now. The $view
widget, as mentioned in Hiding and Showing Things, allows you to look at the contents of fields. It's much like transcluding a field, but it doesn't wikify the contents; instead, it can display them verbatim or apply a variety of other formats. In this case, we've chosen the date
option, one of the widget's most important applications. We additionally have to supply a template
, which is a date format string, consisting of placeholders describing what components of a date should go where. In this case, it shows the day of the month, the month name, the four-digit year, and the hour, minute, and second in 12-hour format, with AM or PM listed at the end. A list of all the placeholders can be found in the Date Format section of the TiddlyWiki documentation.
As another example, let's see on what day the Metadata
tiddler describing the version of this book was last modified, in a long date format typical for the United States:
<$view tiddler="Metadata" field="modified" format="date" template="DDD, MMM DDth, YYYY"/>
Saturday, October 19th, 2024
Getting the current date
As we discussed in Creating Tiddlers With Predefined Fields, it's commonly helpful to retrieve the current date and time in order to prefill a field. This can be done with the now
macro, which accepts any date format string, as described above, as a parameter. For some reason, it does not default to the format string needed to produce the standard internal format, which isn't exactly easy to remember, so I find it helpful to add a function like the following:
\function now-timestamp() [<now [UTC]YYYY0MM0DD0hh0mm0ssXXX>]
<<now-timestamp>>
20241019235630395
(Why use a function rather than a procedure or macro? That's such a good question that I'll leave it as an exercise.)
Calculations with dates
You can use the days
filter operator to find tiddlers that have a date tiddler before or after a particular time relative to the current date. For instance, to find all meetings that have occurred in the last 7 days or have yet to occur, we could say:
<<list-links "[tag[Meeting]days:at[-7]]">>
Unfortunately, the documentation of the days
operator is, as of this writing, almost useless. I have read it dozens of times and am no closer to understanding what it means, and nobody I have talked to has professed to actually understand the operator. A more useful reference I often visit is this forum thread; you might want to bookmark that now.
Plugins
For more complicated needs, a wide variety of plugins and tricks are available, including these:
- Calculating “N days from now”
- Date picker – provides an
$edit-date
widget so you don't have to manually figure out what the appropriate timestamp is for an arbitrary date
Exercises
Make a button labeled Created Now that resets the created
date of the current tiddler to the current time. Place the button on a template, or simply on a test tiddler, and try resetting the created time of the tiddler.
Why did I use a function, rather than a procedure or macro, to define now-timestamp
here? Feel free to play with this live example if that helps.
\function now-timestamp() [<now [UTC]YYYY0MM0DD0hh0mm0ssXXX>]
<<now-timestamp>>
20241019235630397
Hint: What happens if you try to use the value of the <<variable transclusion>>
to set something, as you often will with such a snippet, rather than rendering it within the body of the tiddler?
Create a tiddler called DateFormatter
that allows you to choose any non-system tiddler in the wiki and a field on that tiddler from drop-down menus, then displays the date stored in that field in at least five different formats. The formats displayed should be configurable by creating tiddlers in $:/config/DateFormatter/Formats
.
If the field chosen can't be interpreted as a date, the text (not a date)
should appear where the formatted date otherwise would.
Tip: The fields[]
operator gets the names of the fields present on its input tiddlers.
Here's an example of what it might look like:
go to answer