-
Notifications
You must be signed in to change notification settings - Fork 5
/
parsetime
executable file
·132 lines (100 loc) · 3.26 KB
/
parsetime
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/perl
# Copyright 2015 Mark Lodato <[email protected]>
# Released under the MIT license; see LICENSE for details.
use warnings;
use strict;
use Date::Manip; # sudo aptitude install libdate-manip-perl
use Date::Manip::TZ;
use Getopt::Long;
use Pod::Usage;
my $format = '%a %Y-%m-%d %H:%M:%S %z %Z (%s)';
my $output_timezone = '';
GetOptions(
'format=s' => \$format,
'z|tz|timezone=s' => \$output_timezone,
'help|?' => sub { pod2usage(1); },
'man' => sub { pod2usage(-exitval => 0, -verbose => 2); },
) or pod2usage(2);
my $s = join(' ', @ARGV);
pod2usage(2) if not $s;
$\ = "\n";
sub exit_with_error {
print STDERR @_;
exit 1;
}
# Parse the date.
my $date = new Date::Manip::Date;
if ($s =~ /^(\d+)\.?\d*$/) {
my $timestamp = $1;
# Chop off fractional seconds (ms, ns, us) to get into the range:
# Fri 2128-06-11 04:53:20 -0400 EDT (5000000000)
# Fri 1970-02-27 15:53:20 -0500 EST (5000000)
while ($timestamp >= 5000000000) {
$timestamp = substr $timestamp, 0, -3;
}
$s = "epoch $timestamp";
}
my $err = $date->parse($s);
exit_with_error($date->err()) if $err;
# Convert timezones if requested.
if ($output_timezone ne "") {
my $tz = new Date::Manip::TZ;
my $zone;
if ($output_timezone eq "local") {
$zone = $tz->curr_zone();
} else {
$zone = $tz->zone($output_timezone);
}
exit_with_error("Time zone not found: $output_timezone")
if not defined($zone) or $zone eq "";
$err = $date->convert($zone);
exit_with_error($date->err()) if $err;
}
# Print the date.
print $date->printf($format);
__END__
=head1 NAME
parsetime - Parse a human-readable timestamp
=head1 SYNOPSIS
parsetime [-f <format>] [-tz <output_timezone>] <timestamp>
=head1 DESCRIPTION
Parse a human-readadable timestamp and print the result in the user specified
format, which defaults to the POSIX timestamp. Include the input timezone in
the string; if not specified, it is interpreted in the local timezone.
Pure numbers are interpreted as seconds, milliseconds, microseconds, or
nanoseconds since the unix epoch. To force this to be seconds, use "epoch
<number>".
Examples:
$ parsetime now
Thu 2015-04-30 00:31:46 -0400 EDT (1430368306)
$ parsetime apr 1 2015 pdt
Wed 2015-04-01 00:00:00 -0700 PDT (1427871600)
$ parsetime 1234567890
Fri 2009-02-13 18:31:30 -0500 EST (1234567890)
$ parsetime 1234567890111222
Fri 2009-02-13 18:31:30 -0500 EST (1234567890)
$ parsetime -f %D apr 1 2015
04/01/2015
Examples with timezones, where the local time is EDT (-0400):
$ parsetime -f '%H:%M %z' 'apr 1 at noon'
Wed Apr 1 12:00:00 2015 -0400
$ parsetime -f '%c %z' 'apr 1 at noon' -z pdt
Wed Apr 1 09:00:00 2015 -0700
$ parsetime -f '%c %z' 'apr 1 at noon gmt'
Wed Apr 1 12:00:00 2015 +0000
$ parsetime -f '%c %z' 'apr 1 at noon gmt' -z pdt
Wed Apr 1 05:00:00 2015 -0700
$ parsetime -f '%c %z' 'apr 1 at noon gmt' -z local
Wed Apr 1 08:00:00 2015 -0400
=head1 OPTIONS
=over 20
=item B<--format>=<format>
strftime-style format string.
=item B<-z>, B<--tz>, B<--timezone>=<output_timezone>
Output timezone; use "local" for the local timezone. By default, the output
timezone is the input timezone.
=item B<--help>
Show help message and exit.
=item B<--man>
Show full man page.
=back