-2

I am currently building an internal tool that highlights the pay periods. When a user clicks on a date, it'll return the pay period it belongs to.

I have a singular endDate of a pay period: 2020-01-05 (YYYY-MM-DD). Each pay period is 2 weeks so this pay period would be: 2019-12-23 to 2020-01-05.

If I were to select a random date, I need to return the pay period it belongs to. I can't seem to figure out a solution without brute forcing it and creating a loop starting from a valid pay period and going back by increments/decrements of 14 days until we find the right pay period.

Anyone have any ideas?


Potential solution: Figure out how many days/weeks are between the selected day and the valid payPeriod. Then use that information to determine the pay period. This removes the need to loop over and over to find the right period.

TGrif
  • 5,725
  • 9
  • 31
  • 52
Syn
  • 938
  • 1
  • 10
  • 21
  • how are you storing the data which represents each pay period? Are you using Date objects, or just strings? Have you got any code at all yet which we could see? – ADyson Jan 08 '20 at 16:26
  • I currently only have a date object storing a valid `endDate` of a pay period. Not much code to show. All I got is a react-datepicker with the current date selected. – Syn Jan 08 '20 at 16:27
  • Is the data sourced from a database at all? It would probably be easier to do this in SQL. – ADyson Jan 08 '20 at 16:28
  • No backend. Has to be done completely in frontend – Syn Jan 08 '20 at 16:29
  • 1
    If all you have is a single date, then you will have to calculate all of the other periods from that single date. To check if a date is between two others, [Check if one date is between two dates](https://stackoverflow.com/q/16080378/215552). – Heretic Monkey Jan 08 '20 at 16:33
  • I know how to check if its between two dates lol. I was wondering if there was a smarter way to find out which pay period it belongs to without looping through every single previous option. A small idea popped up in my mind: Figure out how many days/weeks are between the valid `payPeriod` by comparing the time, then make a smarter decision about the payPeriod with that information – Syn Jan 08 '20 at 16:39
  • Are you open to using a library like Moment.js (https://momentjs.com)? Do you want keep the solution in vanilla JavaScript? – LHM Jan 08 '20 at 16:43
  • 1
    I am using date fns to help with some calculating. I dont want to add moment to my project – Syn Jan 08 '20 at 16:47
  • "I need to return the pay period it belongs to." What would this look like? Do you need the dates associated with it? Or do the pay periods have identifying numbers (e.g. Pay Period 1, 2, 3...)? – LHM Jan 08 '20 at 17:05

1 Answers1

0

Since you're using date-fns, the differenceInWeeks method might be your best best. (There is also a differenceInCalendarWeeks method, but I do not think you need the weekStartsOn functionality that it offers.)

(A vanilla JavaScript solution could be built from this answer, if desired.)

From the date-fns documentation:

// How many full weeks are between 5 July 2014 and 20 July 2014?
var result = differenceInWeeks(new Date(2014, 6, 20), new Date(2014, 6, 5))
//=> 2

You could use this information to calculate the number of two-week periods from your initial endDate:

var result = Math.ceil(differenceInWeeks(randomDate, endDate)/2)
// Returns number of pay period after endDate

For dates that are before or including endDate, it would need to look like this:

var refDate = addDays(endDate, 1); // using refDate ensures full weeks for calculation
var result = Math.ceil(differenceInWeeks(refDate, randomDate)/2)
// Returns number of pay period before endDate (1 is endDate's pay period)

Then, to get the specific dates for the resulting pay periods, use the date-fns add() or sub() functions to get the end date of the pay period in question. (Unfortunately, these functions do not have a weeks option, so you will need to convert the number of weeks to days) Example for a randomDate after endDate:

var result = Math.ceil(differenceInWeeks(randomDate, endDate)/2)
var newEndDate = add(endDate, {days: result*14}); // *2 for weeks, *7 for days
// Returns end date of pay period containing randomDate after endDate

Example for randomDate before or including endDate (note this returns the start date):

var refDate = addDays(endDate, 1); // using refDate ensures full weeks for calculation
var result = Math.ceil(differenceInWeeks(refDate, randomDate)/2)
var newStartDate = sub(refDate, {days: result*14}); // *2 for weeks, *7 for days
// Returns start date of pay period containing randomDate before endDate, inclusive

You did not provide a desired output format, but you should then be able to manipulate these results for your calendar to highlight the correct dates.

LHM
  • 721
  • 12
  • 31