1

I'm trying to determine four dates based on the current date -- the beginning of the current pay period to today, and then then start and end dates of the previous pay period -- and I'm having trouble finding the correct execution.

To me it makes sense to have an object with four properties like payPd.currentStart, payPd.currentEnd, payPd.priorStart, and payPd.priorEnd.

Currently I'm working backward from the .currentEnd, which is today, and subtracting days until it's Monday on an odd week -- pay periods are two weeks long:

 var dt = new Date();

    Date.prototype.getWeek = function () {
        var onejan = new Date(this.getFullYear(), 0, 1);
        return Math.ceil((((this - onejan) / 86400000) + onejan.getDay() + 1) / 7);
    }

    var currentStart = '';
    var currentEnd = new Date();
    var priorStart = '';
    var priorEnd =   '';

    function ppdStart(currentEnd){
    var inDate = currentEnd;
        while (inDate.getWeek() % 2 !== 0 || inDate.getDay() !== 1) {
        inDate.setDate(inDate.getDate() - 1);
        }
        return outDate;
        }

So the question is, can I define one property, then define the next property as a function of that one (next odd Monday before today), and so on with the rest? Would I want a callback function, or a get/set? I'm not sure where to go next.

Thanks to all of you in the Javascript community I'm just now joining.

oxwilder
  • 756
  • 5
  • 14
  • Do you want to do this specifically on the `Date` object, or are you open for libraries like [`momentjs`](https://momentjs.com/docs/#/manipulating/) that would help you with a lot of that work? – Icepickle May 14 '20 at 21:46
  • 1
    What do you mean by "Monday on an odd week"? If you mean week of the year, how do you handle some years having 52 weeks and others 53? Is there a one or three week pay period in the case of 53 weeks? Where fortnights are used, it may be better to calculate from a particular start date (epoch) and add fortnights as multiples of 14 days. Don't use hours as daylight saving changeover will mess you up in rare and difficult to find cases. – RobG May 15 '20 at 02:47
  • @robg These are all fine questions, and I'll be honest I just looked up a "get week number" function and plugged it in. As far as DST, I can't think of an instance where being off by 3600 seconds will break the function. I'll look into that epoch thing though, I'm so glad to be able to get more information on this stuff :) – oxwilder May 15 '20 at 14:57

2 Answers2

1

I personally wouldn't bother with extending the prototype for such function. You might as well have a wrapper around a date object that handles any calculation based on the date you originally send in.

This date could then be used to get to the next or the previous period relative to the original date.

I added a snippet of what I mean, and it gives you an easy way to determine the date you originally asked for, and it's pay date. The end period for the payment would then be the start date of the next period minus 1 day.

// from: https://stackoverflow.com/a/7751977/3231537
const twoWeeks = 12096e5;

// from: https://gist.github.com/dblock/1081513
var weekOfYear = function(date){
    var d = new Date(+date);
    d.setHours(0,0,0);
    d.setDate(d.getDate()+4-(d.getDay()||7));
    return Math.ceil((((d-new Date(d.getFullYear(),0,1))/8.64e7)+1)/7);
};

class PayDateHelper {
  constructor( date ) {
    this._date = date;
  }
  nextPayPeriod() {
    return new PayDateHelper( new Date( this.currentDate.getTime() + twoWeeks ) );
  }
  previousPayPeriod() {
    return new PayDateHelper( new Date( this.currentDate.getTime() - twoWeeks ) );
  }
  get currentDate() {
    return this._date;
  }
  get payDate() {
    let interval = 0;
    // when we are in an even week, subtract 7 days
    if ( weekOfYear( this.currentDate ) % 2 === 0 ) {
      interval += 7;
    }
    // and substract the days of the week back to 1 (monday)
    interval += (this.currentDate.getDay() - 1);
    const date = new Date( this.currentDate );
    date.setDate( date.getDate() - interval );
    return date;
  }
}


console.log('-- current period');
let helper = new PayDateHelper( new Date() );
console.log( helper.currentDate );
console.log( helper.payDate );

console.log('-- next period');
let nextPeriod = helper.nextPayPeriod();
console.log( nextPeriod.currentDate );
console.log( nextPeriod.payDate );

console.log('-- previous period');
let previousPeriod = helper.previousPayPeriod();
console.log( previousPeriod.currentDate );
console.log( previousPeriod.payDate );
Icepickle
  • 12,689
  • 3
  • 34
  • 48
  • 1
    Ah! So happy to be pointed in the direction of classes. I didn't even know to consider them. Thanks :D – oxwilder May 15 '20 at 15:00
0

It seems that you want to do something like (in pseudo code):

let obj = {
  today: new Date(),
  yesterday: today - 1 day,
  tomorrow: today + 1 day
};

where you set today to whatever value and yesterday and today are updated accordingly.

You can do that with a getter, so that getting the values for yesterday and tomorrow calculates them based on the value for today.

e.g.

let obj = {
  get yesterday() {
    if (this.today != undefined) {
      let d = new Date(this.today);
      d.setDate(d.getDate() - 1);
      return d;
    } else {
      return void 0;
    }
  },
  get tomorrow() {
    if (this.today != undefined) {
      let d = new Date(this.today);
      d.setDate(d.getDate() + 1);
      return d;
    } else {
      return void 0;
    }
  }
};

// Initial values
console.log('Yesterday: ' + obj.yesterday)
console.log('Today    : ' + obj.today)
console.log('Tomorrow : ' + obj.tomorrow)
// Set today
obj.today = new Date();
// Get values
console.log('Yesterday: ' + obj.yesterday.toDateString());
console.log('Today    : ' + obj.today.toDateString());
console.log('Tomrrow  : ' + obj.tomorrow.toDateString());
RobG
  • 142,382
  • 31
  • 172
  • 209