To construct a local time, you need to use
Time::Piece::localtime->strptime(...)
rather than
Time::Piece->strptime(...)
So,
use Time::Piece qw( localtime );
my $tp = localtime->strptime("$ARGV[0]M", "%m/%d/%y %I:%M:%S%p");
my $is_dst = ( localtime($tp->epoch) )[8];
say $is_dst ? 1 : 0;
Output:
$ ./a '6/31/09 08:40:00A'
1
$ ./a '12/31/09 08:40:00A'
0
Note that your timestamp format is ambiguous. In a place that uses DST, there is one hour a year for which it will return the wrong result.
About the problem in the comments,
use strict;
use warnings;
use feature qw( say );
use DateTime::Format::Strptime qw( );
my $format = DateTime::Format::Strptime->new(
pattern => '%m/%d/%y %I:%M:%S%p %Z',
locale => 'en',
zone_map => { CST => '-0600', CDT => '-0500' }, # Handle non-standard time zone names.
time_zone => 'America/Chicago', # Optional. Convert result to this tz.
strict => 1,
on_error => 'croak',
);
while (<DATA>) {
chomp;
my $dt = $format->parse_datetime($_);
my $epoch = $dt->epoch;
my $local_dt_str = $dt->strftime("%Y-%m-%dT%H:%M:%S%z");
$dt->set_time_zone('UTC');
my $utc_dt_str = $dt->strftime("%Y-%m-%dT%H:%M:%SZ");
say "$epoch $local_dt_str $utc_dt_str";
}
__DATA__
11/03/19 01:00:00AM CDT
11/03/19 01:59:58AM CDT
11/03/19 01:59:59AM CDT
11/03/19 01:00:00AM CST
11/03/19 01:00:01AM CST
11/03/19 01:59:59AM CST
Output:
1572760800 2019-11-03T01:00:00-0500 2019-11-03T06:00:00Z
1572764398 2019-11-03T01:59:58-0500 2019-11-03T06:59:58Z
1572764399 2019-11-03T01:59:59-0500 2019-11-03T06:59:59Z
1572764400 2019-11-03T01:00:00-0600 2019-11-03T07:00:00Z
1572764401 2019-11-03T01:00:01-0600 2019-11-03T07:00:01Z
1572767999 2019-11-03T01:59:59-0600 2019-11-03T07:59:59Z
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…