Not really a language specific question, but my language in use in the examples below is Swift. The code itself is written to be somewhat language agnostic.
public class Employment {
public var payFrequency: PayFrequency
public var payPeriods: [PayPeriod]
// Other class data, variables, etc.
// Constructors, other functions, etc.
public func calculatePayPeriods(payBegin: NSDate) {
self.payPeriods = [] // Null out array
// Enter loop to the extent of calculation.. Infinity?
// Create the PayPeriod object with start, end, and # of hours worked.
// Advance # of days based on payFrequency
}
}
Now I have only included the respective variable(s) and function(s). My question in particular is obviously on the calculatePayPeriods(...) function. This function in particular will be called once the user inputs a single pay period start date. Since I obviously, or well practically, cannot generate the pay periods until the end of time and would prefer not to do year-by-year. My question is as follows: what sort of implementation would best suit a situation where the data being calculated can potentially span infinitely?
Here is the implementation, and a helper function if needed for reference:
public struct PayPeriod {
public var startDate: NSDate
public var endDate: NSDate
public var hours: Double
}
// Returns .Other(amount); 'amount' being in days.
// If 'amount' is compatible with any other case in the enum, then instead that
// case is returned.
public func determinePayFrequency(start: NSDate, end: NSDate) -> PayFrequency {
let converter: Double = 60*60*24 // 60 seconds 60 minutes 24 hours
let calendar = NSCalendar.currentCalendar()
let unit = NSCalendarUnit.CalendarUnitDay
let componentFlags = NSCalendarUnit.CalendarUnitYear | NSCalendarUnit.CalendarUnitMonth | NSCalendarUnit.CalendarUnitDay
// Strip away any extra components we don't need such as hour/min/sec/etc.
var startDay = calendar.dateFromComponents(calendar.components(componentFlags, fromDate:start))!
var endDay = calendar.dateFromComponents(calendar.components(componentFlags, fromDate:end))!
// '+ 1' is to go THROUGH the end day.
return PayFrequency(days: Int(endDay.timeIntervalSinceDate(startDay) / converter) + 1)
}
I appreciate the time you took to read over my question and code. Thank you.
Best regards,
Steven
From what I understand, you want to basically give the user a reasonable range of dates initially and then populate dynamically if they request more. This is a really common practice.
For example, facebook's public home page does not have all the posts that they need in 1 huge page. Instead, they delegate only x amount of posts on the screen at once. Once the user scrolled to the bottom, there would be more loaded.
From what I understand, the background behind this is that facebook has a database that it's constantly retrieving json/xml data from to populate your public home page. Requests that are too big(in your case, infinitely big) would have to be truncated down to x amount, then facebook's cookies hold a variable as to where to retrieve data from in the database again.
The same can be applied with your algorithm. If you feel that the retrievals are VERY frequent, then you should keep a dynamic array(that can reallocate size, commonly by 2x the previous size if needed) and add Day objects until the biggest submission. The ones that request times that are greater than the array size should trigger a function to populate the array to be just big enough to hold the data. If they're not too frequent, you could even just compute a calendar from start date to end date for every entry, and the time would not be inefficient either.
Hope I helped!