New .same() Function, But Is It Useful?

May 13th, 2008 | Code

I need some feedback regarding a feature I just added to the library, but I'm struggling to explain/document clearly and I'm not sure if others would find this useful.

The new .same() function will compare two date objects to determine if they occur on/in exactly the same instance of the given date part. (...like I said, I'm having a hard time explaining this one).

It's easier to understand with code...

Scenario: Determine if the two dates occur on the same day.

Example

var d1 = Date.today(); // today at 00:00
var d2 = new Date();   // exactly now.

// Do they occur on the same day?
d1.same().day(d2); // true

// What if it's the same day, but one year apart?
var nextYear = Date.today().add(1).year();

d1.same().day(nextYear); // false, because the dates must occur on the exact same day.

When comparing the dates in the same above, the .same() function will test that the year, month, and day match. Because we're only interested in whether the day is the same, the hour, minute, second & millisecond values are ignored.

Using the same d1 & d2 values from above, determine if the two dates occur on the same hour.

Example

// Do they occur on the same hour?
d1.same().hour(d2); // false, unless d2 hour is '00' (< 1:00 am).

If no date is passed as a parameter, by default the .same() function will use 'Now' (new Date()) as the default date to compare against.

Example

Date.today().same().day(); // true, 'today' occurs on 'today'
Date.today().same().hour(); // false, unless 'now' is '00' minutes (< 1:00am)

What do think? Would you find this functionality useful?

I do... because I'm often trying to determine if some date object occurs during today. The following samples demonstrate various ways to determine if a date object occurs today.

Example (native JavaScript, without Datejs)

var temp = new Date();
temp.setHours(0);
temp.setMinutes(0);
temp.setSeconds(0);
temp.setMilliseconds(0);

var today = new Date(someDate.getTime()); // clone original instance so we don't actually change the original date.
var today.setHours(0);
var today.setMinutes(0);
var today.setSeconds(0);
var today.setMilliseconds(0);

(today == temp); // true|false

Example (with Datejs)

// with Datejs, but without .same
someDate.clone().clearTime().equals(Date.today());

// New
someDate.same().day();

// Or,
someDate.is().today();

Checking if a given date object occurs today is easy enough with Datejs and would not really justify adding the new .same() functionality, but things can get nasty when you need to compare against a date other than 'today'.

Scenario: Determine if a given date occurs during some week period 2 months from now.

Example

// New
var future = Date.today().add(2).months();

return someDate.same().week(future); // true|false;

The .same() function adds a third context to .second() within the library, which enables the following interesting (but freakishly cryptic) logic.

Example

Date.jan().second().monday().add(1).second().same().second();

The .same() functionality has been added to sugarpak.js and is available from SVN.

Any feedback is appreciated.

10 Comments

  1. […] geoffrey.mcgill wrote an interesting post today on New .same() function, but is it useful?Here’s a quick excerptI need some feedback regarding a feature I just added to the library, but I’m struggling to explain/document clearly and I’m not sure if others would find this useful. The new .same() function will compare two date objects to determine … […]

    Pingback by Library » Blog Archive » New .same() function, but is it useful? — May 13, 2008 @ 7:13 pm

  2. This looks useful.

    Comment by David — May 14, 2008 @ 6:35 am

  3. I would definitely use it. Great idea!

    Comment by Schalk Neethling — May 15, 2008 @ 6:08 am

  4. Why not call it sameDay() or isSameDay()?

    Comment by Mike — August 5, 2009 @ 7:45 am

  5. Seems to be very useful to me.

    @Mike, because its not only used for days. You can also use d1.same().month(d2) or d1.same.hour(d2) for example, to check whether two event are in the same month (of the same year) or the same hour (of the same day of the same month of the same year) respectively.

    Comment by JW — August 23, 2009 @ 6:54 am

  6. It looks like you’re extending the Number class too. It looked nice till then.

    Comment by Rob Colburn — September 4, 2009 @ 10:56 am

  7. Hi,

    It looks like the contact form on your contact page is broken, so I’m posting here instead in the hope that you will see this comment.

    Are you still maintaining / doing any sort of active development on this code? I’m asking because it’s really quite awesome and I’d like to use it in a Thunderbird add-in I maintain, but there’s one little feature missing… I’d like to be able to say, for example, “8:30 am next weekday” and have “weekday” mean the next day if it is currently Monday through Thursday, or the following Monday if it is currently Saturday or Sunday.

    I looked briefly at the code to see if this would be something easy to add, and boy, it’s complicated!

    Comment by Jonathan Kamens — July 17, 2010 @ 5:30 pm

  8. Hi,
    great work!
    I think this may be useful to me in the near future. I am developing a web application and part of it will notify the user at a certain point in the day that corresponds to a schedule in a table. I think this may work, but as I have just stumbled upon it I will do some research and testing and hope to have a working example soon.

    cheers,
    and keep up the good work!

    Comment by mark — October 27, 2010 @ 3:17 pm

  9. Hi Jonathan Kamens,

    In the current version of datajs there appears to be a function called weekday:

    Date.prototype.weekday = function () {
    if (this._is) {
    this._is = false;
    return !this.is().sat() && !this.is().sun();
    }
    return false;
    }

    However, this returns ‘false’ if you do
    Date().parse(“8:30am”).next().weekend();
    instead of showing the next weekday.

    The datajs code could be extended to include a ‘workday’ and ‘weekend’ function which allow next().workday() and prev().weekend(), assuming Mon-Fri are work days and Saturday is the start of the weekend.

    Date.prototype.weekend = function() {
    if (this._is) {
    this._is = false;
    return this.is().saturday() || this.is().sunday();
    }
    return this.saturday();
    }

    /**
    Next Workday is the next day, skipping weekends (Saturdays and Sundays).

    Example Usage and Output:

    var now, nextWorkday, prevWorkday;

    now = new Date(“8:30 am July 17, 2010”)
    // Sat Jul 17 2010 08:30:00
    now.is().workday();
    // false … Satuday is the weekend, not a workday

    // skip weekends and go straight to Monday.
    nextWorkday = now.clone().next().workday()
    // Mon Jul 19 2010 08:30:00
    nextWorkday.is().workday();
    // true … Monday is a weekday.

    // Previous workday from a Monday, Saturday or Sunday is a Friday, not a Monday.
    prevWorkday = nextWorkday.clone().prev().workday()
    // Fri Jul 16 2010 08:30:00
    prevWorkday.is().workday()
    // true … Friday is a weekday

    now.clone().next().day().is().workday();
    // false … Saturday and Sunday are not work days.

    */
    Date.prototype.workday = function () {
    if (this._is) {
    this._is = false;
    return !this.is().weekend();
    }
    this.day();
    if (this.is().weekend()) {
    this._orient < 0 ? this.friday() : this.monday();
    }
    return this;
    }

    /*
    Licensed under The MIT License
    … feel free to include this code in next release of datajs
    */

    Comment by Joshua S. Weinstein — September 13, 2011 @ 11:38 pm

  10. /**
    Functions to set or test if Date is the end (last day) of the month or the start (first day) of the month.
    */

    Date.prototype.end = function () { if (this._is) { this._is = false; return this.clone().addDays(1).getDate() == 1; } this.setDate(1); return this.addMonths(1).addDays(-1); }

    Date.prototype.start = function () { if (this._is) { this._is = false; return this.getDate() == 1; } this.setDate(1); return this; }

    /*
    Example Usage:
    new Date(2012,2-1,1).end().getDate() === 29
    new Date(2012,2-1,1).next().month().end().getDate() === 31
    Date.november().end().getDate() === 30
    new Date(2011,2,15).is().end() === false
    // The following are true for *any* Date:
    new Date().end().is().end() === true
    new Date().start().getDate() === 1
    new Date().start().is().start() === true
    new Date().end().is().start() === false
    new Date().start().is().end() === false
    */

    Comment by Joshua S. Weinstein — September 14, 2011 @ 12:18 am

Leave a comment