zomeruur erratum ?

Nu ik wat minder groggy ben dan deze nacht om 5u(zomertijd!), heb ik nog eens nagedacht over mijn script omdat ik niet zeker ben dat ik de zomertijd op de gepaste manier negeer.

De data die ik gebruik heeft uren waarop het zomeruur is toegepast. Bij 24 maart 2007 komt de zon op om 6:38 en om 25 maart 2007 om 7:35. Dat is bijna een uur verschil.

Stel nu dat ik samen met iemand elke morgen om 6u opsta en dat de zon opkomt om 7u (allebei reele tijd). Stel ook dat ik kies om zomertijd te negeren en die andere niet.

Op zaterdag 24 maart staan we allebei op om 6u en zitten samen 1u in het donker. Op zondag 25 maart sta ik op om 6u reele tijd en de andere om 5u reele tijd (want die heeft zijn klok 1u vooruit gedraaid en verliest een uur slaap).

Vanuit zijn perspectief sta ik 1u later op, dus om 7u zomertijd.

Hoe kan ik dat nu corrigeren ? De datatabel is opgesteld in zomertijd, dus vanuit het perspectief van die andere. Ik zie er dus uit als een luie slaapkop die 1u te lang slaapt. M.a.w., als ik de zomertijd negeer sta ik 1u later op in zomertijd.

Dit stukje code:

