JS Date Object Extensions

2009-04-30 20:00:00 -0400

In our time-tracking app, Tempo, we’ve got a date range drop-down menu, and that allows you to set the start and end dates for a report. Next to it are two text fields for the start and end date, which are over-ridden when the user selects one of the ranges.

Tempo date range selection

This got a little confusing for users because the drop-down selection wasn’t reflected in the text fields, so I threw together some quick javascript for calculating the date end points client-side and setting the fields. In the end, I needed something like:

Tempo.activate_range_select = function() {
var $select = $j(this);

// for each interval, create a start and end date, and insert into date fields
var now = new Date();
var start_date = null;
var end_date = null;

switch($select.val()) {
case "today":
start_date = now.beginning_of_day();
end_date = now;
case "yesterday":
start_date = now.days_ago(1).beginning_of_day();
end_date = now.days_ago(1).end_of_day();

To get here, though, I had to work out these date calculation methods that you can see being used above. Those aren’t naturally occurring methods on the Date class in Javascript, but they can be if you write them yourself! And as you build out the simpler ones, they lend themselves to a full library.

So here’s a little library that extends the Date object with a big pile of handy methods: date.js It’s not all entirely original, I did find some tips out there in the wild and lifted a couple of handy things from the jQuery Date Picker’s date.js. But only a little.

A sampling of some of the methods:

Date.prototype.weekDay = function () {
// in ISO we want Mon = 0 and Sun = 6!
var day = this.getDay() - 1;
day = (day < 0) ? 6 : day;
return day;

Date.prototype.isLeapYear = function() {
var year = this.getFullYear();
return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;

Date.prototype.end_of_week = function() {
var d = this.copy();
d.setDate( this.getDate() + (6 - this.weekDay()) );
return d;

* figuring out the end of quarter:
# q1 = 31 + 28 + 31 = 90 + 2(leap)
# q2 = 30 + 31 + 30 = 91
# q3 = 31 + 31 + 30 = 92
# q4 = 31 + 30 + 31 = 92
Date.prototype.end_of_quarter = function() {
var d = this.copy();
switch( this.getQuarter() ) {
case 1:
// is this a leap year?
if ( this.isLeapYear() ) {
d.setMonth(0, 92); // allow overflow to set correct month and day
} else {
d.setMonth(0, 90)
case 2:
d.setMonth(3, 91);
case 3:
d.setMonth(6, 92);
d.setMonth(9, 92);
return d;

It's a Big World

2009-04-30 20:00:00 -0400

ENTP’s founder Courtenay has an interesting comment up on his blog today:

As a side note, none of these people are from the US, which is a reminder to those of us North American-centric coders that there is a huge world of smart people out there.

Which is funny (or ironic), because on WNYC just now they were discussing 1) the surprising lack of H1B applications for the first time in a long time, and 2) proposals in Congress to make access to temporary worker visas more restrictive. Interesting times.

Tempo Maintenance Tonight: APR-23

2009-04-22 20:00:00 -0400

We’ll be interrupting service briefly tonight (23-APR-2009) on Tempo for a bit of background maintenance that should improve stability of the service. This will take place at 11pm EDT.

My Thoughts Exactly

2009-04-18 20:00:00 -0400

On the Apple Push Notification Service for iPhone OS/SDK 3.0, there’s an interesting comment thread over on Mobile Orchard. Ryan Daigle writes:

This has the potential to become a very expensive and heavy-weight hack to masquerade as a local cron system on the iPhone.

As Adrian Hosey reasons in that same thread, it really is a lot of fail-prone nonsense. There should be some kind of local device API for scheduling with launchd or whatever the OS uses.

Campfire could use Save Points

2009-04-15 20:00:00 -0400

Bryan Lee O'Malley's Scott Pilgrim and the Infinite Sadness Savepoint

Due to a series of unfortunate events I am in this spot where we lost some code, including some custom PL/SQL written for chart series and data calculations. Most of these queries had been pasted into Campfire at some point so I’m digging through transcripts looking for code to reuse.

Campfire is a web-based chat and collaboration tool; we use it all the time here at Zetetic, so much so that I’ve even taken to using a really great third-party client called Propane for it. In any event, it often happens that I need to search through our transcripts to find a particular conversation or look up bits of code that might not be anywhere else. And it’s always a nuisance to identify what you’re searching for when you search on a string of text and then proceed to click through each matching transcript.

So an idea occurred to me: Save Points! It’s very, very common in many of the interfaces we use (at least in the tech world) to have some kind of toggle in the gutter of a view allowing us to mark an item for later review. GMail and Google Reader both use a star for this:

Google Reader Star

In Apple’s XCode IDE (and many other IDE’s), we often click in the gutter next to a line of code to set a breakpoint:

Xcode Breakpoint

What I think Campfire needs is a turn on this type of interface, a feature I can’t help but think of as a Save Point. I want to be able to click in the gutter next to a line of conversation in a Campfire chat so that I can later pull up all my save points instead of searching. In fact, I’d also like to be able to click on the save point and give it a name.

Campfire Chat

The reason I think it would help me in my current scenario is that presumably when I pasted something like “woot! this is the final version of such and such query and it totally works fast!”, I’d paste the query and then I’d just click a quick save point in case I wanted to return to that point in the conversation at some later date. Here’s hoping the 37Signals folks will consider implementing such a feature.