The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.


Time::WorkHours - proportional shift DateTime to a work hours and few work hours routines


    # our work hours is from 02:00 until 07:00
    my $wh = Time::WorkHours->new(
        work_interval_start => '02h',
        work_interval       => '5h',    # or 5*60
    # shift given date to our work hours
    my $new_datetime = $wh->shift_to_work_time(DateTime->new(
        'hour'   => 14,
        'minute' => 32,
        # ... what ever month, year, day


Purpouse of this module is to equaly distribute tasks that are comming through the whole day into certain day interval.

Or just move comming request to the start of work hours.

For example imagine you want to process smoke tests only in the idle server hours - in the night. But the CPAN modules are comming through all day. You can note down the modules as they are comming and set the processing time to $wh->shift_to_work_time() so that it will not take the processing time when the server has to do it's "real" job.





Object constructor. Pass two mandatory arguments. work_interval_start and work_interval.

work_interval_start is the minute (or hour) when the work hours start.

work_interval is how many minutes (or hours) does the work interval last.

Both can be passed as a number in that case must represent minutes or as a string with numbers and 'h' at the end representing the value in hours.


    $wh = Time::WorkHours->new(
        work_interval_start => '2h',  # or 120
        work_interval       => 180,   # or '3h'

Work interval starts at 02:00 and lasts for 3 hours.


Return nearest DateTime when the work time starts. If inside the work interval then returns start datetime of this interval.

If argument not passed the default is DateTime->now.


Same as work_start but will always return DateTime in the future.


Returns nearest end of the work time.

If argument not passed the default is DateTime->now.


Return true/false if the $datetime lies within work hours.

If argument not passed the default is DateTime->now.


Takes the $date and moves it to the neares work time interval. The shift is calculated proportionaly so that the time shifts are distributed in the work hour interval in the same order as they occure in 24h interval.


    my $wh = Time::WorkHours->new(
        work_interval_start => '22h',
        work_interval       => '4h',
    my $new_datetime = $wh->shift_to_work_time(DateTime->new(
        'day'    => 5,
        'hour'   => 14,
        'minute' => 00,
        # ... what ever month, year

Will shift to next day to 00:00 as 14:00 is just in the middle of 02:00 - (22:00) - 02:00 interval so it's shifted to the middle of 22:00 - 02:00 work hours.

If the DateTime will be at 01:59 (last minute of the work interval) there will be no shift.

If the DateTime will be at 02:00 (first non work minute) the shift will be to 22:00.

If argument not passed the default is DateTime->now.


Return number of minute in the day when the work interval starts.


Return for how many minutes does the work interval lasts.


Jozef Kutej


Copyright 2008 Jozef Kutej, all rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.