Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 788235
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 14, 20262026-05-14T21:19:49+00:00 2026-05-14T21:19:49+00:00

First question. Be gentle. I’m working on software that tracks technicians’ time spent working

  • 0

First question. Be gentle.

I’m working on software that tracks technicians’ time spent working on tasks. The software needs to be enhanced to recognize different billable rate multipliers based on the day of the week and the time of day. (For example, “Time and a half after 5 PM on weekdays.”)

The tech using the software is only required to log the date, his start time and his stop time (in hours and minutes). The software is expected to break the time entry into parts at the boundaries of when the rate multipliers change. A single time entry is not permitted to span multiple days.

Here is a partial sample of the rate table. The first-level array keys are the days of the week, obviously. The second-level array keys represent the time of the day when the new multiplier kicks in, and runs until the next sequential entry in the array. The array values are the multiplier for that time range.

[rateTable] => Array
    (
        [Monday] => Array
            (
                [00:00:00] => 1.5
                [08:00:00] => 1
                [17:00:00] => 1.5
                [23:59:59] => 1
            )

        [Tuesday] => Array
            (
                [00:00:00] => 1.5
                [08:00:00] => 1
                [17:00:00] => 1.5
                [23:59:59] => 1
            )
        ...
    )

In plain English, this represents a time-and-a-half rate from midnight to 8 am, regular rate from 8 to 5 pm, and time-and-a-half again from 5 till 11:59 pm. The time that these breaks occur may be arbitrary to the second and there can be an arbitrary number of them for each day. (This format is entirely negotiable, but my goal is to make it as easily human-readable as possible.)

As an example: a time entry logged on Monday from 15:00:00 (3 PM) to 21:00:00 (9 PM) would consist of 2 hours billed at 1x and 4 hours billed at 1.5x. It is also possible for a single time entry to span multiple breaks. Using the example rateTable above, a time entry from 6 AM to 9 PM would have 3 sub-ranges from 6-8 AM @ 1.5x, 8AM-5PM @ 1x, and 5-9 PM @ 1.5x. By contrast, it’s also possible that a time entry may only be from 08:15:00 to 08:30:00 and be entirely encompassed in the range of a single multiplier.

I could really use some help coding up some PHP (or at least devising an algorithm) that can take a day of the week, a start time and a stop time and parse into into the required subparts. It would be ideal to have the output be an array that consists of multiple entries for a (start,stop,multiplier) triplet. For the above example, the output would be:

[output] => Array
    (
        [0] => Array
            (
                [start] => 15:00:00
                [stop] => 17:00:00
                [multiplier] => 1
            )

        [1] => Array
            (
                [start] => 17:00:00
                [stop] => 21:00:00
                [multiplier] => 1.5
            )
    )

