#!/usr/bin/env perl
use strict;
use warnings;
use Getopt::Long;
my $help;
my $ok = GetOptions("help|?" => \$help);
usage() if !$ok || $help;
require_module('DateTime');
# Format classes to use for display
my @formats = qw( DateParse MySQL HTTP Mail RSS );
# Check for availability of format classes
my @available;
FORMAT_CLASS:
foreach my $format (@formats) {
my $class = "DateTime::Format::$format";
next FORMAT_CLASS unless optional_module($class);
push @available, {
name => $format,
class => $class,
can_parse => $class->can('parse_datetime'),
can_format => $class->can('format_datetime'),
};
}
# read dates
while (my $t = <>) {
chomp($t);
my $dt;
if ($t =~ /^\d+$/) {
$dt = DateTime->from_epoch( epoch => $t );
}
elsif ($dt = try_helper_parsers($t)) {
# we are done
}
elsif ($t =~ /^(\d\d\d\d)[-\/](\d+)[-\/](\d+)$/) {
$dt = DateTime->new(
year => $1,
month => $2,
day => $3,
);
}
elsif ($t =~ /^(\d+)[-\/](\d+)[-\/](\d\d\d\d)$/) {
$dt = DateTime->new(
year => $3,
month => $2,
day => $1,
);
}
elsif ($t =~ /^(\d\d\d\d)[-\/](\d+)[-\/](\d+) (\d+):(\d+):(\d+)$/) {
$dt = DateTime->new(
year => $1,
month => $2,
day => $3,
hour => $4,
minute => $5,
second => $6,
);
}
elsif ($t =~ /^(\d+)[-\/](\d+)[-\/](\d\d\d\d) (\d+):(\d+):(\d+)$/) {
$dt = DateTime->new(
year => $3,
month => $2,
day => $1,
hour => $4,
minute => $5,
second => $6,
);
}
elsif ($t =~ /^(\d+):(\d+):(\d+)$/) {
$dt = DateTime->new(
hour => $1,
minute => $2,
second => $3,
);
}
if ($dt) {
print " $t -- $dt ", $dt->epoch, " (hex ", sprintf('%0.4x', $dt->epoch) ,")\n";
foreach my $helper (@available) {
next unless $helper->{can_format};
print " $t -- format $helper->{name} is: ", $helper->{class}->format_datetime($dt), "\n";
}
}
else {
print " $t -- could not parse this\n"
}
}
####################################################
# Try the helper classes to parse the datetime given
sub try_helper_parsers {
my $t = shift;
my $dt;
foreach my $helper (@available) {
next unless $helper->{can_parse};
eval { $dt = $helper->{class}->parse_datetime($t) };
last if $dt;
}
return $dt;
}
#####################################
# Deal with required/optional modules
sub require_module {
my $module = shift;
eval "require $module";
if (my $e = $@) {
print STDERR "FATAL: $0 requires the Perl module '$module'.\n\n";
print STDERR "You can install it with:\n\n";
print STDERR " cpan $module\n\n";
exit(1);
}
$module->import(@_);
}
sub optional_module {
my $module = shift;
eval "require $module";
return 0 if $@;
$module->import(@_);
return 1;
}
#######
# Usage
sub usage {
print STDERR <<USAGE;
Usage: x-datetime-converter [--help] [-?]
Reads datetime strings via stdin, and uses several methods to parse it.
If the parse is sucessful, we print the parsed date in several formats.
The list of formats supported is based on a list of DateTime::Format::*
modules available.
The following modules are used, if installed:
USAGE
foreach my $mod (@formats) {
print STDERR " * DateTime::Format::$mod\n";
}
print STDERR <<USAGE;
Make sure the modules are installed with:
cpan MODULE_NAME [MODULE_NAME]...
USAGE
exit(1);
}