File Coverage

blib/lib/Mail/Message/Field/Date.pm
Criterion Covered Total %
statement 27 42 64.2
branch 7 20 35.0
condition 5 8 62.5
subroutine 7 10 70.0
pod 5 5 100.0
total 51 85 60.0


line stmt bran cond sub pod time code
1             # This code is part of Perl distribution Mail-Message version 4.04.
2             # The POD got stripped from this file by OODoc version 3.06.
3             # For contributors see file ChangeLog.
4              
5             # This software is copyright (c) 2001-2026 by Mark Overmeer.
6              
7             # This is free software; you can redistribute it and/or modify it under
8             # the same terms as the Perl 5 programming language system itself.
9             # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later
10              
11              
12             package Mail::Message::Field::Date;{
13             our $VERSION = '4.04';
14             }
15              
16 28     28   105153 use parent 'Mail::Message::Field::Structured';
  28         413  
  28         283  
17              
18 28     28   2854 use warnings;
  28         77  
  28         1921  
19 28     28   182 use strict;
  28         68  
  28         4157  
20              
21 28     28   177 use Log::Report 'mail-message', import => [ qw/__x error/ ];
  28         64  
  28         330  
22              
23 28     28   6490 use POSIX qw/mktime tzset/;
  28         71  
  28         333  
24              
25             #--------------------
26              
27             my $dayname = qr/Mon|Tue|Wed|Thu|Fri|Sat|Sun/;
28             my @months = qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/;
29             my %monthnr; { my $i; $monthnr{$_} = ++$i for @months }
30             my %tz = qw/
31             EDT -0400 EST -0500 CDT -0500 CST -0600
32             MDT -0600 MST -0700 PDT -0700 PST -0800
33             UT +0000 GMT +0000/;
34              
35             sub parse($)
36 5     5 1 8 { my ($self, $string) = @_;
37              
38 5 50       334 my ($dn, $d, $mon, $y, $h, $min, $s, $z) = $string =~ m/
39             ^ \s*
40             (?: ($dayname) \s* \, \s* )? # dayname (optional)
41             ( 0?[1-9] | [12][0-9] | 3[01] ) \s+ # day
42             ( [A-Z][a-z][a-z]|[0-9][0-9] ) \s+ # month
43             ( (?: 19 | 20 | ) [0-9][0-9] ) \s+ # year
44             ( [0-1]?[0-9] | 2[0-3] ) \s* # hour
45             [:.] ( [0-5][0-9] ) \s* # minute
46             (?: [:.] ( [0-5][0-9] ) )? \s* # second (optional)
47             ( [+-][0-9]{4} | [A-Z]+ )? # zone
48             # optionally followed by trash
49             /x or return undef;
50              
51 5   100     16 $dn //= '';
52 5         11 $dn =~ s/\s+//g;
53 5 50       9 $mon = $months[$mon-1] if $mon =~ /[0-9]+/; # Broken mail clients
54              
55 5 50       12 $y += 2000 if $y < 50;
56 5 50       8 $y += 1900 if $y < 100;
57              
58 5   50     9 $z ||= '-0000';
59 5 50 0     7 $z = $tz{$z} || '-0000' if $z =~ m/[A-Z]/;
60              
61 5 100 100     40 $self->{MMFD_date} = sprintf "%s%02d %s %04d %02d:%02d:%02d %s",
62             (length $dn ? "$dn, " : ''), $d, $mon, $y, $h, $min, $s // 0, $z;
63              
64 5         9 $self;
65             }
66              
67 0     0 1 0 sub produceBody() { $_[0]->{MMFD_date} }
68              
69             #--------------------
70              
71             sub addAttribute($;@)
72 0     0 1 0 { my $self = shift;
73 0         0 error __x"no attributes for date fields.";
74             }
75              
76              
77 5     5 1 36 sub date() { $_[0]->{MMFD_date} }
78              
79              
80             sub time()
81 0 0   0 1   { my $date = shift->date or return;
82 0           my ($d, $mon, $y, $h, $min, $s, $z) = $date =~ m/
83             ^ (?:\w\w\w\,\s+)? (\d\d)\s+(\w+)\s+(\d\d\d\d) \s+ (\d\d)\:(\d\d)\:(\d\d) \s+ ([+-]\d\d\d\d)? \s* $
84             /x;
85              
86 0           my $oldtz = $ENV{TZ};
87 0           $ENV{TZ} = 'UTC';
88 0           tzset;
89 0           my $timestamp = mktime $s, $min, $h, $d, $monthnr{$mon}-1, $y-1900;
90 0 0         if(defined $oldtz) { $ENV{TZ} = $oldtz } else { delete $ENV{TZ} }
  0            
  0            
91 0           tzset;
92              
93 0 0         $timestamp += ($1 eq '-' ? 1 : -1) * ($2*3600 + $3*60)
    0          
94             if $z =~ m/^([+-])(\d\d)(\d\d)$/;
95 0           $timestamp;
96             }
97              
98             #--------------------
99              
100             1;