I just plain can’t wrap my head around the logic of splitting a single (start,stop) into (potentially) multiple subparts.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-14T21:19:49+00:00Added an answer on May 14, 2026 at 9:19 pm

    Eineki cracked the algorithm. The part missing from my attempts was having the start and the stop time available in each multiplier range. I value the density of data in my original rateTable, so I used the guts of Eineki’s convert() routine to take the table stored in config and add the stop times in. My code already auto-created (or filled in) a minimal rate table, guaranteeing that the rest of the code won’t choke or throw warning/errors, so I included that. I also condensed bill() and map_shift() together since in my mind the two don’t have any useful purpose without each other.

    <?php
    
    //-----------------------------------------------------------------------
    function CompactSliceData($start, $stop, $multiplier)
    // Used by the VerifyRateTable() to change the format of the multiplier table.
    {
        return compact('start', 'stop','multiplier');
    }
    
    //-----------------------------------------------------------------------
    function VerifyAndConvertRateTable($configRateTable)
    // The rate table must contain keyed elements for all 7 days of the week. 
    // Each subarray must contain at LEAST a single entry for '00:00:00' => 
    // 1 and '23:59:59' => 1. If the first entry does not start at midnight, 
    // a new element will be added to the array to represent this. If given 
    // an empty array, this function will auto-vivicate a "default" rate 
    // table where all time is billed at 1.0x.
    {
        $weekDays = array('Monday', 'Tuesday', 'Wednesday', 
                'Thursday', 'Friday', 'Saturday', 
                'Sunday',);  // Not very i18n friendly?     
    
        $newTable = array();
        foreach($weekDays as $day)
        {
            if( !array_key_exists($day, $configRateTable) 
                || !is_array($configRateTable[$day]) 
                || !array_key_exists('00:00:00', $configRateTable[$day]) )
            {
                $configRateTable[$day]['00:00:00'] = 1;
            }
    
            if( !array_key_exists($day, $configRateTable) 
                || !is_array($configRateTable[$day]) 
                || !array_key_exists('23:59:59', $configRateTable[$day]) )
            {
                $configRateTable[$day]['23:59:59'] = 1;
            }
    
            // Convert the provided table format to something we can work with internally.
            // Ref: http://stackoverflow.com/questions/2792048/slicing-a-time-range-into-parts
            $newTable[$day] = array_slice(
                    array_map(
                       'CompactSliceData',
                       array_keys($configRateTable[$day]),
                       array_keys(array_slice($configRateTable[$day],1)),
                       $configRateTable[$day]),
                    0,-1);
        }
        return $newTable;
    }
    
    //-----------------------------------------------------------------------
    function SliceTimeEntry($dayTable, $start, $stop)
    // Iterate through a day's table of rate slices and split the $start/$stop
    // into parts along the boundaries.
    // Ref: http://stackoverflow.com/questions/2792048/slicing-a-time-range-into-parts
    {
        $report = array();
        foreach($dayTable as $slice) 
        {
            if ($start < $slice['stop'] && $stop > $slice['start'])
            {
               $report[] = array(
                        'start'=> max($start, $slice['start']),
                        'stop' => min($stop, $slice['stop']),
                        'multiplier' => $slice['multiplier']
                    );
            }
        }
        return $report;
    }
    
    
    /* examples */
    $rateTable = array(
        'Monday' => array('00:00:00' => 1.5, '08:00:00' => 1, '17:00:00' => 1.5),
        'Tuesday' => array('00:00:00' => 1.5, '08:00:00' => 1, '17:00:00' => 1.5),
        'Wednesday' => array('00:00:00' => 1.5, '08:00:00' => 1, '17:00:00' => 1.5),
        'Thursday' => array('00:00:00' => 1.5, '08:00:00' => 1, '17:00:00' => 1.5),
        'Friday' => array('00:00:00' => 1.5, '08:00:00' => 1, '17:00:00' => 1.5),
        'Saturday' => array('00:00:00' => 1.5, '15:00:00' => 2),
        'Sunday' => array('00:00:00' => 1.5, '15:00:00' => 2),
    );
    
    $rateTable = VerifyAndConvertRateTable($rateTable);
    
    print_r(SliceTimeEntry($rateTable['Monday'],'08:05:00','18:05:00'));
    print_r(SliceTimeEntry($rateTable['Monday'],'08:05:00','12:00:00'));
    print_r(SliceTimeEntry($rateTable['Tuesday'],'07:15:00','19:30:00'));
    print_r(SliceTimeEntry($rateTable['Tuesday'],'07:15:00','17:00:00'));
    
    ?>
    

    Thanks everyone, especially Eineki.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 388k
  • Answers 388k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer I found the problem. I have been using "Telerik Extension… May 15, 2026 at 12:20 am
  • Editorial Team
    Editorial Team added an answer Assuming that you have NSTextFieldCell in your table (for other… May 15, 2026 at 12:20 am
  • Editorial Team
    Editorial Team added an answer Passing a reference would be less overhead than reinitializing a… May 15, 2026 at 12:20 am

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.