File Coverage

blib/lib/Tk/DatePick.pm
Criterion Covered Total %
statement 6 277 2.1
branch 0 102 0.0
condition 0 24 0.0
subroutine 2 26 7.6
pod n/a
total 8 429 1.8


line stmt bran cond sub pod time code
1             package Tk::DatePick;
2              
3 1     1   5751 use strict;
  1         3  
  1         29  
4 1     1   5 use warnings;
  1         3  
  1         3107  
5              
6             our $VERSION = '1.02';
7              
8             require Tk::Frame;
9             our @ISA = qw(Tk::Frame);
10              
11             Tk::Widget->Construct('DatePick');
12              
13             sub Populate
14             {
15 0     0     require Tk::Label;
16 0           require Tk::FireButton;
17 0           my ($cw,$args) = @_;
18 0           my $max = $args->{'-max'};
19 0           my $min = $args->{'-min'};
20 0           my $yeartype = $args->{'-yeartype'};
21 0           my $currdate = $args->{'-text'};
22 0           my $format = $args->{'-dateformat'};
23 0 0         $format = 0 unless defined $format;
24 0 0         if (defined $currdate)
  0 0          
25             {die "Invalid Date" unless isvaliddate($currdate,$format);}
26 0 0         $currdate = ourtoday($format) unless defined $currdate;
27 0 0         if (defined $yeartype)
28             {
29 0 0         if ($yeartype eq 'calyear')
  0            
30 0           {($min,$max) = calyear($currdate,$format);}
31             else {($min,$max) = finyear($currdate,$format);}
32             }
33 0           $cw->SUPER::Populate($args);
34 0           my $f = $cw->Frame(-relief => 'sunken',
35             -border => 1)->pack;
36 0           my $l = $f->Label(
37             -width => '16',
38             -text => $currdate,
39             )->pack(-side => 'top');
40 0           my $temp;
41 0           $cw->ConfigSpecs(
42             '-status' => ['METHOD'],
43             '-dateformat' => ['PASSIVE'],
44             '-max' => ['PASSIVE'],
45             '-min' => ['PASSIVE'],
46             '-yeartype' => ['PASSIVE'],
47             DEFAULT => [$l]);
48             my($button_1) = $f->FireButton (
49             -text => '<<<',
50             -command => sub
51             {
52 0     0     $currdate = addyear($currdate,-1,$format,$max,$min);
53 0           $l->configure(-text => $currdate);
54              
55             }
56 0           )->pack(-side => 'left');
57              
58             my($button_2) = $f->FireButton (
59             -text => '<<',
60             -command => sub
61             {
62 0     0     $currdate = addmonths($currdate,-1,$format,$max,$min);
63 0           $l->configure(-text => $currdate);
64             }
65 0           )->pack(-side => 'left');
66             my($button_3) = $f->FireButton (
67             -text => '<',
68             -command => sub
69             {
70 0     0     $currdate = adddays($currdate,-1,$format,$max,$min);
71 0           $l->configure(-text => $currdate);
72             }
73 0           )->pack(-side => 'left');
74             my($button_4) = $f->FireButton (
75             -text => '>',
76             -command => sub
77             {
78 0     0     $currdate = adddays($currdate,1,$format,$max,$min);
79 0           $l->configure(-text => $currdate);
80             }
81 0           )->pack(-side => 'left');
82             my($button_5) = $f->FireButton (
83             -text => '>>',
84             -command => sub
85             {
86 0     0     $currdate = addmonths($currdate,1,$format,$max,$min);
87 0           $l->configure(-text => $currdate);
88             }
89 0           )->pack(-side => 'left');
90             my($button_6) = $f->FireButton (
91             -text => '>>>',
92             -command => sub
93             {
94 0     0     $currdate = addyear($currdate,1,$format,$max,$min);
95 0           $l->configure(-text => $currdate);
96             }
97 0           )->pack(-side => 'left');
98 0           $cw->Advertise('but1' => $button_1);
99 0           $cw->Advertise('but2' => $button_2);
100 0           $cw->Advertise('but3' => $button_3);
101 0           $cw->Advertise('but4' => $button_4);
102 0           $cw->Advertise('but5' => $button_5);
103 0           $cw->Advertise('but6' => $button_6);
104 0           $cw->Delegates('state' => $button_1,$button_2,$button_3,
105             $button_4,$button_5,$button_6);
106             }
107             #-----------------------------------------------------------------
108             #to disable and enable the firebuttons
109             ######################################
110             sub status
111             {
112 0     0     my ($cw,$temp) = @_;
113 0           my $but1 = $cw->Subwidget('but1');
114 0           my $but2 = $cw->Subwidget('but2');
115 0           my $but3 = $cw->Subwidget('but3');
116 0           my $but4 = $cw->Subwidget('but4');
117 0           my $but5 = $cw->Subwidget('but5');
118 0           my $but6 = $cw->Subwidget('but6');
119 0           $but1->configure(-state => $temp);
120 0           $but2->configure(-state => $temp);
121 0           $but3->configure(-state => $temp);
122 0           $but4->configure(-state => $temp);
123 0           $but5->configure(-state => $temp);
124 0           $but6->configure(-state => $temp);
125             }
126             #--------------------------------------------------------------
127             #########################
128             #date manipulation stuff
129             ########################
130             my %monthnum = ('Jan',1,'Feb',2,'Mar',3,'Apr',4,'May',5,'Jun',6,
131             'Jul',7,'Aug',8,'Sep',9,'Oct',10,'Nov',11,'Dec',12);
132             my %monthname = (1,'Jan',2,'Feb',3,'Mar',4,'Apr',5,'May',
133             6,'Jun',7,'Jul',8,'Aug',9,'Sep',10,'Oct',11,'Nov',12,'Dec');
134              
135             #-----------------------------------------------------------
136             sub daysinmonth
137             {
138 0     0     my($yr,$mth) = @_;
139 0           my $days;
140 0 0         if ($mth == 1) {$days = 31;}
  0            
141 0 0 0       if (($mth == 2) and (($yr % 4) == 0)) {$days = 29;}
  0            
142 0 0 0       if (($mth == 2) and (($yr % 4) != 0)) {$days = 28;}
  0            
143 0 0         if ($mth == 3) {$days = 31;}
  0            
144 0 0         if ($mth == 4) {$days = 30;}
  0            
145 0 0         if ($mth == 5) {$days = 31;}
  0            
146 0 0         if ($mth == 6) {$days = 30;}
  0            
147 0 0         if ($mth == 7) {$days = 31;}
  0            
148 0 0         if ($mth == 8) {$days = 31;}
  0            
149 0 0         if ($mth == 9) {$days = 30;}
  0            
150 0 0         if ($mth == 10) {$days = 31;}
  0            
151 0 0         if ($mth == 11) {$days = 30;}
  0            
152 0 0         if ($mth == 12) {$days = 31;}
  0            
153 0           return $days;
154             } #end of daysinmonth
155             #------------------------------------------------------------
156             #scalar date returns the number of days since 1.1.1900.
157             sub scalardate
158             {
159 0     0     my($day,$month,$year,$i);
160 0           my $scdate = 365;
161 0           my ($date,$format) = @_;
162 0           ($day,$month,$year) = parsedate($date,$format);
163 0 0         die "Invalid Date" unless isvaliddate($date,$format);
164 0           $year = $year - 1900;
165 0           for ($i = 1; $i < $year; $i++)
166             {
167 0 0         if (($i % 4) == 0) {$scdate = $scdate + 366;}
  0            
  0            
168             else {$scdate = $scdate +365;}
169             }
170 0           for ($i = 1; $i < $month; $i++)
171             {
172 0           $scdate = $scdate + daysinmonth($year,$i);
173             }
174 0           $scdate = $scdate + $day;
175 0           return $scdate;
176             }# end of scalardate.
177             #-------------------------------------------------------------
178             sub daysinyear
179              
180             {
181 0     0     my $result;
182 0           my($yer) = @_;
183 0 0         if (($yer % 4) == 0) {$result = 366;}
  0            
  0            
184             else {$result = 365;}
185 0           return $result;
186             }
187             #-------------------------------------------------------------
188             #this converts a number into a date string
189              
190             sub datefromscalar
191              
192             {
193 0     0     my($inscale,$year,$i,$month,$day,$format,$date);
194 0           ($inscale, $format) = @_;
195 0           $inscale = $inscale - 365;
196 0           for ($i = 1; $inscale > daysinyear($i); $i++)
197             {
198 0           $inscale = $inscale - daysinyear($i);
199             }
200 0           $year = $i + 1900;
201 0           for ($i = 1; $inscale > daysinmonth($year,$i); $i++)
202             {
203 0           $inscale = $inscale - daysinmonth($year,$i);
204             }
205 0           $month = $i;
206 0           $day = $inscale;
207 0 0         if ($format == 0)
  0            
208 0           {$date = $day.'/'.$month.'/'.$year;}
209             else {$date = $month.'/'.$day.'/'.$year;}
210 0           return $date;
211             }# end of datefromscalar
212              
213             #---------------------------------------------------------------
214              
215             # this adds or subtracts days to a date and gives the result
216              
217             sub adddays
218             {
219 0     0     my($date,$addition,$format,$max,$min) = @_;
220 0           my ($mx,$mn,$newdate);
221 0 0         if (defined $max)
222             {
223 0           $mx = scalardate($max, $format);
224             }
225             else
226             {
227 0           $mx = scalardate('31/12/2095',0);
228             }
229 0 0         if (defined $min)
230             {
231 0           $mn = scalardate($min, $format);
232             }
233             else
234             {
235 0           $mn = scalardate('1/1/1905',0);
236             }
237 0           my $temp = scalardate($date,$format) + $addition;
238 0 0 0       if (($temp > $mx)or ($temp < $mn))
  0            
239 0           {$newdate = $date}
240             else
241             {$newdate = datefromscalar($temp,$format);}
242 0           return $newdate;
243             }#end of adddays
244             #--------------------------------------------------------------
245              
246             #this adds or subtracts months
247             sub addmonth
248             {
249 0     0     my($month,$adden,$mm,$newmonth);
250 0           $month = $_[0];
251 0           $adden = $_[1];
252 0           $mm = $monthnum{$month};
253 0           $mm = ($mm + $adden) % 12;
254 0 0         if ($mm <= 0){$mm = $mm + 12;}
  0            
255 0           $newmonth = $monthname{$mm};
256 0           return $newmonth;
257             }#end of addmonth
258             #--------------------------------------------------------------
259             #this adds a years to a date
260             sub addyear
261             {
262 0     0     my($inyear,$years,$format,$max,$min) = @_;
263 0           my ($mx,$mn,$total,$i,$outyear);
264 0 0         if (defined $max)
265             {
266 0           $mx = scalardate($max, $format);
267             }
268             else
269             {
270 0           $mx = scalardate('31/12/2095',0);
271             }
272 0 0         if (defined $min)
273             {
274 0           $mn = scalardate($min, $format);
275             }
276             else
277             {
278 0           $mn = scalardate('1/1/1905',0);
279             }
280 0           my ($day,$mth,$yr) = parsedate($inyear,$format);
281 0           $total = scalardate($inyear,$format);
282 0 0         if ($years > 0)
283             {
284 0           for ($i=1;$i <= $years;$i++)
285             {
286 0 0         if ($mth > 2)
  0            
287 0           {$total += daysinyear($yr+$i);}
288             else
289             {$total += daysinyear($yr+$i-1);}
290             }
291             }#end of if
292             else
293             {
294 0           for ($i=$years;$i < 0;$i++)
295             {
296 0 0         if ($mth > 2)
  0            
297 0           {$total -= daysinyear($yr+$i+1);}
298             else
299             {$total -= daysinyear($yr+$i+4);}
300             }
301             }#end of else
302 0 0 0       if (($total > $mx)or ($total < $mn))
  0            
303 0           {$outyear = $inyear;}
304             else
305             {$outyear = datefromscalar($total,$format);}
306 0           return $outyear;
307             }#end of addyear
308             #---------------------------------------------------------------
309             #this adds months to a date
310             sub addmonths
311             {
312 0     0     my($inyear,$months,$format,$max,$min) = @_;
313 0           my ($mx,$mn,$total,$i,$outyear);
314 0 0         if (defined $max)
315             {
316 0           $mx = scalardate($max, $format);
317             }
318             else
319             {
320 0           $mx = scalardate('31/12/2095',0);
321             }
322 0 0         if (defined $min)
323             {
324 0           $mn = scalardate($min, $format);
325             }
326             else
327             {
328 0           $mn = scalardate('1/1/1905',0);
329             }
330 0           my ($day,$mth,$yr) = parsedate($inyear,$format);
331 0           $total = scalardate($inyear,$format);
332 0 0         if ($months > 0)
333             {
334 0           for ($i=1;$i <= $months;$i++)
335             {
336 0           $total += daysinmonth($yr,$mth);
337 0 0         if ($mth == 12) {$mth = 1;++$yr;}
  0            
  0            
  0            
338             else {++$mth}
339             }
340             }#end of if
341             else
342             {
343 0 0         if ($mth == 1) {$mth = 12;--$yr;}
  0            
  0            
  0            
344             else {--$mth;}
345 0           for ($i=$months;$i < 0;$i++)
346             {
347 0           $total -= daysinmonth($yr,$mth);
348 0 0         if ($mth == 1) {$mth = 12;--$yr;}
  0            
  0            
  0            
349             else {--$mth;}
350             }
351             }#end of else
352 0 0 0       if (($total > $mx) or ($total < $mn))
  0            
353 0           {$outyear = $inyear;}
354             else
355             {$outyear = datefromscalar($total,$format);}
356 0           return $outyear;
357             }#end of addmonth
358             #---------------------------------------------------------------
359             # this gives the days between two dates
360              
361             sub datedif
362             {
363 0     0     my($date1,$date2) = @_;
364 0           my $difference = scalardate($date1) - scalardate($date2);
365 0           return $difference;
366             } # end of datedif
367             #---------------------------------------------------------------
368             # this compares two dates
369              
370             sub datecomp
371             {
372 0     0     my $result;
373 0           my($date1,$date2) = @_;
374 0 0         if (datedif($date1,$date2) == 0){$result = 0;}
  0 0          
  0            
375 0           elsif (datedif($date1,$date2) < 0){$result = -1;}
376             else {$result = 1;}
377 0           return $result;
378             } # end of datedcomp
379             #---------------------------------------------------------------
380             sub calyear #gives the begining and end of the calendar year
381             {
382 0     0     my ($date,$format) = @_;
383 0           my ($begin,$end);
384 0           my ($day,$month,$year) = parsedate($date,$format);
385 0 0         if ($format == 0)
386             {
387 0           $begin = '1/1/'.$year;
388 0           $end = '31/12/'.$year;
389             }
390             else
391             {
392 0           $begin = '1/1/'.$year;
393 0           $end = '12/31/'.$year;
394             }
395 0           return ($begin,$end);
396             }#end of calyear
397              
398             #-------------------------------------------------------
399             sub finyear #gives the begining and end of the financial year
400             {
401 0     0     my ($date,$format) = @_;
402 0           my ($begin,$end,$begyear,$endyear);
403 0           my ($day,$month,$year) = parsedate($date,$format);
404 0 0         if ($month < 4)
405             {
406 0           $begyear = $year-1;
407 0           $endyear = $year;
408             }
409             else
410             {
411 0           $begyear = $year;
412 0           $endyear = $year+1;
413             }
414 0 0         if ($format == 0)
415             {
416 0           $begin = '1/4/'.$begyear;
417 0           $end = '31/3/'.$endyear;
418             }
419             else
420             {
421 0           $begin = '4/1/'.$begyear;
422 0           $end = '3/31/'.$endyear;
423             }
424 0           return ($begin,$end);
425             }#end of finyear
426              
427             #-------------------------------------------------------
428             sub parsedate #returns day, month, year from datestring
429             {
430 0     0     my ($date,$format) = @_;
431 0           my ($day,$month,$year);
432 0           my @nut = split(/\D/,$date,4);
433 0 0         if ($format == 0)
434             {
435 0           $day = $nut[0];
436 0           $month = $nut[1];
437             }
438             else
439             {
440 0           $day = $nut[1];
441 0           $month = $nut[0];
442             }
443 0           $year = $nut[2];
444 0           return ($day,$month,$year);
445             } #end of parsedate
446              
447             #-----------------------------------------------------------
448             sub ourtoday #gives the current system date
449             {
450 0     0     my $format = $_[0];
451 0           my @ar = localtime;
452 0           my $day = $ar[3];
453 0           my $month = $ar[4]+1;
454 0           my $year = $ar[5] + 1900;
455 0           my $date;
456 0 0         if ($format == 0)
  0            
457 0           {$date = $day.'/'.$month.'/'.$year;}
458             else
459             {$date = $month.'/'.$day.'/'.$year;}
460 0           return $date;
461             }
462             #---------------------------------------------------------------
463             #this converts unix dates to our dates
464              
465             sub unixtodate
466             {
467 0     0     my($unixdate,$dd,$mm,$yy,$format,$ourdate);
468 0           ($unixdate, $format) = @_;
469 0           my @nut = split(/\s+/,$unixdate,7);
470 0           $dd = $nut[2];
471 0           $yy = $nut[5];
472 0           $mm = $monthnum{$nut[1]};
473 0 0         if ($format == 0)
  0            
474 0           {$ourdate = $dd.'/'.$mm.'/'.$yy;}
475             else
476             {$ourdate = $mm.'/'.$dd.'/'.$yy;}
477 0           return $ourdate;
478             }# end of unixtodate
479             #---------------------------------------------------------------
480              
481             sub isvaliddate
482             {
483 0     0     my $valid = 1;
484 0           my ($date,$format) = @_;
485 0           my ($day,$month,$year) = parsedate($date,$format);
486 0 0 0       if (($month < 1) or ($month > 12))
  0            
487             {$valid = 0;}
488 0 0 0       if (($year < 1901) or ($year > 2099))
  0            
489             {$valid = 0;}
490 0 0 0       if (($day < 1) or ($day > daysinmonth($year,$month)))
  0            
491             {$valid =0;}
492 0           return $valid;
493             }
494             #---------------------------------------------------------------
495             1;
496              
497              
498              
499             1;
500             __END__