I've implemented support for week numbers. (We use them extensively at work for project related activity.) This allows, for example, setting the newJournal parameters
{{{<<newJournal 'YYYY-0MM-0DD wk0WW DDD'>>}}}
to give: "2006-05-01 wk18 Monday"
Support consists of two ammendments to the core, the addition of the WW and 0WW formats in Date.prototype.formatString, and the addition of a Date.prototype.getWeek function. These are below, followed by some test code.
It would be great if these could be included in the next release of TiddlyWiki. (I originally did the newJournal support as a newJournal2 macro, but think that these additions are sufficiently general to be included in the core.)
//{{{ // Substitute date components into a string Date.prototype.formatString = function(template) { ... template = template.replace(/ss/g,this.getSeconds()); // these are the two new formats template = template.replace(/0WW/g,String.zeroPad(this.getWeek(),2)); template = template.replace(/WW/g,this.getWeek()); return template;
}
// and here's the new function Date.prototype.getWeek = function() { var dt = new Date(this.getTime()); var d = dt.getDay(); if (d==0) d=7;// JavaScript 0=Sun, ISO 0=Mon dt.setTime(dt.getTime()+(4-d)*86400000);// shift day to Thurs of same week to calculate weekNo var n = Math.floor((dt.getTime()-new Date(dt.getFullYear(),0,1)+3600000)/86400000); return Math.floor(n/7)+1;
}
//}}}
// Test code follows: //
/*{{{*/ //short macro for testing Date.prototype.getWeek function. config.macros.weekNo = {label:"weekNo",prompt:"week number"}; config.macros.weekNo.handler = function(place,macroName,params) { var dt = new Date(params[0]); t = dt.getWeek(); var output = "w:" + String.zeroPad(t,2) + " d:" + config.messages.dates.days[dt.getDay()]; wikify(output,place,null,null);
> I've implemented support for week numbers. (We use them extensively at > work for project related activity.) This allows, for example, setting > the newJournal parameters
> {{{<<newJournal 'YYYY-0MM-0DD wk0WW DDD'>>}}}
> to give: "2006-05-01 wk18 Monday"
> Support consists of two ammendments to the core, the addition of the WW > and 0WW formats in Date.prototype.formatString, and the addition of a > Date.prototype.getWeek function. These are below, followed by some test > code.
> It would be great if these could be included in the next release of > TiddlyWiki. (I originally did the newJournal support as a newJournal2 > macro, but think that these additions are sufficiently general to be > included in the core.)
> //{{{ > // Substitute date components into a string > Date.prototype.formatString = function(template) > { > ... > template = template.replace(/ss/g,this.getSeconds()); > // these are the two new formats > template = template.replace(/0WW/g,String.zeroPad(this.getWeek(),2)); > template = template.replace(/WW/g,this.getWeek()); > return template; > }
> // and here's the new function > Date.prototype.getWeek = function() > { > var dt = new Date(this.getTime()); > var d = dt.getDay(); > if (d==0) d=7;// JavaScript 0=Sun, ISO 0=Mon > dt.setTime(dt.getTime()+(4-d)*86400000);// shift day to Thurs of same > week to calculate weekNo > var n = Math.floor((dt.getTime()-new > Date(dt.getFullYear(),0,1)+3600000)/86400000); > return Math.floor(n/7)+1; > } > //}}}
> // Test code follows: //
> /*{{{*/ > //short macro for testing Date.prototype.getWeek function. > config.macros.weekNo = {label:"weekNo",prompt:"week number"}; > config.macros.weekNo.handler = function(place,macroName,params) > { > var dt = new Date(params[0]); > t = dt.getWeek(); > var output = "w:" + String.zeroPad(t,2) + " d:" + > config.messages.dates.days[dt.getDay()]; > wikify(output,place,null,null); > } > /*}}}*/
I've just joined, and wasn't aware of the previous discussion.
As is stated in that discussion, there's an ISO standard (ISO-8601) that defines week numbers. When week numbers are used by projects across several companies this is universally used - after all it's no use if the statement "we're shipping the code on Monday of week 17" is ambiguous. Week numbers are very commonly used by European companies (I've used them communicating with Nokia, Sony Ericsson, Philips among others).
The standard states that: a) weeks begin on a Monday b) the first week in the year is the first week that has 4 or more days in it. This is equivalent to the first week with a Thursday in it.
This means that years can have either 52 or 53 weeks, and that the 1st of Jan can occur in week 1, 52 or 53, depending on the date of the first Thursday in January.
My code exploits the fact that week number of a given day is the same as the week number of the Thursday of that week, and that week 1 is the first week with a Thursday in it. Here's the code with a bit more commenting:
var d = dt.getDay(); // in JavaScript Sunday is day 0 (days range from 0-6) // but for the ISO standard, Sunday is day 7 (days range from 1-7) if (d==0) d=7;
// move the day to Thursday of the same week (the 4 is day 4, thursday) // 86400000 is the number of milliseconds in a day dt.setTime(dt.getTime()+(4-d)*86400000);
// calculate the number of days of the shifted day from the begining // of the year containing that day // (note that the day shift may have caused the year to shift) // add an hour (3600000) to compensate for rounding errors var n = Math.floor((dt.getTime()-new Date(dt.getFullYear(),0,1)+3600000)/86400000);
// divide number of days by 7 to get number of weeks and add 1, // since week numbers start at 1. return Math.floor(n/7)+1;
I'm confident that the code complies to the standard (there's a reasonable amount of test code).
Yeah, I agree that the week number code checks out, I was wondering about the issue with having to adjust the year - the suggestion that 29-12-2005 might need to be written as 2006w01. Is that really necessary? One could imagine implementing it by having a variant code for the year (like "WYWY") that takes into account the week number.
Cheers
Jeremy
On 02/05/06, Martin Budden <mjbud...@gmail.com> wrote:
> I've just joined, and wasn't aware of the previous discussion.
> As is stated in that discussion, there's an ISO standard (ISO-8601) > that defines week numbers. When week numbers are used by projects > across several companies this is universally used - after all it's no > use if the statement "we're shipping the code on Monday of week 17" is > ambiguous. Week numbers are very commonly used by European companies > (I've used them communicating with Nokia, Sony Ericsson, Philips among > others).
> The standard states that: > a) weeks begin on a Monday > b) the first week in the year is the first week that has 4 or more days > in it. This is equivalent to the first week with a Thursday in it.
> This means that years can have either 52 or 53 weeks, and that the 1st > of Jan can occur in week 1, 52 or 53, depending on the date of the > first Thursday in January.
> My code exploits the fact that week number of a given day is the same > as the week number of the Thursday of that week, and that week 1 is the > first week with a Thursday in it. Here's the code with a bit more > commenting:
> var d = dt.getDay(); > // in JavaScript Sunday is day 0 (days range from 0-6) > // but for the ISO standard, Sunday is day 7 (days range from 1-7) > if (d==0) d=7;
> // move the day to Thursday of the same week (the 4 is day 4, thursday) > // 86400000 is the number of milliseconds in a day > dt.setTime(dt.getTime()+(4-d)*86400000);
> // calculate the number of days of the shifted day from the begining > // of the year containing that day > // (note that the day shift may have caused the year to shift) > // add an hour (3600000) to compensate for rounding errors > var n = Math.floor((dt.getTime()-new > Date(dt.getFullYear(),0,1)+3600000)/86400000);
> // divide number of days by 7 to get number of weeks and add 1, > // since week numbers start at 1. > return Math.floor(n/7)+1;
> I'm confident that the code complies to the standard (there's a > reasonable amount of test code).
Good point. A variant code for the week adjusted year number is required. I guess a two character variant for a two digit year is also required.
Rather than using "WYWY" and "WY", I think I'll use "wYYYY" and "wYY", treating the w as a modifier to an existing format (cf 0MM). Also "WY" seems just that little bit too common and might come up in text (eg WYOMING). (I thought of using YWYW and YW, but then YW comes up in YWCA.)
Sorry this has taken a little while, it's been a busy week.
I've added the week adjusted year format (using wYY and wYYYY). While doing this I extended the date formatting to allow full and abbreviated day and month names (eg February, Feb, Thursday, Thu) and lowercase versions (eg february, feb, thursday, thu). There seem to be quite a few Todo and Calendar type TiddlyWikis that implement their own abbreviated date formatting. Having these in the core will benefit these plugins, and will also mean they get there date abbreviations translated whenever anyone translates the core.
I've implemented this as follows:
New formats MMMM, mmmm, DDDD, dddd for full month and day names (and lowercase forms). New formats ddd and mmm for abbreviated month and day names (lowercase forms) Additional monthAbbrs and dayAbbrs arrays in config.messages.dates.
New option chkDateFormatMmmDddAsFullName (set to true as default). This option controls whether the formats DDD and MMM represent full day and month names, or the abbreviated forms.
Having the option set true as default means that existing TiddlyWikis and plugins won't be changed by an upgrade. They can then can either: i) leave the option set to true ii) change the option to false, if they prefer (or don't mind) using the abbreviated date format iii) change any date formats from MMM and DDD to MMMM and DDDD and then switch the option to false.
You may wish to change config.macros.timeline from {dateFormat: "DD MMM YYYY"} to {dateFormat: "DD MMM YYYY"}
and the SideBarOptions Shadow tiddler from <<newJournal 'DD MMM YYYY'>> to <<newJournal 'DD MMM YYYY'>>
on the other hand, you may wish to and retain these as they are and so migrate to the abreviated format.
I was just about to post this, when I saw Simon Baird's AM/PM posting! So I have included this for completeness (and to save you doing two updates).
The the following are included below:
A) The changes to the JavaScript Date() object B) The configuration option chkDateFormatMmmDddAsFullName (and its associated entry in the AdvancedOptions Shadow Tiddler) C) The additional monthAbbrs and dayAbbrs arrays in config.messages.dates D) The test code E) The tiddler that exercises the test code F) The output from the test code
Date.prototype.getWeek = function() { var dt = new Date(this.getTime()); var d = dt.getDay(); if (d==0) d=7;// JavaScript Sun=0, ISO Sun=7 dt.setTime(dt.getTime()+(4-d)*86400000);// shift day to Thurs of same week to calculate weekNo var n = Math.floor((dt.getTime()-new Date(dt.getFullYear(),0,1)+3600000)/86400000); return Math.floor(n/7)+1;
}
Date.prototype.getYearForWeekNo = function() { var dt = new Date(this.getTime()); var d = dt.getDay(); if (d==0) d=7;// JavaScript Sun=0, ISO Sun=7 dt.setTime(dt.getTime()+(4-d)*86400000);// shift day to Thurs of same week return dt.getFullYear();
}
Date.prototype.getHours12 = function() { var h = this.getHours(); return (h > 12 ? h-12 : ( h > 0 ? h : 12 ));
That's great, Martin, thanks so much. Yours are very thoughtful contributions, and I hope you don't find the to-and-fro too discouraging!
One minor point is that I was wondering what was the motivation for the lower case weeks and days?
Also the chkDateFormatMmmDddAsFullName thing feels quite lumpy; I was again curious about the motivation. I'd have expected that the existing settings for 'MMM' and 'DDD' would stay the same, and that anyone who wants to use the new, longer versions can do so by explicitly specifying them. If anyone really, really wants to retrospectively change existing 'MMM' and 'DDD' format date strings to use the longer formats, it would seem reasonable to override formatString() to redefine how those two strings get substituted, if that makes sense.
Cheers
Jeremy
On 07/05/06, Martin Budden <mjbud...@gmail.com> wrote:
> Sorry this has taken a little while, it's been a busy week.
> I've added the week adjusted year format (using wYY and wYYYY). While > doing this I extended the date formatting to allow full and abbreviated > day and month names (eg February, Feb, Thursday, Thu) and lowercase > versions (eg february, feb, thursday, thu). There seem to be quite a > few Todo and Calendar type TiddlyWikis that implement their own > abbreviated date formatting. Having these in the core will benefit > these plugins, and will also mean they get there date abbreviations > translated whenever anyone translates the core.
> I've implemented this as follows:
> New formats MMMM, mmmm, DDDD, dddd for full month and day names (and > lowercase forms). > New formats ddd and mmm for abbreviated month and day names (lowercase > forms) > Additional monthAbbrs and dayAbbrs arrays in config.messages.dates.
> New option chkDateFormatMmmDddAsFullName (set to true as default). This > option controls whether the formats DDD and MMM represent full day and > month names, or the abbreviated forms.
> Having the option set true as default means that existing TiddlyWikis > and plugins won't be changed by an upgrade. They can then can either: > i) leave the option set to true > ii) change the option to false, if they prefer (or don't mind) using > the abbreviated date format > iii) change any date formats from MMM and DDD to MMMM and DDDD and then > switch the option to false.
> You may wish to change > config.macros.timeline > from {dateFormat: "DD MMM YYYY"} to {dateFormat: "DD MMM YYYY"}
> and the SideBarOptions Shadow tiddler > from <<newJournal 'DD MMM YYYY'>> to <<newJournal 'DD MMM YYYY'>>
> on the other hand, you may wish to and retain these as they are and so > migrate to the abreviated format.
> I was just about to post this, when I saw Simon Baird's AM/PM posting! > So I have included this for completeness (and to save you doing two > updates).
> The the following are included below:
> A) The changes to the JavaScript Date() object > B) The configuration option chkDateFormatMmmDddAsFullName (and its > associated entry in the AdvancedOptions Shadow Tiddler) > C) The additional monthAbbrs and dayAbbrs arrays in > config.messages.dates > D) The test code > E) The tiddler that exercises the test code > F) The output from the test code
> Date.prototype.getWeek = function() > { > var dt = new Date(this.getTime()); > var d = dt.getDay(); > if (d==0) d=7;// JavaScript Sun=0, ISO Sun=7 > dt.setTime(dt.getTime()+(4-d)*86400000);// shift day to Thurs of same > week to calculate weekNo > var n = Math.floor((dt.getTime()-new > Date(dt.getFullYear(),0,1)+3600000)/86400000); > return Math.floor(n/7)+1; > }
> Date.prototype.getYearForWeekNo = function() > { > var dt = new Date(this.getTime()); > var d = dt.getDay(); > if (d==0) d=7;// JavaScript Sun=0, ISO Sun=7 > dt.setTime(dt.getTime()+(4-d)*86400000);// shift day to Thurs of same > week > return dt.getFullYear(); > }
> Date.prototype.getHours12 = function() > { > var h = this.getHours(); > return (h > 12 ? h-12 : ( h > 0 ? h : 12 )); > }
i) I agree that lower case day and month names is strictly unnecessary, but they do serve a useful purpose: when tagging an item with a day or month, generally the item is of prime importance and the date of secondary importance. Keeping the day or month in lower case avoids drawing the eye to it.
ii) Current behavior is: MMMM - undefined DDDD - undefined. MMM - March (say) DDD- Tuesday (say)
I'm changing it to MMMM - March (say) DDDD- Tuesday (say) MMM - Mar (say) DDD - Tue (say)
so I'm changing the behavior of MMM and DDD.
The chkDateFormatMmmDddAsFullName compatibility flag avoids breaking any plugins that depend on the old MMM and DDD formats.
(By the way, I don't find the to and fro-ing discouraging, I'm glad you want to get things right, and having a high bar to entry makes it that much more satisfying if you do accept my code into the core.)
- we omit the lowercase month and day support, and delegate it to an extension plugin - we leave the behaviour of MMM and DDD as it is at the moment, to avoid the complexity of adding another checkbox option - we add MM3 and DD3 to signify the 3-letter abbreviated months and days
Of course, I'd have to embarrassedly agree that your remapping of MMMM vs MMM is much more logical and usable, but I'm just concerned about backwards compatibility.
Cheers
Jeremy.
On 08/05/06, Martin Budden <mjbud...@gmail.com> wrote:
> i) I agree that lower case day and month names is strictly unnecessary, > but they do serve a useful purpose: when tagging an item with a day or > month, generally the item is of prime importance and the date of > secondary importance. Keeping the day or month in lower case avoids > drawing the eye to it.
> ii) Current behavior is: > MMMM - undefined > DDDD - undefined. > MMM - March (say) > DDD- Tuesday (say)
> I'm changing it to > MMMM - March (say) > DDDD- Tuesday (say) > MMM - Mar (say) > DDD - Tue (say)
> so I'm changing the behavior of MMM and DDD.
> The chkDateFormatMmmDddAsFullName compatibility flag avoids breaking > any plugins that depend on the old MMM and DDD formats.
> (By the way, I don't find the to and fro-ing discouraging, I'm glad you > want to get things right, and having a high bar to entry makes it that > much more satisfying if you do accept my code into the core.)
I guess inclusion of lowercase support cannot really be justified. As you say this can be delegated to a plugin (since the ddd dddd etc formats remain unused).
MM3 and DD3 are fine as an alternative to my compatibility flag. I have one request though: can you retain the MMMM and DDDD forms and make them the "official" forms. This gives:
MMMM - official full monthname MMM - deprecated full monthname, retained for compatibility MM3 - abbreviated monthname.
ditto for days.
This means plugins can migrate to using the MMMM and DDDD forms, if required, and at some point in the future it will be possible then convert to using the MMM and DDD forms.
I know this is an additional two lines of code, but I've been reading the code and I think I can find some savings elsewhere to "pay" for it.
> I guess inclusion of lowercase support cannot really be justified. As > you say this can be delegated to a plugin (since the ddd dddd etc > formats remain unused).
> MM3 and DD3 are fine as an alternative to my compatibility flag. I have > one request though: can you retain the MMMM and DDDD forms and make > them the "official" forms. This gives:
> MMMM - official full monthname > MMM - deprecated full monthname, retained for compatibility > MM3 - abbreviated monthname.
> ditto for days.
> This means plugins can migrate to using the MMMM and DDDD forms, if > required, and at some point in the future it will be possible then > convert to using the MMM and DDD forms.
> I know this is an additional two lines of code, but I've been reading > the code and I think I can find some savings elsewhere to "pay" for it.