use warnings; use strict; use feature 'say'; use DateTime; # this is a prototype of a light timer my $on_at = '18:00'; # lights on my $on_time = 12; # hours on for my $off_time; my $on = 0; # light is on bool my $t = time; my $count = 0; # iter count my $done = 20000; # num iterations # dt objects my ($t1, $on_at_dt, $off_at_dt) = init_time($on_at, $on_time); while (1){ # on if ($t1 > $on_at_dt && ! $on){ # light is not on, and it's time $on = 1; say "\non: $t1"; } # off if ($t1 > $off_at_dt && $on){ # light's out time $on = 0; say "off: $t1"; $on_at_dt = set_on_timer( $t1, $on_at_dt, $on_at ); $off_at_dt = set_off_timer( $on_at_dt, $off_at_dt, $on_time ); } # expedite the current time for testing $t1->add(seconds => 30); $count++; last if $count == $done; } sub init_time { my ($on_at, $on_time) = @_; my $t1 = DateTime->now; $t1->set_time_zone('local'); my $on_at_dt = $t1->clone; $on_at_dt->set_hour( (split(/:/, $on_at))[0] ); $on_at_dt->set_minute( (split(/:/, $on_at))[1] ); my $off_at_dt = $on_at_dt->clone; $off_at_dt->add(hours => $on_time); return ($t1, $on_at_dt, $off_at_dt); } sub set_off_timer { my ($on_dt, $off_dt, $on_time) = @_; $off_dt = $on_dt->clone; $off_dt->add(hours => $on_time); return $off_dt; } sub set_on_timer { my ($t1, $dt, $on_at) = @_; $dt = $t1->clone; $dt->set_second(0); $dt->set_hour((split(/:/, $on_at))[0]); $dt->set_minute((split(/:/, $on_at))[1]); return $dt; }