The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#!/usr/bin/perl

use strict;
use warnings;

BEGIN {
    # Windows can't change timezone inside Perl script
    if (($ENV{TZ}||'') ne 'GMT') {
        $ENV{TZ} = 'GMT';
        exec $^X, (map { "-I\"$_\"" } @INC), $0;
    };
}

use Carp ();
use File::Spec;
use Time::Local;

$SIG{__WARN__} = sub { local $Carp::CarpLevel = 1; Carp::confess("Warning: ", @_) };

use Test::More tests => 227;

BEGIN { use_ok 'POSIX::strftime::GNU'; }
BEGIN { use_ok 'POSIX', qw( strftime ); }

POSIX::setlocale(&POSIX::LC_TIME, 'C');

my %format = (
    a      => 'Sun',
    '^a'   => 'SUN',
    '^#a'  => 'SUN',
    '#a'   => 'SUN',
    '#^a'  => 'SUN',
    '012a' => '000000000Sun',
    '_012a' => '000000000Sun',
    '12a'  => '         Sun',
    '#12a' => '         SUN',
    '^#12a' => '         SUN',
    '-12a' => '         Sun',
    '_^#12a' => '         SUN',
    '^_#12a' => '         SUN',
    '^#_12a' => '         SUN',
    '^0#_12a' => '         SUN',
    '^_0#12a' => '000000000SUN',
    '^-_0#12a' => '000000000SUN',
    A      => 'Sunday',
    '^A'   => 'SUNDAY',
    '#A'   => 'SUNDAY',
    '12A'  => '      Sunday',
    b      => 'Jul',
    '^b'   => 'JUL',
    '#b'   => 'JUL',
    '12b'  => '         Jul',
    B      => 'July',
    '^B'   => 'JULY',
    '#B'   => 'JULY',
    '12B'  => '        July',
    C      => '20',
    '^C'   => '20',
    '^#C'  => '20',
    '#C'   => '20',
    '#^C'  => '20',
    '_#^C'  => '20',
    '12C'  => '000000000020',
    '_12C' => '          20',
    '-12C' => '20',
    '^#12C' => '000000000020',
    '_^#12C' => '          20',
    '^_#12C' => '          20',
    '^#_12C' => '          20',
    d      => '06',
    '12d'  => '000000000006',
    '_12d' => '           6',
    '-12d'  => '6',
    D      => '07/06/08',
    '12D'  => '    07/06/08',
    e      => ' 6',
    '12e'  => '           6',
    '-12e' => '6',
    EC     => '20',
    '12EC' => '000000000020',
    '_12EC' => '          20',
    '-12EC' => '20',
    Ex     => '07/06/08',
    EX     => '21:03:54',
    EY     => '2008',
    Ey     => '08',
    F      => '2008-07-06',
    '12F'  => '  2008-07-06',
    '-12F' => '  2008-07-06',
    G      => '2008',
    '12G'  => '000000002008',
    '_12G' => '        2008',
    '-12G' => '2008',
    g      => '08',
    '12g'  => '000000000008',
    '_12g' => '           8',
    '-12g' => '8',
    h      => 'Jul',
    '12h'  => '         Jul',
    '^h'   => 'JUL',
    '#h'   => 'JUL',
    H      => '21',
    '12H'  => '000000000021',
    '_12H' => '          21',
    '-12H' => '21',
    I      => '09',
    '12I'  => '000000000009',
    '_12I' => '           9',
    '-12I' => '9',
    j      => '188',
    '12j'  => '000000000188',
    '_12j' => '         188',
    '-12j' => '188',
    k      => '21',
    '12k'  => '          21',
    '-12k' => '21',
    l      => ' 9',
    '12l'  => '           9',
    '-12l' => '9',
    m      => '07',
    '12m'  => '000000000007',
    '_12m' => '           7',
    '-12m' => '7',
    M      => '03',
    '12M'  => '000000000003',
    '_12M' => '           3',
    '-12M' => '3',
    n      => "\n",
    '12n'  => "           \n",
    '-12n' => "           \n",
    N      => '123456000',
    '2N'   => '12',
    '12N'  => '000123456000',
    '_12N' => '   123456000',
    '-12N' => '123456000',
    Od     => '06',
    '12Od' => '000000000006',
    '_12Od' => '           6',
    '-12Od' => '6',
    Oe     => ' 6',
    OH     => '21',
    OI     => '09',
    Om     => '07',
    OM     => '03',
    OS     => '54',
    Ou     => '7',
    OU     => '27',
    OV     => '27',
    Ow     => '0',
    Oy     => '08',
    p      => 'PM',
    '^p'   => 'PM',
    '^#p'  => 'pm',
    '#p'   => 'pm',
    '#^p'  => 'pm',
    '12p'  => '          PM',
    '012p' => '0000000000PM',
    '_12p' => '          PM',
    '-12p' => '          PM',
    P      => 'pm',
    '^P'   => 'pm',
    '#P'   => 'pm',
    '12P'  => '          pm',
    '-12P' => '          pm',
    r      => '09:03:54 PM',
    '12r'  => ' 09:03:54 PM',
    '-12r' => ' 09:03:54 PM',
    '012r' => '009:03:54 PM',
    '^r'   => '09:03:54 PM',
    '#r'   => '09:03:54 PM',
    R      => '21:03',
    '12R'  => '       21:03',
    '-12R' => '       21:03',
    s      => '1215378234',
    '12s'  => '001215378234',
    '_12s' => '  1215378234',
    '-12s' => '1215378234',
    S      => '54',
    '12S'  => '000000000054',
    '_12S' => '          54',
    '-12S' => '54',
    t      => "\t",
    '12t'  => "           \t",
    '012t' => "00000000000\t",
    '-12t' => "           \t",
    T      => '21:03:54',
    '12T'  => '    21:03:54',
    '12T'  => '    21:03:54',
    '-12T' => '    21:03:54',
    u      => '7',
    '12u'  => '000000000007',
    '_12u' => '           7',
    '-12u' => '7',
    U      => '27',
    '12U'  => '000000000027',
    '_12U' => '          27',
    '-12U' => '27',
    V      => '27',
    '12V'  => '000000000027',
    '_12V' => '          27',
    '-12V' => '27',
    w      => '0',
    '12w'  => '000000000000',
    '_12w' => '           0',
    '-12w' => '0',
    W      => '26',
    '12W'  => '000000000026',
    '_12W' => '          26',
    '-12W' => '26',
    x      => '07/06/08',
    '12x'  => '    07/06/08',
    '-12x' => '    07/06/08',
    X      => '21:03:54',
    '12X'  => '    21:03:54',
    '-12X' => '    21:03:54',
    y      => '08',
    '12y'  => '000000000008',
    '_12y' => '           8',
    '-12y' => '8',
    Y      => '2008',
    '12Y'  => '000000002008',
    '_12Y' => '        2008',
    '-12Y' => '2008',
    z      => '+0000',
    ':z'   => '+00:00',
    '::z'  => '+00:00:00',
    ':::z' => '+00',
    '^#:z' => '+00:00',
    '012z' => '+00000000000',
    '12z'  => '+00000000000',
    '_12z' => '          +0',
    '-12z' => '+0',
    '12:z' => '+00000000:00',
    '_12:z' => '       +0:00',
    '-12:z' => '+0:00',
    '12::z' => '+00000:00:00',
    '_12::z' => '    +0:00:00',
    '-12::z' => '+0:00:00',
    '12:::z' => '+00000000000',
    '_12:::z' => '          +0',
    '-12:::z' => '+0',
    Z      => qr/^(GMT|UTC)$/,
    '^Z'   => qr/^(GMT|UTC)$/,
    '^#Z'  => qr/^(gmt|utc)$/,
    '#Z'   => qr/^(gmt|utc)$/,
    '#^Z'  => qr/^(gmt|utc)$/,
    '012Z' => qr/^0{9}(GMT|UTC)$/,
    '12Z'  => qr/^ {9}(GMT|UTC)$/,
    '-12Z' => qr/^ {9}(GMT|UTC)$/,
    '%'    => '%',
    '_12%' => '           %',
    '-12%' => '           %',
    '012%' => '00000000000%',
);

my @t = localtime timelocal(54, 3, 21, 6, 6, 108);
$t[0] += 0.123456;

foreach my $f (sort keys %format) {
    if (ref $format{$f} eq 'Regexp') {
        like strftime("%$f", @t), $format{$f}, "%$f";
    }
    else {
        is   strftime("%$f", @t), $format{$f}, "%$f";
    };
};