Add support for working with negative dates

See discussion https://groups.google.com/g/tiddlywiki/c/aHlyaHr93Io/m/vGcDa6lxAgAJ
This commit is contained in:
jeremy@jermolene.com 2020-12-01 10:39:27 +00:00
parent dde4182830
commit 6a91dbfe2f
5 changed files with 41 additions and 80 deletions

View File

@ -305,7 +305,12 @@ $tw.utils.stringifyDate = function(value) {
// Parse a date from a UTC YYYYMMDDHHMMSSmmm format string
$tw.utils.parseDate = function(value) {
if(typeof value === "string") {
var year = parseInt(value.substr(0,4),10),
var negative = 1;
if(value.charAt(0) === "-") {
negative = -1;
value = value.substr(1);
}
var year = parseInt(value.substr(0,4),10) * negative,
d = new Date(Date.UTC(year,
parseInt(value.substr(4,2),10)-1,
parseInt(value.substr(6,2),10),

View File

@ -302,7 +302,7 @@ exports.formatDateString = function(date,template) {
return $tw.utils.pad($tw.utils.getHours12(date));
}],
[/^wYYYY/, function() {
return $tw.utils.getYearForWeekNo(date);
return $tw.utils.pad($tw.utils.getYearForWeekNo(date),4);
}],
[/^hh12/, function() {
return $tw.utils.getHours12(date);
@ -311,7 +311,14 @@ exports.formatDateString = function(date,template) {
return date.getDate() + $tw.utils.getDaySuffix(date);
}],
[/^YYYY/, function() {
return date.getFullYear();
return $tw.utils.pad(date.getFullYear(),4);
}],
[/^aYYYY/, function() {
return $tw.utils.pad(Math.abs(date.getFullYear()),4);
}],
[/^\{era:([^,\|}]*)\|([^}\|]*)\|([^}]*)\}/, function(match) {
var year = date.getFullYear();
return year === 0 ? match[2] : (year < 0 ? match[1] : match[3]);
}],
[/^0hh/, function() {
return $tw.utils.pad(date.getHours());
@ -400,7 +407,7 @@ exports.formatDateString = function(date,template) {
$tw.utils.each(matches, function(m) {
var match = m[0].exec(t);
if(match) {
matchString = m[1].call();
matchString = m[1].call(null,match);
t = t.substr(match[0].length);
return false;
}

View File

@ -25,6 +25,16 @@ describe("Utility tests", function() {
expect(psa(" [[Tidd\u00a0ler8]] two ")).toEqual(["Tidd\u00a0ler8","two"]);
});
it("should handle parsing a date", function() {
var pd = function(v) {
return $tw.utils.parseDate(v).toString();
};
expect(pd("20150428204930183")).toEqual("Tue Apr 28 2015 21:49:30 GMT+0100 (British Summer Time)");
expect(pd("-20150428204930183")).toEqual("Sun Apr 28 -2015 20:48:15 GMT-0001 (British Summer Time)");
expect(pd("00730428204930183")).toEqual("Fri Apr 28 0073 20:48:15 GMT-0001 (British Summer Time)");
expect(pd("-00730428204930183")).toEqual("Thu Apr 28 -0073 20:48:15 GMT-0001 (British Summer Time)");
});
it("should handle base64 encoding emojis", function() {
var booksEmoji = "📚";
expect(booksEmoji).toBe(booksEmoji);
@ -62,6 +72,8 @@ describe("Utility tests", function() {
var fds = $tw.utils.formatDateString,
// nov is month: 10!
d = new Date(2014,10,9,17,41,28,542);
expect(fds(d,"{era:bce||ce}")).toBe("ce");
expect(fds(d,"YYYY")).toBe("2014");
expect(fds(d,"DDD DD MMM YYYY")).toBe("Sunday 9 November 2014");
expect(fds(d,"ddd hh mm ssss")).toBe("Sun 17 41 2828");
expect(fds(d,"MM0DD")).toBe("1109");
@ -92,6 +104,19 @@ describe("Utility tests", function() {
d = new Date(2014,11,29,23,59,59);
expect(fds(d,"WW")).toBe("1");
expect(fds(d,"wYYYY")).toBe("2015");
// Negative years
d = new Date(-2014,10,9,17,41,28,542);
expect(fds(d,"YYYY")).toBe("-2014");
expect(fds(d,"aYYYY")).toBe("2014");
expect(fds(d,"{era:bce||ce}")).toBe("bce");
// Zero years
d = new Date(0,10,9,17,41,28,542);
d.setUTCFullYear(0); // See https://stackoverflow.com/a/5870822
expect(fds(d,"YYYY")).toBe("0000");
expect(fds(d,"aYYYY")).toBe("0000");
expect(fds(d,"{era:bce|z|ce}")).toBe("z");
});
it("should parse text references", function() {

View File

@ -1,28 +0,0 @@
created: 20150117190213631
modified: 20150124214537000
tags: Concepts
title: Date Fields
type: text/vnd.tiddlywiki
Certain [[fields|TiddlerFields]] of a tiddler are used to store dates and times.
The two standard date fields are <<.field created>> and <<.field modified>>.
Values of date fields are 17-character strings:
* 4 digits for the year
* 2 digits for the month
* 2 digits for the day
* 2 digits for the hour
* 2 digits for the minute
* 2 digits for the second
* 3 digits for the millisecond
To avoid problems arising from differences of time zone, TiddlyWiki always uses [[UTC|https://en.wikipedia.org/wiki/Coordinated_Universal_Time]].
As an example, the <<.field created>> field of this tiddler has the value <<.value """<$view field="created"/>""">>.
Dates can be [[converted to other formats|DateFormat]] for display:
<$macrocall $name="wikitext-example-without-html"
src="""<$view field="created" format="date" template="DDD DDth MMM YYYY"/>""">

View File

@ -1,48 +0,0 @@
created: 20140418142957325
modified: 20180730201626985
tags: Features
title: DateFormat
type: text/vnd.tiddlywiki
When used to display date values (with the `format` attribute set to ''date''), the ViewWidget accepts a `template` attribute that allows the format of the date values to be specified. The format string is processed with the following substitutions:
|!Token |!Substituted Value |
|`DDD` |Day of week in full (eg, "Monday") |
|`ddd` |Short day of week (eg, "Mon") |
|`DD` |Day of month |
|`0DD` |Adds a leading zero |
|`DDth` |Adds a suffix |
|`WW` |ISO-8601 week number of year |
|`0WW` |Adds a leading zero |
|`MMM` |Month in full (eg, "July") |
|`mmm` |Short month (eg, "Jul") |
|`MM` |Month number |
|`0MM` |Adds leading zero |
|`YYYY` |Full year |
|`YY` |Two digit year |
|`wYYYY` |Full year with respect to week number |
|`wYY` |Two digit year with respect to week number |
|`hh` |Hours |
|`0hh` |Adds a leading zero |
|`hh12` |Hours in 12 hour clock |
|`0hh12` |Hours in 12 hour clock with leading zero |
|`mm` |Minutes |
|`0mm` |Minutes with leading zero |
|`ss` |Seconds |
|`0ss` |Seconds with leading zero |
|`XXX` |Milliseconds |
|`0XXX` |Milliseconds with leading zero |
|`am` or `pm` |Lower case AM/PM indicator |
|`AM` or `PM` |Upper case AM/PM indicator |
|`TZD` |Timezone offset |
|`\x` |Used to escape a character that would otherwise have special meaning |
|`[UTC]`|Time-shift the represented date to UTC. Must be at very start of format string|
Note that other text is passed through unchanged, allowing commas, colons or other separators to be used.
! Examples
|!Template |!Output |
|`DDth MMM YYYY` |16th February 2011 |
|`DDth MMM \M\M\M YYYY` |16th February MMM 2011 |
|`DDth mmm YYYY 0hh:0mm:0ss` |16th Feb 2011 11:38:42 |