200 likes | 347 Views
Dates. Reinventing Them. Actions. Format – m/d/y add days subtract days Day of Week Julian day Difference Between two Dates. Format. sub get_format { my $format = shift; my (%date_pos, $dpack, $sep); my $dpack; if ($format =~ /^[ymd]+$/) { } else { }
E N D
Dates Reinventing Them
Actions • Format – m/d/y • add days • subtract days • Day of Week • Julian day • Difference Between two Dates
Format sub get_format { my $format = shift; my (%date_pos, $dpack, $sep); my $dpack; if ($format =~ /^[ymd]+$/) { } else { } return (\%date_pos, $dpack, $sep); }
yyyymmdd if ($format =~ /^[ymd]+$/) { if (length($format) == 3) { my @lst = split //, $format; foreach (@lst) { $date_pos{$_} = $ind++; my $num = $_ eq 'y' ? 4 : 2; $dpack .= " A$num "; } } my $cur = substr($format, 0, 1); }
M-d-y, y/d/m else { ($sep) = $format =~ /(\W+)/; my @lst = split /\Q$sep/, $format; my $ind = 0; foreach (@lst) { $date_pos{$_} = $ind++; } }
Format sub format_date { my ($date, $in, $out)= @_; my $res; my ($date_in, $pack_in, $sep_in) = get_format($in); my ($date_out, $pack_out, $sep_out) = get_format($out); my @lst; my ($y, $m, $d); @lst = $sep_in ? split /\Q$sep_in/, $date : unpack($pack_in, $date) ; $y = $lst[$$date_in{y}]; $m = $lst[$$date_in{m}]; $d = $lst[$$date_in{d}]; if ($sep_out) { } else { } return $res; }
Format with sep if ($sep_out) { my @lst; $lst[$$date_out{y}] = $y; $lst[$$date_out{m}] = $m; $lst[$$date_out{d}] = $d; $res = join $sep_out, @lst; }
yyymmdd else { my @lst; $lst[$$date_out{y}] = $y; $lst[$$date_out{m}] = sprintf("%02d",$m); $lst[$$date_out{d}] = sprintf("%02d",$d); $res = join "", @lst; }
Basics sub get_month_days { my $date = shift; my ($year, $month, $day) = unpack("A4 A2 A2", $date); my $days; my %mdays = ( '01' => 31, '03' => 31, '04' => 30, '05' => 31, '06' => 30, '07' => 31, '08' => 31, '09' => 30, '10' => 31, '11' => 30, '12' => 31 ); return $days if $days = $mdays{$month}; return 29 if $year % 400 == 0; return 28 if $year %100 == 0; return 29 if $year % 4 == 0; return 28; }
Next Month sub get_next { my ($year, $month) = @_; if ($$month ne '12') { $$month++; $$month = sprintf("%02d", $$month); } else { $$year++; $$month = '01'; } }
Prev Month sub get_previous { my ($year, $month) = @_; if ($$month ne '01') { $$month--; $$month = sprintf("%02d", $$month); } else { $$year--; $$month = '12'; } }
Add Days sub add_days { my ($date, $days) = @_; return if $date eq ''; my ($year, $month, $day) = unpack("A4 A2 A2", $date); my $mdays = get_month_days($date); my $rem_days = $mdays - $day; if ($days <= $rem_days) { $day += $days; return sprintf ("%04d%02d%02d", $year , $month , $day); } while ($days) { $days -= $rem_days; get_next(\$year, \$month); $mdays = get_month_days($year . $month . $day); if ($days <= $mdays) { $day = $days; return sprintf ("%04d%02d%02d", $year , $month , $day); } $rem_days = $mdays; } }
Add Days - Many while ($days) { $days -= $rem_days; get_next(\$year, \$month); $mdays = get_month_days($year . $month . $day); if ($days <= $mdays) { $day = $days; return sprintf ("%04d%02d%02d", $year , $month , $day); } $rem_days = $mdays; }
Day of Week (black magic) sub dow { my $date = shift; my ($y, $m, $d) = unpack("A4 A2 A2", $date); my $c = substr($y, 0, 2); $y = $y - 1 if $m < 3; $m = $m -2 if $m > 3; $m = $m + 10 if $m < 3; my $dow = ($d + int(2.6 * ($m) - 0.2) - 2*$c + $y + int(($y - $y % 4) / 4) + int(($c - $c % 4) / 4)) % 7; $dow = sprintf("%02d", $dow); return $dow; }
Julian Day sub julian_day_month { my ($year, $day) = @_; my ($month, $days, $last_days); $month = 0; while ($days < $day) { $month++; my $curd = sprintf ("%04d%02d%02d", $year, $month, 1); $last_days = $days; $days += get_month_days($curd); } my $diff = $day - $last_days; return ($diff, $month); }
Day Difference sub get_days_diff { my ($first, $sec) = @_; return 0 if $first == $sec; my $nmonth; my $nyear; my $diff_days; my ($y1, $m1, $d1) = unpack("A4 A2 A2", $first); my ($y2, $m2, $d2) = unpack("A4 A2 A2", $sec); if (($y1 == $y2) and ($m1 == $m2)) { return $d2 - $d1; } elsif ($y1 == $y2) { ## Same year - see next } else { ## Different Year } return $diff_days; }
Day Diff – Same Year elsif ($y1 == $y2) { my $curdate = "$y1$m1$d1"; my $mdays = get_month_days($curdate); $diff_days = $mdays - $d1; $nmonth = $m1; while ($nmonth < $m2) { $nmonth++; if ($nmonth == $m2) { $diff_days += $d2; last; } $curdate = sprintf("%04d%02d%02d", $y1, $nmonth, "01"); $diff_days += get_month_days($curdate); } }
Day Diff – Different Year else { my $curdate = "$y1$m1$d1"; my $mdays = get_month_days($curdate); $diff_days = $mdays - $d1; $nyear = $y1; $nmonth = $m1; while ($nmonth < 12) { ## biggest year } while ($nyear < $y2 -1) { ## years untill smallest } ## smallest year }
All Bigger Years while ($nmonth < 12) { $nmonth++; $curdate = sprintf("%04d%02d%02d", $y1, $nmonth, "01"); $diff_days += get_month_days($curdate); } while ($nyear < $y2 -1) { $nyear++; $nmonth = 0; while ($nmonth < 12) { $nmonth++; $curdate = sprintf("%04d%02d%02d", $nyear, $nmonth, "01"); $diff_days += get_month_days($curdate); } }
Smallest Year $nmonth = "00"; while ($nmonth < $m2) { $nmonth++; if ($nmonth == $m2) { $diff_days += $d2; last; } $curdate = sprintf("%04d%02d%02d", $y1, $nmonth, "01"); $diff_days += get_month_days($curdate); }