if($ignore_summertime and $list->{$i}->{summertime}) {
$realwakeup = $wakeup - 3600;
$realsleep = $sleep - 3600;


Moet dus worden:

if($ignore_summertime and $list->{$i}->{summertime}) {
$realwakeup = $wakeup + 3600;
$realsleep = $sleep + 3600;


En geeft dan volgende data:


04:00 - 20:00: extra verbruik met zomeruur = 5 day(s), 22 hour(s), 34 min(s), 0 sec(s)
04:15 - 20:15: extra verbruik met zomeruur = 5 day(s), 6 hour(s), 13 min(s), 0 sec(s)
04:30 - 20:30: extra verbruik met zomeruur = 4 day(s), 12 hour(s), 59 min(s), 0 sec(s)
04:45 - 20:45: extra verbruik met zomeruur = 3 day(s), 9 hour(s), 32 min(s), 0 sec(s)
05:00 - 21:00: extra verbruik met zomeruur = 1 day(s), 20 hour(s), 2 min(s), 0 sec(s)
05:15 - 21:15: uitgespaard verbruik met zomeruur = 0 day(s), 2 hour(s), 43 min(s), 0 sec(s)
05:30 - 21:30: uitgespaard verbruik met zomeruur = 2 day(s), 1 hour(s), 18 min(s), 0 sec(s)
05:45 - 21:45: uitgespaard verbruik met zomeruur = 3 day(s), 13 hour(s), 49 min(s), 0 sec(s)
06:00 - 22:00: uitgespaard verbruik met zomeruur = 4 day(s), 16 hour(s), 27 min(s), 0 sec(s)
06:15 - 22:15: uitgespaard verbruik met zomeruur = 5 day(s), 9 hour(s), 48 min(s), 0 sec(s)
06:30 - 22:30: uitgespaard verbruik met zomeruur = 6 day(s), 2 hour(s), 38 min(s), 0 sec(s)
06:45 - 22:45: uitgespaard verbruik met zomeruur = 6 day(s), 19 hour(s), 4 min(s), 0 sec(s)
07:00 - 23:00: uitgespaard verbruik met zomeruur = 7 day(s), 9 hour(s), 41 min(s), 0 sec(s)
07:15 - 23:15: uitgespaard verbruik met zomeruur = 7 day(s), 22 hour(s), 26 min(s), 0 sec(s)
07:30 - 23:30: uitgespaard verbruik met zomeruur = 8 day(s), 9 hour(s), 13 min(s), 0 sec(s)
07:45 - 23:45: uitgespaard verbruik met zomeruur = 8 day(s), 16 hour(s), 44 min(s), 0 sec(s)
08:00 - 00:00: uitgespaard verbruik met zomeruur = 8 day(s), 21 hour(s), 45 min(s), 0 sec(s)
08:15 - 00:15: uitgespaard verbruik met zomeruur = 9 day(s), 0 hour(s), 27 min(s), 0 sec(s)
08:30 - 00:30: uitgespaard verbruik met zomeruur = 9 day(s), 1 hour(s), 0 min(s), 0 sec(s)
08:45 - 00:45: uitgespaard verbruik met zomeruur = 9 day(s), 1 hour(s), 0 min(s), 0 sec(s)
09:00 - 01:00: uitgespaard verbruik met zomeruur = 9 day(s), 1 hour(s), 0 min(s), 0 sec(s)
09:15 - 01:15: uitgespaard verbruik met zomeruur = 9 day(s), 1 hour(s), 0 min(s), 0 sec(s)
09:30 - 01:30: uitgespaard verbruik met zomeruur = 9 day(s), 1 hour(s), 0 min(s), 0 sec(s)
09:45 - 01:45: uitgespaard verbruik met zomeruur = 9 day(s), 1 hour(s), 0 min(s), 0 sec(s)
10:00 - 02:00: uitgespaard verbruik met zomeruur = 9 day(s), 1 hour(s), 0 min(s), 0 sec(s)
10:15 - 02:15: uitgespaard verbruik met zomeruur = 9 day(s), 1 hour(s), 0 min(s), 0 sec(s)
10:30 - 02:30: uitgespaard verbruik met zomeruur = 9 day(s), 1 hour(s), 0 min(s), 0 sec(s)
10:45 - 02:45: uitgespaard verbruik met zomeruur = 9 day(s), 1 hour(s), 0 min(s), 0 sec(s)
11:00 - 03:00: uitgespaard verbruik met zomeruur = 9 day(s), 1 hour(s), 0 min(s), 0 sec(s)
11:15 - 03:15: uitgespaard verbruik met zomeruur = 9 day(s), 1 hour(s), 0 min(s), 0 sec(s)
11:30 - 03:30: uitgespaard verbruik met zomeruur = 9 day(s), 1 hour(s), 0 min(s), 0 sec(s)
11:45 - 03:45: uitgespaard verbruik met zomeruur = 9 day(s), 1 hour(s), 0 min(s), 0 sec(s)
12:00 - 04:00: uitgespaard verbruik met zomeruur = 9 day(s), 1 hour(s), 0 min(s), 0 sec(s)
12:15 - 04:15: uitgespaard verbruik met zomeruur = 9 day(s), 1 hour(s), 0 min(s), 0 sec(s)
12:30 - 04:30: uitgespaard verbruik met zomeruur = 9 day(s), 1 hour(s), 0 min(s), 0 sec(s)
12:45 - 04:45: uitgespaard verbruik met zomeruur = 9 day(s), 1 hour(s), 0 min(s), 0 sec(s)


Nieuwe code:

#!/usr/bin/perl

use Data::Dumper;

$ignore_summertime = $ARGV[0];
$opstatijd = $ARGV[1];
$slaaptijd = $ARGV[2];

sub datestr_to_sec {
my $str = shift;
my $h, $m;

if($str =~ /^(\d+):(\d+)$/) {
$h = $1 + 0;
$m = $2 + 0;
}

return ($h * 3600) + ($m * 60);
}

sub sec_to_read {
my $sec = shift;
my $d, $h, $m, $s;

$d = int($sec / 86400); $sec %= 86400;
$h = int($sec / 3600); $sec %= 3600;
$m = int($sec / 60); $sec %= 60;
$s = $sec;

return "$d day(s), $h hour(s), $m min(s), $s sec(s)";
}

$list = {};
$counter = 0;
$prev = -1;
$currentsummertime = 0;

$wakeup = datestr_to_sec($opstatijd);
$sleep = datestr_to_sec($slaaptijd);

while($line = ) {

chomp $line;
if($line =~ /(\d+) (\d+) (\d+) <\/td>(\d\d:\d\d) <\/td>(\d\d:\d\d) <\/td> (\d\d)\. <\/td>(\d\d:\d\d) <\/td>(\d\d:\d\d) <\/td><\/tr>/) {
my($day, $month, $year, $start, $end, $schem_duration, $schem_start, $schem_end) =
($1, $2, $3, $4, $5, $6, $7, $8);

$list->{$counter}->{day} = $day;
$list->{$counter}->{month} = $day;
$list->{$counter}->{year} = $day;
$list->{$counter}->{daytime} = "$year$month$day";
$list->{$counter}->{start_string} = $start;
$list->{$counter}->{start} = datestr_to_sec($start);
$list->{$counter}->{end_string} = $end;
$list->{$counter}->{end} = datestr_to_sec($end);
$list->{$counter}->{schem_duration} = $schem_duration * 60;
$list->{$counter}->{schem_start_string} = $schem_start;
$list->{$counter}->{schem_start} = datestr_to_sec($schem_start);
$list->{$counter}->{schem_end_string} = $schem_end;
$list->{$counter}->{schem_end} = datestr_to_sec($schem_end);

if($prev < 0) {
# we start in januari, which is winter time
$currentsummertime = 0;
} elsif($list->{$counter}->{start} - $prev > 50*60) {
# summer time
#print "Switched to summertime on $list->{$counter}->{daytime}\n";
$currentsummertime = 1;

} elsif($prev - $list->{$counter}->{start} > 50*60) {
# winter time
#print "Switched to wintertime on $list->{$counter}->{daytime}\n";
$currentsummertime = 0;
} else {

}
$list->{$counter}->{summertime} = $currentsummertime;
$prev = $list->{$counter}->{start};
$counter++;
}
}

#print Dumper($list);

# night
$blacksecs = 0;
# dawn
$greysecs = 0;

$realwakeup = $wakeup;
$realsleep = $sleep;

for($i = 0; $i < $counter; $i++) {
#print "$i $list->{$i}->{schem_start} sec $list->{$i}->{start} sec $list->{$i}->{end} sec $list->{$i}->{schem_end} sec drawday\n";

# simulate that summertime doesn't exist
if($ignore_summertime and $list->{$i}->{summertime}) {
$realwakeup = $wakeup + 3600;
$realsleep = $sleep + 3600;
} else {
$realwakeup = $wakeup;
$realsleep = $sleep;
}

# we wake up before dawn
if($realwakeup < $list->{$i}->{schem_start}) {
$blacksecs += ($list->{$i}->{schem_start} - $realwakeup);
}

# we wake up before sunlight
if($realwakeup < $list->{$i}->{start}) {
# are we awake before dawn ?
if($realwakeup < $list->{$i}->{schem_start}) {
$greysecs += $list->{$i}->{schem_duration};
} else {
# we woke up during dawn
$greysecs += $list->{$i}->{start} - $realwakeup;
}
}

# we go to realsleep when it's dark
if($realsleep > $list->{$i}->{schem_end}) {
$blacksecs += ($realsleep - $list->{$i}->{schem_end});
}

# we go to realsleep when the sun sets
if($realsleep > $list->{$i}->{end}) {
if($realsleep > $list->{$i}->{schem_end}) {
$greysecs += $list->{$i}->{schem_duration};
} else {
$greysecs += $realsleep - $list->{$i}->{end};
}
}
}

print "Seconds in grey: $greysecs ".sec_to_read($greysecs)."\n";
print "Seconds in black: $blacksecs ".sec_to_read($blacksecs)."\n";


En script om de bovenstaande output te genereren:

#!/bin/bash

for h in `seq 4 12`; do
for m in 0 15 30 45; do
startt=`printf "%02d:%02d" $h $m`
endt=`printf "%02d:%02d" $(($h+16)) $m`

greywith=`./zomeruur.pl 0 $startt $endt < zon_2007.html | grep grey | awk '{print $4}'`
greywithout=`./zomeruur.pl 1 $startt $endt < zon_2007.html | grep grey | awk '{print $4}'`
blackwith=`./zomeruur.pl 0 $startt $endt < zon_2007.html | grep black | awk '{print $4}'`
blackwithout=`./zomeruur.pl 1 $startt $endt < zon_2007.html | grep black | awk '{print $4}'`
# d = extra verbruik MET zomeruur
d=$((greywith + blackwith - greywithout - blackwithout))

echo -n "$startt - $endt: "
if [ $d -gt 0 ];
then
x=`./sec_to_read.pl $d`
echo " extra verbruik met zomeruur = $x";
else
d=$((-$d))
x=`./sec_to_read.pl $d`
echo " uitgespaard verbruik met zomeruur = $x";
fi
done
done


sec_to_read.pl script (om seconden naar iets leesbaar om te zetten):

#!/usr/bin/perl

sub sec_to_read {
my $sec = shift;
my $d, $h, $m, $s;

$d = int($sec / 86400); $sec %= 86400;
$h = int($sec / 3600); $sec %= 3600;
$m = int($sec / 60); $sec %= 60;
$s = $sec;

return "$d day(s), $h hour(s), $m min(s), $s sec(s)";
}

print sec_to_read($ARGV[0])."\n";