package PubMed::Dates; use strict; use warnings; use Carp qw(confess); use Date::Parse; use Date::Format; use Date::Calc; use PubMed::Paths; use PubMed::Files; my $seconds_in_a_day=60*60*24; my $seconds_in_a_week=7*$seconds_in_a_day; my $format='%Y-%m-%d'; our $month_number; $month_number->{'Jan'}='01'; $month_number->{'Feb'}='02'; $month_number->{'Mar'}='03'; $month_number->{'Apr'}='04'; $month_number->{'May'}='05'; $month_number->{'Jun'}='06'; $month_number->{'Jun'}='06'; $month_number->{'Jul'}='07'; $month_number->{'Aug'}='08'; $month_number->{'Sep'}='09'; $month_number->{'Oct'}='10'; $month_number->{'Nov'}='11'; $month_number->{'Dec'}='12'; $month_number->{'JAN'}='01'; $month_number->{'FEB'}='02'; $month_number->{'MAR'}='03'; $month_number->{'APR'}='04'; $month_number->{'MAY'}='05'; $month_number->{'JUN'}='06'; $month_number->{'JUN'}='06'; $month_number->{'JUL'}='07'; $month_number->{'AUG'}='08'; $month_number->{'SEP'}='09'; $month_number->{'OCT'}='10'; $month_number->{'NOV'}='11'; $month_number->{'DEC'}='12'; $month_number->{'JAn'}='01'; $month_number->{'FEb'}='02'; $month_number->{'MAr'}='03'; $month_number->{'APr'}='04'; $month_number->{'MAy'}='05'; $month_number->{'JUn'}='06'; $month_number->{'JUn'}='06'; $month_number->{'JUl'}='07'; $month_number->{'AUg'}='08'; $month_number->{'SEp'}='09'; $month_number->{'OCt'}='10'; $month_number->{'NOv'}='11'; $month_number->{'N0v'}='11'; $month_number->{'DEc'}='12'; $month_number->{'jan'}='01'; $month_number->{'feb'}='02'; $month_number->{'mar'}='03'; $month_number->{'apr'}='04'; $month_number->{'may'}='05'; $month_number->{'jun'}='06'; $month_number->{'jun'}='06'; $month_number->{'jul'}='07'; $month_number->{'aug'}='08'; $month_number->{'sep'}='09'; $month_number->{'oct'}='10'; $month_number->{'nov'}='11'; $month_number->{'dec'}='12'; $month_number->{'Oc'}='10'; $month_number->{'Oktober'}='10'; $month_number->{'Ene'}='01'; our $seasons_date; $seasons_date->{'Spring'}="03-21"; $seasons_date->{'Spr'}="03-21"; $seasons_date->{'SPR'}="03-21"; $seasons_date->{'Summer'}="06-21"; $seasons_date->{'Fall'} ="09-21"; $seasons_date->{'Fall/Winter'} ="09-21"; $seasons_date->{'Autumn'}="09-21"; $seasons_date->{'Winter'}="12-21"; $seasons_date->{'spring'}="03-21"; $seasons_date->{'summer'}="06-21"; $seasons_date->{'fall'} ="09-21"; $seasons_date->{'autumn'}="09-21"; $seasons_date->{'winter'}="12-21"; $seasons_date->{'SPRING'}="03-21"; $seasons_date->{'SUMMER'}="06-21"; $seasons_date->{'FALL'} ="09-21"; $seasons_date->{'AUTUMN'}="09-21"; $seasons_date->{'WINTER'}="12-21"; $seasons_date->{'SUM'}="06-21"; sub this_year { return time2str('%Y',time); } sub get_past_weeks_from_date { my $number=shift // ''; my $start_date=shift // ''; my $dates=[]; if(not $number=~m|^\d+|) { confess "I need a different number than '$number'."; } ## we never look at today's date if(not $number > 0) { return $dates; } my $start=0; if($start_date) { $start=&get_time_on_date($start_date); ## to start from the given day $start+=$seconds_in_a_day; } else { $start=time(); } my $count=0; while($number>0) { my $time=$start - $number * $seconds_in_a_week; $dates->[$count++]=time2str($format,$time); $number--; } return $dates; } sub is_before { my $d1=shift; my $d2=shift; return $d1 cmp $d2; } sub get_time_on_date { my $date=shift; my $do_date="$PubMed::Paths::date -d '$date 12:00'"; my $date_written=`$do_date`; chomp $date_written; my $time=Date::Parse::str2time($date_written); return $time; } sub date_file { my $file=shift // confess "I need a file here."; my $time=&PubMed::Files::mtime($file); my $date=time2str("%Y-%m-%d", $time); return $date; } sub get_past_dates_from_number { my $number=shift // ''; my $start_date=shift // ''; my $dates=[]; if(not $number=~m|^\d+|) { confess "I need a different number than '$number'."; } ## we never look at today's date if(not $number > 0) { return $dates; } my $start=0; if($start_date) { $start=&get_time_on_date($start_date); ## to start from the given day $start+=$seconds_in_a_day; } else { $start=time(); } my $count=0; while($number>0) { my $time=$start - $number * $seconds_in_a_day; $dates->[$count++]=time2str($format,$time); $number--; } return $dates; } sub today { my $time=shift // time; my $date=time2str("%Y-%m-%d", $time); return $date; } sub yesterday { my $date=`$PubMed::Paths::date -I -d 'yesterday'`; chomp $date; return $date; } ## prepare the date if data sub make_touch_for_date { my $date=shift; my $string="$date 12:00"; my $time=str2time($string) or confess "I think you gave me invalid date '$date'"; my $touch_date=File::Touch->new(mtime_only=>1,mtime=>$time); return $touch_date; } ## later date come second sub diff_dates { my $d1=shift; my $d2=shift; ## construct containing the parsed dates my $d; my $count=0; foreach my $in ($d1,$d2) { $in=~m|^(\d{4})-(\d{2})-(\d{2})$| or confess "bad date '$in'."; $d->[$count]->[0]=$1; $d->[$count]->[1]=$2; $d->[$count]->[2]=$3; $count++; } ## make sure we capture an invalid date my $delta; eval { $delta=Date::Calc::Delta_Days(@{$d->[0]},@{$d->[1]}); }; if(not defined($delta)) { confess "I could not compute the difference between $d1 and $d2"; } return $delta; } sub split_date { my $date=shift; my $year=substr($date,0,4); my $month=substr($date,5,2); my $day=substr($date,8,2); return ($year,$month,$day); } sub is_date { my $date=shift // confess "I need a date here."; ## by http://umbraco.slu-art.phosdev.se/en/contact/staff/johan-soedercrantz/ if($date=~m/^[0-9]{4}-(((0[13578]|(10|12))-(0[1-9]|[1-2][0-9]|3[0-1]))|(02-(0[1-9]|[1-2][0-9]))|((0[469]|11)-(0[1-9]|[1-2][0-9]|30)))$/) { return 1; } return 0; } sub days_ago { my $d=shift // confess "I need a date here."; my $ago=shift // confess "I need an integer here."; my ($year,$month,$day) = &split_date($d); ($year,$month,$day) = &Date::Calc::Add_Delta_Days($year,$month,$day,-$ago); if(length($month)==1) { $month="0$month"; } if(length($day)==1) { $day="0$day"; } my $date="$year-$month-$day"; return $date; } sub days_in_the_last_years { my $years_ago=shift // confess "I need a number here."; my $today=&today(); my $year=substr($today,0,4); my $rest=substr($today,4); my $year_ago=$year-$years_ago; my $days=&diff_dates($year_ago.$rest,$today); return $days; } 1;