Initial Commit
This commit is contained in:
681
database/perl/lib/Time/HiRes.pm
Normal file
681
database/perl/lib/Time/HiRes.pm
Normal file
@@ -0,0 +1,681 @@
|
||||
package Time::HiRes;
|
||||
|
||||
{ use 5.006; }
|
||||
use strict;
|
||||
|
||||
require Exporter;
|
||||
use XSLoader ();
|
||||
|
||||
our @ISA = qw(Exporter);
|
||||
|
||||
our @EXPORT = qw( );
|
||||
# More or less this same list is in Makefile.PL. Should unify.
|
||||
our @EXPORT_OK = qw (usleep sleep ualarm alarm gettimeofday time tv_interval
|
||||
getitimer setitimer nanosleep clock_gettime clock_getres
|
||||
clock clock_nanosleep
|
||||
CLOCKS_PER_SEC
|
||||
CLOCK_BOOTTIME
|
||||
CLOCK_HIGHRES
|
||||
CLOCK_MONOTONIC
|
||||
CLOCK_MONOTONIC_COARSE
|
||||
CLOCK_MONOTONIC_FAST
|
||||
CLOCK_MONOTONIC_PRECISE
|
||||
CLOCK_MONOTONIC_RAW
|
||||
CLOCK_PROCESS_CPUTIME_ID
|
||||
CLOCK_PROF
|
||||
CLOCK_REALTIME
|
||||
CLOCK_REALTIME_COARSE
|
||||
CLOCK_REALTIME_FAST
|
||||
CLOCK_REALTIME_PRECISE
|
||||
CLOCK_REALTIME_RAW
|
||||
CLOCK_SECOND
|
||||
CLOCK_SOFTTIME
|
||||
CLOCK_THREAD_CPUTIME_ID
|
||||
CLOCK_TIMEOFDAY
|
||||
CLOCK_UPTIME
|
||||
CLOCK_UPTIME_COARSE
|
||||
CLOCK_UPTIME_FAST
|
||||
CLOCK_UPTIME_PRECISE
|
||||
CLOCK_UPTIME_RAW
|
||||
CLOCK_VIRTUAL
|
||||
ITIMER_PROF
|
||||
ITIMER_REAL
|
||||
ITIMER_REALPROF
|
||||
ITIMER_VIRTUAL
|
||||
TIMER_ABSTIME
|
||||
d_usleep d_ualarm d_gettimeofday d_getitimer d_setitimer
|
||||
d_nanosleep d_clock_gettime d_clock_getres
|
||||
d_clock d_clock_nanosleep d_hires_stat
|
||||
d_futimens d_utimensat d_hires_utime
|
||||
stat lstat utime
|
||||
);
|
||||
|
||||
our $VERSION = '1.9764';
|
||||
our $XS_VERSION = $VERSION;
|
||||
$VERSION = eval $VERSION;
|
||||
|
||||
our $AUTOLOAD;
|
||||
sub AUTOLOAD {
|
||||
my $constname;
|
||||
($constname = $AUTOLOAD) =~ s/.*:://;
|
||||
# print "AUTOLOAD: constname = $constname ($AUTOLOAD)\n";
|
||||
die "&Time::HiRes::constant not defined" if $constname eq 'constant';
|
||||
my ($error, $val) = constant($constname);
|
||||
# print "AUTOLOAD: error = $error, val = $val\n";
|
||||
if ($error) {
|
||||
my (undef,$file,$line) = caller;
|
||||
die "$error at $file line $line.\n";
|
||||
}
|
||||
{
|
||||
no strict 'refs';
|
||||
*$AUTOLOAD = sub { $val };
|
||||
}
|
||||
goto &$AUTOLOAD;
|
||||
}
|
||||
|
||||
sub import {
|
||||
my $this = shift;
|
||||
for my $i (@_) {
|
||||
if (($i eq 'clock_getres' && !&d_clock_getres) ||
|
||||
($i eq 'clock_gettime' && !&d_clock_gettime) ||
|
||||
($i eq 'clock_nanosleep' && !&d_clock_nanosleep) ||
|
||||
($i eq 'clock' && !&d_clock) ||
|
||||
($i eq 'nanosleep' && !&d_nanosleep) ||
|
||||
($i eq 'usleep' && !&d_usleep) ||
|
||||
($i eq 'utime' && !&d_hires_utime) ||
|
||||
($i eq 'ualarm' && !&d_ualarm)) {
|
||||
require Carp;
|
||||
Carp::croak("Time::HiRes::$i(): unimplemented in this platform");
|
||||
}
|
||||
}
|
||||
Time::HiRes->export_to_level(1, $this, @_);
|
||||
}
|
||||
|
||||
XSLoader::load( 'Time::HiRes', $XS_VERSION );
|
||||
|
||||
# Preloaded methods go here.
|
||||
|
||||
sub tv_interval {
|
||||
# probably could have been done in C
|
||||
my ($a, $b) = @_;
|
||||
$b = [gettimeofday()] unless defined($b);
|
||||
(${$b}[0] - ${$a}[0]) + ((${$b}[1] - ${$a}[1]) / 1_000_000);
|
||||
}
|
||||
|
||||
# Autoload methods go after =cut, and are processed by the autosplit program.
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Time::HiRes - High resolution alarm, sleep, gettimeofday, interval timers
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Time::HiRes qw( usleep ualarm gettimeofday tv_interval nanosleep
|
||||
clock_gettime clock_getres clock_nanosleep clock
|
||||
stat lstat utime);
|
||||
|
||||
usleep ($microseconds);
|
||||
nanosleep ($nanoseconds);
|
||||
|
||||
ualarm ($microseconds);
|
||||
ualarm ($microseconds, $interval_microseconds);
|
||||
|
||||
$t0 = [gettimeofday];
|
||||
($seconds, $microseconds) = gettimeofday;
|
||||
|
||||
$elapsed = tv_interval ( $t0, [$seconds, $microseconds]);
|
||||
$elapsed = tv_interval ( $t0, [gettimeofday]);
|
||||
$elapsed = tv_interval ( $t0 );
|
||||
|
||||
use Time::HiRes qw ( time alarm sleep );
|
||||
|
||||
$now_fractions = time;
|
||||
sleep ($floating_seconds);
|
||||
alarm ($floating_seconds);
|
||||
alarm ($floating_seconds, $floating_interval);
|
||||
|
||||
use Time::HiRes qw( setitimer getitimer );
|
||||
|
||||
setitimer ($which, $floating_seconds, $floating_interval );
|
||||
getitimer ($which);
|
||||
|
||||
use Time::HiRes qw( clock_gettime clock_getres clock_nanosleep
|
||||
ITIMER_REAL ITIMER_VIRTUAL ITIMER_PROF
|
||||
ITIMER_REALPROF );
|
||||
|
||||
$realtime = clock_gettime(CLOCK_REALTIME);
|
||||
$resolution = clock_getres(CLOCK_REALTIME);
|
||||
|
||||
clock_nanosleep(CLOCK_REALTIME, 1.5e9);
|
||||
clock_nanosleep(CLOCK_REALTIME, time()*1e9 + 10e9, TIMER_ABSTIME);
|
||||
|
||||
my $ticktock = clock();
|
||||
|
||||
use Time::HiRes qw( stat lstat );
|
||||
|
||||
my @stat = stat("file");
|
||||
my @stat = stat(FH);
|
||||
my @stat = lstat("file");
|
||||
|
||||
use Time::HiRes qw( utime );
|
||||
utime $floating_seconds, $floating_seconds, file...;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The C<Time::HiRes> module implements a Perl interface to the
|
||||
C<usleep>, C<nanosleep>, C<ualarm>, C<gettimeofday>, and
|
||||
C<setitimer>/C<getitimer> system calls, in other words, high
|
||||
resolution time and timers. See the L</EXAMPLES> section below and the
|
||||
test scripts for usage; see your system documentation for the
|
||||
description of the underlying C<nanosleep> or C<usleep>, C<ualarm>,
|
||||
C<gettimeofday>, and C<setitimer>/C<getitimer> calls.
|
||||
|
||||
If your system lacks C<gettimeofday()> or an emulation of it you don't
|
||||
get C<gettimeofday()> or the one-argument form of C<tv_interval()>.
|
||||
If your system lacks all of C<nanosleep()>, C<usleep()>,
|
||||
C<select()>, and C<poll>, you don't get C<Time::HiRes::usleep()>,
|
||||
C<Time::HiRes::nanosleep()>, or C<Time::HiRes::sleep()>.
|
||||
If your system lacks both C<ualarm()> and C<setitimer()> you don't get
|
||||
C<Time::HiRes::ualarm()> or C<Time::HiRes::alarm()>.
|
||||
|
||||
If you try to import an unimplemented function in the C<use> statement
|
||||
it will fail at compile time.
|
||||
|
||||
If your subsecond sleeping is implemented with C<nanosleep()> instead
|
||||
of C<usleep()>, you can mix subsecond sleeping with signals since
|
||||
C<nanosleep()> does not use signals. This, however, is not portable,
|
||||
and you should first check for the truth value of
|
||||
C<&Time::HiRes::d_nanosleep> to see whether you have nanosleep, and
|
||||
then carefully read your C<nanosleep()> C API documentation for any
|
||||
peculiarities.
|
||||
|
||||
If you are using C<nanosleep> for something else than mixing sleeping
|
||||
with signals, give some thought to whether Perl is the tool you should
|
||||
be using for work requiring nanosecond accuracies.
|
||||
|
||||
Remember that unless you are working on a I<hard realtime> system,
|
||||
any clocks and timers will be imprecise, especially so if you are working
|
||||
in a pre-emptive multiuser system. Understand the difference between
|
||||
I<wallclock time> and process time (in UNIX-like systems the sum of
|
||||
I<user> and I<system> times). Any attempt to sleep for X seconds will
|
||||
most probably end up sleeping B<more> than that, but don't be surprised
|
||||
if you end up sleeping slightly B<less>.
|
||||
|
||||
The following functions can be imported from this module.
|
||||
No functions are exported by default.
|
||||
|
||||
=over 4
|
||||
|
||||
=item gettimeofday ()
|
||||
|
||||
In array context returns a two-element array with the seconds and
|
||||
microseconds since the epoch. In scalar context returns floating
|
||||
seconds like C<Time::HiRes::time()> (see below).
|
||||
|
||||
=item usleep ( $useconds )
|
||||
|
||||
Sleeps for the number of microseconds (millionths of a second)
|
||||
specified. Returns the number of microseconds actually slept.
|
||||
Can sleep for more than one second, unlike the C<usleep> system call.
|
||||
Can also sleep for zero seconds, which often works like a I<thread yield>.
|
||||
See also L<C<Time::HiRes::sleep()>|/sleep ( $floating_seconds )>, and
|
||||
L<C<clock_nanosleep()>|/clock_nanosleep ( $which, $nanoseconds, $flags = 0)>.
|
||||
|
||||
Do not expect usleep() to be exact down to one microsecond.
|
||||
|
||||
=item nanosleep ( $nanoseconds )
|
||||
|
||||
Sleeps for the number of nanoseconds (1e9ths of a second) specified.
|
||||
Returns the number of nanoseconds actually slept (accurate only to
|
||||
microseconds, the nearest thousand of them). Can sleep for more than
|
||||
one second. Can also sleep for zero seconds, which often works like
|
||||
a I<thread yield>. See also
|
||||
L<C<Time::HiRes::sleep()>|/sleep ( $floating_seconds )>,
|
||||
L<C<Time::HiRes::usleep()>|/usleep ( $useconds )>, and
|
||||
L<C<clock_nanosleep()>|/clock_nanosleep ( $which, $nanoseconds, $flags = 0)>.
|
||||
|
||||
Do not expect nanosleep() to be exact down to one nanosecond.
|
||||
Getting even accuracy of one thousand nanoseconds is good.
|
||||
|
||||
=item ualarm ( $useconds [, $interval_useconds ] )
|
||||
|
||||
Issues a C<ualarm> call; the C<$interval_useconds> is optional and
|
||||
will be zero if unspecified, resulting in C<alarm>-like behaviour.
|
||||
|
||||
Returns the remaining time in the alarm in microseconds, or C<undef>
|
||||
if an error occurred.
|
||||
|
||||
ualarm(0) will cancel an outstanding ualarm().
|
||||
|
||||
Note that the interaction between alarms and sleeps is unspecified.
|
||||
|
||||
=item tv_interval
|
||||
|
||||
tv_interval ( $ref_to_gettimeofday [, $ref_to_later_gettimeofday] )
|
||||
|
||||
Returns the floating seconds between the two times, which should have
|
||||
been returned by C<gettimeofday()>. If the second argument is omitted,
|
||||
then the current time is used.
|
||||
|
||||
=item time ()
|
||||
|
||||
Returns a floating seconds since the epoch. This function can be
|
||||
imported, resulting in a nice drop-in replacement for the C<time>
|
||||
provided with core Perl; see the L</EXAMPLES> below.
|
||||
|
||||
B<NOTE 1>: This higher resolution timer can return values either less
|
||||
or more than the core C<time()>, depending on whether your platform
|
||||
rounds the higher resolution timer values up, down, or to the nearest second
|
||||
to get the core C<time()>, but naturally the difference should be never
|
||||
more than half a second. See also L</clock_getres>, if available
|
||||
in your system.
|
||||
|
||||
B<NOTE 2>: Since Sunday, September 9th, 2001 at 01:46:40 AM GMT, when
|
||||
the C<time()> seconds since epoch rolled over to 1_000_000_000, the
|
||||
default floating point format of Perl and the seconds since epoch have
|
||||
conspired to produce an apparent bug: if you print the value of
|
||||
C<Time::HiRes::time()> you seem to be getting only five decimals, not
|
||||
six as promised (microseconds). Not to worry, the microseconds are
|
||||
there (assuming your platform supports such granularity in the first
|
||||
place). What is going on is that the default floating point format of
|
||||
Perl only outputs 15 digits. In this case that means ten digits
|
||||
before the decimal separator and five after. To see the microseconds
|
||||
you can use either C<printf>/C<sprintf> with C<"%.6f">, or the
|
||||
C<gettimeofday()> function in list context, which will give you the
|
||||
seconds and microseconds as two separate values.
|
||||
|
||||
=item sleep ( $floating_seconds )
|
||||
|
||||
Sleeps for the specified amount of seconds. Returns the number of
|
||||
seconds actually slept (a floating point value). This function can
|
||||
be imported, resulting in a nice drop-in replacement for the C<sleep>
|
||||
provided with perl, see the L</EXAMPLES> below.
|
||||
|
||||
Note that the interaction between alarms and sleeps is unspecified.
|
||||
|
||||
=item alarm ( $floating_seconds [, $interval_floating_seconds ] )
|
||||
|
||||
The C<SIGALRM> signal is sent after the specified number of seconds.
|
||||
Implemented using C<setitimer()> if available, C<ualarm()> if not.
|
||||
The C<$interval_floating_seconds> argument is optional and will be
|
||||
zero if unspecified, resulting in C<alarm()>-like behaviour. This
|
||||
function can be imported, resulting in a nice drop-in replacement for
|
||||
the C<alarm> provided with perl, see the L</EXAMPLES> below.
|
||||
|
||||
Returns the remaining time in the alarm in seconds, or C<undef>
|
||||
if an error occurred.
|
||||
|
||||
B<NOTE 1>: With some combinations of operating systems and Perl
|
||||
releases C<SIGALRM> restarts C<select()>, instead of interrupting it.
|
||||
This means that an C<alarm()> followed by a C<select()> may together
|
||||
take the sum of the times specified for the C<alarm()> and the
|
||||
C<select()>, not just the time of the C<alarm()>.
|
||||
|
||||
Note that the interaction between alarms and sleeps is unspecified.
|
||||
|
||||
=item setitimer ( $which, $floating_seconds [, $interval_floating_seconds ] )
|
||||
|
||||
Start up an interval timer: after a certain time, a signal ($which) arrives,
|
||||
and more signals may keep arriving at certain intervals. To disable
|
||||
an "itimer", use C<$floating_seconds> of zero. If the
|
||||
C<$interval_floating_seconds> is set to zero (or unspecified), the
|
||||
timer is disabled B<after> the next delivered signal.
|
||||
|
||||
Use of interval timers may interfere with C<alarm()>, C<sleep()>,
|
||||
and C<usleep()>. In standard-speak the "interaction is unspecified",
|
||||
which means that I<anything> may happen: it may work, it may not.
|
||||
|
||||
In scalar context, the remaining time in the timer is returned.
|
||||
|
||||
In list context, both the remaining time and the interval are returned.
|
||||
|
||||
There are usually three or four interval timers (signals) available: the
|
||||
C<$which> can be C<ITIMER_REAL>, C<ITIMER_VIRTUAL>, C<ITIMER_PROF>, or
|
||||
C<ITIMER_REALPROF>. Note that which ones are available depends: true
|
||||
UNIX platforms usually have the first three, but only Solaris seems to
|
||||
have C<ITIMER_REALPROF> (which is used to profile multithreaded programs).
|
||||
Win32 unfortunately does not have interval timers.
|
||||
|
||||
C<ITIMER_REAL> results in C<alarm()>-like behaviour. Time is counted in
|
||||
I<real time>; that is, wallclock time. C<SIGALRM> is delivered when
|
||||
the timer expires.
|
||||
|
||||
C<ITIMER_VIRTUAL> counts time in (process) I<virtual time>; that is,
|
||||
only when the process is running. In multiprocessor/user/CPU systems
|
||||
this may be more or less than real or wallclock time. (This time is
|
||||
also known as the I<user time>.) C<SIGVTALRM> is delivered when the
|
||||
timer expires.
|
||||
|
||||
C<ITIMER_PROF> counts time when either the process virtual time or when
|
||||
the operating system is running on behalf of the process (such as I/O).
|
||||
(This time is also known as the I<system time>.) (The sum of user
|
||||
time and system time is known as the I<CPU time>.) C<SIGPROF> is
|
||||
delivered when the timer expires. C<SIGPROF> can interrupt system calls.
|
||||
|
||||
The semantics of interval timers for multithreaded programs are
|
||||
system-specific, and some systems may support additional interval
|
||||
timers. For example, it is unspecified which thread gets the signals.
|
||||
See your L<C<setitimer(2)>> documentation.
|
||||
|
||||
=item getitimer ( $which )
|
||||
|
||||
Return the remaining time in the interval timer specified by C<$which>.
|
||||
|
||||
In scalar context, the remaining time is returned.
|
||||
|
||||
In list context, both the remaining time and the interval are returned.
|
||||
The interval is always what you put in using C<setitimer()>.
|
||||
|
||||
=item clock_gettime ( $which )
|
||||
|
||||
Return as seconds the current value of the POSIX high resolution timer
|
||||
specified by C<$which>. All implementations that support POSIX high
|
||||
resolution timers are supposed to support at least the C<$which> value
|
||||
of C<CLOCK_REALTIME>, which is supposed to return results close to the
|
||||
results of C<gettimeofday>, or the number of seconds since 00:00:00:00
|
||||
January 1, 1970 Greenwich Mean Time (GMT). Do not assume that
|
||||
CLOCK_REALTIME is zero, it might be one, or something else.
|
||||
Another potentially useful (but not available everywhere) value is
|
||||
C<CLOCK_MONOTONIC>, which guarantees a monotonically increasing time
|
||||
value (unlike time() or gettimeofday(), which can be adjusted).
|
||||
See your system documentation for other possibly supported values.
|
||||
|
||||
=item clock_getres ( $which )
|
||||
|
||||
Return as seconds the resolution of the POSIX high resolution timer
|
||||
specified by C<$which>. All implementations that support POSIX high
|
||||
resolution timers are supposed to support at least the C<$which> value
|
||||
of C<CLOCK_REALTIME>, see L</clock_gettime>.
|
||||
|
||||
B<NOTE>: the resolution returned may be highly optimistic. Even if
|
||||
the resolution is high (a small number), all it means is that you'll
|
||||
be able to specify the arguments to clock_gettime() and clock_nanosleep()
|
||||
with that resolution. The system might not actually be able to measure
|
||||
events at that resolution, and the various overheads and the overall system
|
||||
load are certain to affect any timings.
|
||||
|
||||
=item clock_nanosleep ( $which, $nanoseconds, $flags = 0)
|
||||
|
||||
Sleeps for the number of nanoseconds (1e9ths of a second) specified.
|
||||
Returns the number of nanoseconds actually slept. The $which is the
|
||||
"clock id", as with clock_gettime() and clock_getres(). The flags
|
||||
default to zero but C<TIMER_ABSTIME> can specified (must be exported
|
||||
explicitly) which means that C<$nanoseconds> is not a time interval
|
||||
(as is the default) but instead an absolute time. Can sleep for more
|
||||
than one second. Can also sleep for zero seconds, which often works
|
||||
like a I<thread yield>. See also
|
||||
L<C<Time::HiRes::sleep()>|/sleep ( $floating_seconds )>,
|
||||
L<C<Time::HiRes::usleep()>|/usleep ( $useconds )>, and
|
||||
L<C<Time::HiRes::nanosleep()>|/nanosleep ( $nanoseconds )>.
|
||||
|
||||
Do not expect clock_nanosleep() to be exact down to one nanosecond.
|
||||
Getting even accuracy of one thousand nanoseconds is good.
|
||||
|
||||
=item clock()
|
||||
|
||||
Return as seconds the I<process time> (user + system time) spent by
|
||||
the process since the first call to clock() (the definition is B<not>
|
||||
"since the start of the process", though if you are lucky these times
|
||||
may be quite close to each other, depending on the system). What this
|
||||
means is that you probably need to store the result of your first call
|
||||
to clock(), and subtract that value from the following results of clock().
|
||||
|
||||
The time returned also includes the process times of the terminated
|
||||
child processes for which wait() has been executed. This value is
|
||||
somewhat like the second value returned by the times() of core Perl,
|
||||
but not necessarily identical. Note that due to backward
|
||||
compatibility limitations the returned value may wrap around at about
|
||||
2147 seconds or at about 36 minutes.
|
||||
|
||||
=item stat
|
||||
|
||||
=item stat FH
|
||||
|
||||
=item stat EXPR
|
||||
|
||||
=item lstat
|
||||
|
||||
=item lstat FH
|
||||
|
||||
=item lstat EXPR
|
||||
|
||||
As L<perlfunc/stat> or L<perlfunc/lstat>
|
||||
but with the access/modify/change file timestamps
|
||||
in subsecond resolution, if the operating system and the filesystem
|
||||
both support such timestamps. To override the standard stat():
|
||||
|
||||
use Time::HiRes qw(stat);
|
||||
|
||||
Test for the value of &Time::HiRes::d_hires_stat to find out whether
|
||||
the operating system supports subsecond file timestamps: a value
|
||||
larger than zero means yes. There are unfortunately no easy
|
||||
ways to find out whether the filesystem supports such timestamps.
|
||||
UNIX filesystems often do; NTFS does; FAT doesn't (FAT timestamp
|
||||
granularity is B<two> seconds).
|
||||
|
||||
A zero return value of &Time::HiRes::d_hires_stat means that
|
||||
Time::HiRes::stat is a no-op passthrough for CORE::stat()
|
||||
(and likewise for lstat),
|
||||
and therefore the timestamps will stay integers. The same
|
||||
thing will happen if the filesystem does not do subsecond timestamps,
|
||||
even if the &Time::HiRes::d_hires_stat is non-zero.
|
||||
|
||||
In any case do not expect nanosecond resolution, or even a microsecond
|
||||
resolution. Also note that the modify/access timestamps might have
|
||||
different resolutions, and that they need not be synchronized, e.g.
|
||||
if the operations are
|
||||
|
||||
write
|
||||
stat # t1
|
||||
read
|
||||
stat # t2
|
||||
|
||||
the access time stamp from t2 need not be greater-than the modify
|
||||
time stamp from t1: it may be equal or I<less>.
|
||||
|
||||
=item utime LIST
|
||||
|
||||
As L<perlfunc/utime>
|
||||
but with the ability to set the access/modify file timestamps
|
||||
in subsecond resolution, if the operating system and the filesystem,
|
||||
and the mount options of the filesystem, all support such timestamps.
|
||||
|
||||
To override the standard utime():
|
||||
|
||||
use Time::HiRes qw(utime);
|
||||
|
||||
Test for the value of &Time::HiRes::d_hires_utime to find out whether
|
||||
the operating system supports setting subsecond file timestamps.
|
||||
|
||||
As with CORE::utime(), passing undef as both the atime and mtime will
|
||||
call the syscall with a NULL argument.
|
||||
|
||||
The actual achievable subsecond resolution depends on the combination
|
||||
of the operating system and the filesystem.
|
||||
|
||||
Modifying the timestamps may not be possible at all: for example, the
|
||||
C<noatime> filesystem mount option may prohibit you from changing the
|
||||
access time timestamp.
|
||||
|
||||
Returns the number of files successfully changed.
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
use Time::HiRes qw(usleep ualarm gettimeofday tv_interval);
|
||||
|
||||
$microseconds = 750_000;
|
||||
usleep($microseconds);
|
||||
|
||||
# signal alarm in 2.5s & every .1s thereafter
|
||||
ualarm(2_500_000, 100_000);
|
||||
# cancel that ualarm
|
||||
ualarm(0);
|
||||
|
||||
# get seconds and microseconds since the epoch
|
||||
($s, $usec) = gettimeofday();
|
||||
|
||||
# measure elapsed time
|
||||
# (could also do by subtracting 2 gettimeofday return values)
|
||||
$t0 = [gettimeofday];
|
||||
# do bunch of stuff here
|
||||
$t1 = [gettimeofday];
|
||||
# do more stuff here
|
||||
$t0_t1 = tv_interval $t0, $t1;
|
||||
|
||||
$elapsed = tv_interval ($t0, [gettimeofday]);
|
||||
$elapsed = tv_interval ($t0); # equivalent code
|
||||
|
||||
#
|
||||
# replacements for time, alarm and sleep that know about
|
||||
# floating seconds
|
||||
#
|
||||
use Time::HiRes;
|
||||
$now_fractions = Time::HiRes::time;
|
||||
Time::HiRes::sleep (2.5);
|
||||
Time::HiRes::alarm (10.6666666);
|
||||
|
||||
use Time::HiRes qw ( time alarm sleep );
|
||||
$now_fractions = time;
|
||||
sleep (2.5);
|
||||
alarm (10.6666666);
|
||||
|
||||
# Arm an interval timer to go off first at 10 seconds and
|
||||
# after that every 2.5 seconds, in process virtual time
|
||||
|
||||
use Time::HiRes qw ( setitimer ITIMER_VIRTUAL time );
|
||||
|
||||
$SIG{VTALRM} = sub { print time, "\n" };
|
||||
setitimer(ITIMER_VIRTUAL, 10, 2.5);
|
||||
|
||||
use Time::HiRes qw( clock_gettime clock_getres CLOCK_REALTIME );
|
||||
# Read the POSIX high resolution timer.
|
||||
my $high = clock_gettime(CLOCK_REALTIME);
|
||||
# But how accurate we can be, really?
|
||||
my $reso = clock_getres(CLOCK_REALTIME);
|
||||
|
||||
use Time::HiRes qw( clock_nanosleep TIMER_ABSTIME );
|
||||
clock_nanosleep(CLOCK_REALTIME, 1e6);
|
||||
clock_nanosleep(CLOCK_REALTIME, 2e9, TIMER_ABSTIME);
|
||||
|
||||
use Time::HiRes qw( clock );
|
||||
my $clock0 = clock();
|
||||
... # Do something.
|
||||
my $clock1 = clock();
|
||||
my $clockd = $clock1 - $clock0;
|
||||
|
||||
use Time::HiRes qw( stat );
|
||||
my ($atime, $mtime, $ctime) = (stat("istics"))[8, 9, 10];
|
||||
|
||||
=head1 C API
|
||||
|
||||
In addition to the perl API described above, a C API is available for
|
||||
extension writers. The following C functions are available in the
|
||||
modglobal hash:
|
||||
|
||||
name C prototype
|
||||
--------------- ----------------------
|
||||
Time::NVtime NV (*)()
|
||||
Time::U2time void (*)(pTHX_ UV ret[2])
|
||||
|
||||
Both functions return equivalent information (like C<gettimeofday>)
|
||||
but with different representations. The names C<NVtime> and C<U2time>
|
||||
were selected mainly because they are operating system independent.
|
||||
(C<gettimeofday> is Unix-centric, though some platforms like Win32 and
|
||||
VMS have emulations for it.)
|
||||
|
||||
Here is an example of using C<NVtime> from C:
|
||||
|
||||
NV (*myNVtime)(); /* Returns -1 on failure. */
|
||||
SV **svp = hv_fetchs(PL_modglobal, "Time::NVtime", 0);
|
||||
if (!svp) croak("Time::HiRes is required");
|
||||
if (!SvIOK(*svp)) croak("Time::NVtime isn't a function pointer");
|
||||
myNVtime = INT2PTR(NV(*)(), SvIV(*svp));
|
||||
printf("The current time is: %" NVff "\n", (*myNVtime)());
|
||||
|
||||
=head1 DIAGNOSTICS
|
||||
|
||||
=head2 useconds or interval more than ...
|
||||
|
||||
In ualarm() you tried to use number of microseconds or interval (also
|
||||
in microseconds) more than 1_000_000 and setitimer() is not available
|
||||
in your system to emulate that case.
|
||||
|
||||
=head2 negative time not invented yet
|
||||
|
||||
You tried to use a negative time argument.
|
||||
|
||||
=head2 internal error: useconds < 0 (unsigned ... signed ...)
|
||||
|
||||
Something went horribly wrong-- the number of microseconds that cannot
|
||||
become negative just became negative. Maybe your compiler is broken?
|
||||
|
||||
=head2 useconds or uinterval equal to or more than 1000000
|
||||
|
||||
In some platforms it is not possible to get an alarm with subsecond
|
||||
resolution and later than one second.
|
||||
|
||||
=head2 unimplemented in this platform
|
||||
|
||||
Some calls simply aren't available, real or emulated, on every platform.
|
||||
|
||||
=head1 CAVEATS
|
||||
|
||||
Notice that the core C<time()> maybe rounding rather than truncating.
|
||||
What this means is that the core C<time()> may be reporting the time
|
||||
as one second later than C<gettimeofday()> and C<Time::HiRes::time()>.
|
||||
|
||||
Adjusting the system clock (either manually or by services like ntp)
|
||||
may cause problems, especially for long running programs that assume
|
||||
a monotonously increasing time (note that all platforms do not adjust
|
||||
time as gracefully as UNIX ntp does). For example in Win32 (and derived
|
||||
platforms like Cygwin and MinGW) the Time::HiRes::time() may temporarily
|
||||
drift off from the system clock (and the original time()) by up to 0.5
|
||||
seconds. Time::HiRes will notice this eventually and recalibrate.
|
||||
Note that since Time::HiRes 1.77 the clock_gettime(CLOCK_MONOTONIC)
|
||||
might help in this (in case your system supports CLOCK_MONOTONIC).
|
||||
|
||||
Some systems have APIs but not implementations: for example QNX and Haiku
|
||||
have the interval timer APIs but not the functionality.
|
||||
|
||||
In pre-Sierra macOS (pre-10.12, OS X) clock_getres(), clock_gettime()
|
||||
and clock_nanosleep() are emulated using the Mach timers; as a side
|
||||
effect of being emulated the CLOCK_REALTIME and CLOCK_MONOTONIC are
|
||||
the same timer.
|
||||
|
||||
gnukfreebsd seems to have non-functional futimens() and utimensat()
|
||||
(at least as of 10.1): therefore the hires utime() does not work.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
Perl modules L<BSD::Resource>, L<Time::TAI64>.
|
||||
|
||||
Your system documentation for L<C<clock(3)>>, L<C<clock_gettime(2)>>,
|
||||
L<C<clock_getres(3)>>, L<C<clock_nanosleep(3)>>, L<C<clock_settime(2)>>,
|
||||
L<C<getitimer(2)>>, L<C<gettimeofday(2)>>, L<C<setitimer(2)>>, L<C<sleep(3)>>,
|
||||
L<C<stat(2)>>, L<C<ualarm(3)>>.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
D. Wegscheid <wegscd@whirlpool.com>
|
||||
R. Schertler <roderick@argon.org>
|
||||
J. Hietaniemi <jhi@iki.fi>
|
||||
G. Aas <gisle@aas.no>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
Copyright (c) 1996-2002 Douglas E. Wegscheid. All rights reserved.
|
||||
|
||||
Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Jarkko Hietaniemi.
|
||||
All rights reserved.
|
||||
|
||||
Copyright (C) 2011, 2012, 2013 Andrew Main (Zefram) <zefram@fysh.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the same terms as Perl itself.
|
||||
|
||||
=cut
|
||||
515
database/perl/lib/Time/Local.pm
Normal file
515
database/perl/lib/Time/Local.pm
Normal file
@@ -0,0 +1,515 @@
|
||||
package Time::Local;
|
||||
|
||||
use strict;
|
||||
|
||||
use Carp ();
|
||||
use Exporter;
|
||||
|
||||
our $VERSION = '1.30';
|
||||
|
||||
use parent 'Exporter';
|
||||
|
||||
our @EXPORT = qw( timegm timelocal );
|
||||
our @EXPORT_OK = qw(
|
||||
timegm_modern
|
||||
timelocal_modern
|
||||
timegm_nocheck
|
||||
timelocal_nocheck
|
||||
timegm_posix
|
||||
timelocal_posix
|
||||
);
|
||||
|
||||
my @MonthDays = ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
|
||||
|
||||
# Determine breakpoint for rolling century
|
||||
my $ThisYear = ( localtime() )[5];
|
||||
my $Breakpoint = ( $ThisYear + 50 ) % 100;
|
||||
my $NextCentury = $ThisYear - $ThisYear % 100;
|
||||
$NextCentury += 100 if $Breakpoint < 50;
|
||||
my $Century = $NextCentury - 100;
|
||||
my $SecOff = 0;
|
||||
|
||||
my ( %Options, %Cheat );
|
||||
|
||||
use constant SECS_PER_MINUTE => 60;
|
||||
use constant SECS_PER_HOUR => 3600;
|
||||
use constant SECS_PER_DAY => 86400;
|
||||
|
||||
my $MaxDay;
|
||||
if ( $] < 5.012000 ) {
|
||||
require Config;
|
||||
## no critic (Variables::ProhibitPackageVars)
|
||||
|
||||
my $MaxInt;
|
||||
if ( $^O eq 'MacOS' ) {
|
||||
|
||||
# time_t is unsigned...
|
||||
$MaxInt = ( 1 << ( 8 * $Config::Config{ivsize} ) )
|
||||
- 1; ## no critic qw(ProhibitPackageVars)
|
||||
}
|
||||
else {
|
||||
$MaxInt
|
||||
= ( ( 1 << ( 8 * $Config::Config{ivsize} - 2 ) ) - 1 ) * 2
|
||||
+ 1; ## no critic qw(ProhibitPackageVars)
|
||||
}
|
||||
|
||||
$MaxDay = int( ( $MaxInt - ( SECS_PER_DAY / 2 ) ) / SECS_PER_DAY ) - 1;
|
||||
}
|
||||
else {
|
||||
# recent localtime()'s limit is the year 2**31
|
||||
$MaxDay = 365 * ( 2**31 );
|
||||
}
|
||||
|
||||
# Determine the EPOC day for this machine
|
||||
my $Epoc = 0;
|
||||
if ( $^O eq 'vos' ) {
|
||||
|
||||
# work around posix-977 -- VOS doesn't handle dates in the range
|
||||
# 1970-1980.
|
||||
$Epoc = _daygm( 0, 0, 0, 1, 0, 70, 4, 0 );
|
||||
}
|
||||
elsif ( $^O eq 'MacOS' ) {
|
||||
$MaxDay *= 2; # time_t unsigned ... quick hack?
|
||||
# MacOS time() is seconds since 1 Jan 1904, localtime
|
||||
# so we need to calculate an offset to apply later
|
||||
$Epoc = 693901;
|
||||
$SecOff = timelocal( localtime(0) ) - timelocal( gmtime(0) );
|
||||
$Epoc += _daygm( gmtime(0) );
|
||||
}
|
||||
else {
|
||||
$Epoc = _daygm( gmtime(0) );
|
||||
}
|
||||
|
||||
%Cheat = (); # clear the cache as epoc has changed
|
||||
|
||||
sub _daygm {
|
||||
|
||||
# This is written in such a byzantine way in order to avoid
|
||||
# lexical variables and sub calls, for speed
|
||||
return $_[3] + (
|
||||
$Cheat{ pack( 'ss', @_[ 4, 5 ] ) } ||= do {
|
||||
my $month = ( $_[4] + 10 ) % 12;
|
||||
my $year = $_[5] + 1900 - int( $month / 10 );
|
||||
|
||||
( ( 365 * $year )
|
||||
+ int( $year / 4 )
|
||||
- int( $year / 100 )
|
||||
+ int( $year / 400 )
|
||||
+ int( ( ( $month * 306 ) + 5 ) / 10 ) ) - $Epoc;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub _timegm {
|
||||
my $sec
|
||||
= $SecOff + $_[0]
|
||||
+ ( SECS_PER_MINUTE * $_[1] )
|
||||
+ ( SECS_PER_HOUR * $_[2] );
|
||||
|
||||
return $sec + ( SECS_PER_DAY * &_daygm );
|
||||
}
|
||||
|
||||
sub timegm {
|
||||
my ( $sec, $min, $hour, $mday, $month, $year ) = @_;
|
||||
|
||||
if ( $Options{no_year_munging} ) {
|
||||
$year -= 1900;
|
||||
}
|
||||
elsif ( !$Options{posix_year} ) {
|
||||
if ( $year >= 1000 ) {
|
||||
$year -= 1900;
|
||||
}
|
||||
elsif ( $year < 100 and $year >= 0 ) {
|
||||
$year += ( $year > $Breakpoint ) ? $Century : $NextCentury;
|
||||
}
|
||||
}
|
||||
|
||||
unless ( $Options{no_range_check} ) {
|
||||
Carp::croak("Month '$month' out of range 0..11")
|
||||
if $month > 11
|
||||
or $month < 0;
|
||||
|
||||
my $md = $MonthDays[$month];
|
||||
++$md
|
||||
if $month == 1 && _is_leap_year( $year + 1900 );
|
||||
|
||||
Carp::croak("Day '$mday' out of range 1..$md")
|
||||
if $mday > $md or $mday < 1;
|
||||
Carp::croak("Hour '$hour' out of range 0..23")
|
||||
if $hour > 23 or $hour < 0;
|
||||
Carp::croak("Minute '$min' out of range 0..59")
|
||||
if $min > 59 or $min < 0;
|
||||
Carp::croak("Second '$sec' out of range 0..59")
|
||||
if $sec >= 60 or $sec < 0;
|
||||
}
|
||||
|
||||
my $days = _daygm( undef, undef, undef, $mday, $month, $year );
|
||||
|
||||
unless ( $Options{no_range_check} or abs($days) < $MaxDay ) {
|
||||
my $msg = q{};
|
||||
$msg .= "Day too big - $days > $MaxDay\n" if $days > $MaxDay;
|
||||
|
||||
$year += 1900;
|
||||
$msg
|
||||
.= "Cannot handle date ($sec, $min, $hour, $mday, $month, $year)";
|
||||
|
||||
Carp::croak($msg);
|
||||
}
|
||||
|
||||
return
|
||||
$sec + $SecOff
|
||||
+ ( SECS_PER_MINUTE * $min )
|
||||
+ ( SECS_PER_HOUR * $hour )
|
||||
+ ( SECS_PER_DAY * $days );
|
||||
}
|
||||
|
||||
sub _is_leap_year {
|
||||
return 0 if $_[0] % 4;
|
||||
return 1 if $_[0] % 100;
|
||||
return 0 if $_[0] % 400;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub timegm_nocheck {
|
||||
local $Options{no_range_check} = 1;
|
||||
return &timegm;
|
||||
}
|
||||
|
||||
sub timegm_modern {
|
||||
local $Options{no_year_munging} = 1;
|
||||
return &timegm;
|
||||
}
|
||||
|
||||
sub timegm_posix {
|
||||
local $Options{posix_year} = 1;
|
||||
return &timegm;
|
||||
}
|
||||
|
||||
sub timelocal {
|
||||
my $ref_t = &timegm;
|
||||
my $loc_for_ref_t = _timegm( localtime($ref_t) );
|
||||
|
||||
my $zone_off = $loc_for_ref_t - $ref_t
|
||||
or return $loc_for_ref_t;
|
||||
|
||||
# Adjust for timezone
|
||||
my $loc_t = $ref_t - $zone_off;
|
||||
|
||||
# Are we close to a DST change or are we done
|
||||
my $dst_off = $ref_t - _timegm( localtime($loc_t) );
|
||||
|
||||
# If this evaluates to true, it means that the value in $loc_t is
|
||||
# the _second_ hour after a DST change where the local time moves
|
||||
# backward.
|
||||
if (
|
||||
!$dst_off
|
||||
&& ( ( $ref_t - SECS_PER_HOUR )
|
||||
- _timegm( localtime( $loc_t - SECS_PER_HOUR ) ) < 0 )
|
||||
) {
|
||||
return $loc_t - SECS_PER_HOUR;
|
||||
}
|
||||
|
||||
# Adjust for DST change
|
||||
$loc_t += $dst_off;
|
||||
|
||||
return $loc_t if $dst_off > 0;
|
||||
|
||||
# If the original date was a non-existent gap in a forward DST jump, we
|
||||
# should now have the wrong answer - undo the DST adjustment
|
||||
my ( $s, $m, $h ) = localtime($loc_t);
|
||||
$loc_t -= $dst_off if $s != $_[0] || $m != $_[1] || $h != $_[2];
|
||||
|
||||
return $loc_t;
|
||||
}
|
||||
|
||||
sub timelocal_nocheck {
|
||||
local $Options{no_range_check} = 1;
|
||||
return &timelocal;
|
||||
}
|
||||
|
||||
sub timelocal_modern {
|
||||
local $Options{no_year_munging} = 1;
|
||||
return &timelocal;
|
||||
}
|
||||
|
||||
sub timelocal_posix {
|
||||
local $Options{posix_year} = 1;
|
||||
return &timelocal;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
# ABSTRACT: Efficiently compute time from local and GMT time
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=encoding UTF-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Time::Local - Efficiently compute time from local and GMT time
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
version 1.30
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Time::Local qw( timelocal_posix timegm_posix );
|
||||
|
||||
my $time = timelocal_posix( $sec, $min, $hour, $mday, $mon, $year );
|
||||
my $time = timegm_posix( $sec, $min, $hour, $mday, $mon, $year );
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module provides functions that are the inverse of built-in perl functions
|
||||
C<localtime()> and C<gmtime()>. They accept a date as a six-element array, and
|
||||
return the corresponding C<time(2)> value in seconds since the system epoch
|
||||
(Midnight, January 1, 1970 GMT on Unix, for example). This value can be
|
||||
positive or negative, though POSIX only requires support for positive values,
|
||||
so dates before the system's epoch may not work on all operating systems.
|
||||
|
||||
It is worth drawing particular attention to the expected ranges for the values
|
||||
provided. The value for the day of the month is the actual day (i.e. 1..31),
|
||||
while the month is the number of months since January (0..11). This is
|
||||
consistent with the values returned from C<localtime()> and C<gmtime()>.
|
||||
|
||||
=head1 FUNCTIONS
|
||||
|
||||
=head2 C<timelocal_posix()> and C<timegm_posix()>
|
||||
|
||||
These functions are the exact inverse of Perl's built-in C<localtime> and
|
||||
C<gmtime> functions. That means that calling C<< timelocal_posix(
|
||||
localtime($value) ) >> will always give you the same C<$value> you started
|
||||
with. The same applies to C<< timegm_posix( gmtime($value) ) >>.
|
||||
|
||||
The one exception is when the value returned from C<localtime()> represents an
|
||||
ambiguous local time because of a DST change. See the documentation below for
|
||||
more details.
|
||||
|
||||
These functions expect the year value to be the number of years since 1900,
|
||||
which is what the C<localtime()> and C<gmtime()> built-ins returns.
|
||||
|
||||
They perform range checking by default on the input C<$sec>, C<$min>,
|
||||
C<$hour>, C<$mday>, and C<$mon> values and will croak (using C<Carp::croak()>)
|
||||
if given a value outside the allowed ranges.
|
||||
|
||||
While it would be nice to make this the default behavior, that would almost
|
||||
certainly break a lot of code, so you must explicitly import these functions
|
||||
and use them instead of the default C<timelocal()> and C<timegm()>.
|
||||
|
||||
You are B<strongly> encouraged to use these functions in any new code which
|
||||
uses this module. It will almost certainly make your code's behavior less
|
||||
surprising.
|
||||
|
||||
=head2 C<timelocal_modern()> and C<timegm_modern()>
|
||||
|
||||
When C<Time::Local> was first written, it was a common practice to represent
|
||||
years as a two-digit value like C<99> for C<1999> or C<1> for C<2001>. This
|
||||
caused all sorts of problems (google "Y2K problem" if you're very young) and
|
||||
developers eventually realized that this was a terrible idea.
|
||||
|
||||
The default exports of C<timelocal()> and C<timegm()> do a complicated
|
||||
calculation when given a year value less than 1000. This leads to surprising
|
||||
results in many cases. See L</Year Value Interpretation> for details.
|
||||
|
||||
The C<time*_modern()> functions do not do this year munging and simply take
|
||||
the year value as provided.
|
||||
|
||||
They perform range checking by default on the input C<$sec>, C<$min>,
|
||||
C<$hour>, C<$mday>, and C<$mon> values and will croak (using C<Carp::croak()>)
|
||||
if given a value outside the allowed ranges.
|
||||
|
||||
=head2 C<timelocal()> and C<timegm()>
|
||||
|
||||
This module exports two functions by default, C<timelocal()> and C<timegm()>.
|
||||
|
||||
They perform range checking by default on the input C<$sec>, C<$min>,
|
||||
C<$hour>, C<$mday>, and C<$mon> values and will croak (using C<Carp::croak()>)
|
||||
if given a value outside the allowed ranges.
|
||||
|
||||
B<Warning: The year value interpretation that these functions and their
|
||||
nocheck variants use will almost certainly lead to bugs in your code, if not
|
||||
now, then in the future. You are strongly discouraged from using these in new
|
||||
code, and you should convert old code to using either the C<*_posix> or
|
||||
C<*_modern> functions if possible.>
|
||||
|
||||
=head2 C<timelocal_nocheck()> and C<timegm_nocheck()>
|
||||
|
||||
If you are working with data you know to be valid, you can use the "nocheck"
|
||||
variants, C<timelocal_nocheck()> and C<timegm_nocheck()>. These variants must
|
||||
be explicitly imported.
|
||||
|
||||
If you supply data which is not valid (month 27, second 1,000) the results
|
||||
will be unpredictable (so don't do that).
|
||||
|
||||
Note that my benchmarks show that this is just a 3% speed increase over the
|
||||
checked versions, so unless calling C<Time::Local> is the hottest spot in your
|
||||
application, using these nocheck variants is unlikely to have much impact on
|
||||
your application.
|
||||
|
||||
=head2 Year Value Interpretation
|
||||
|
||||
B<This does not apply to the C<*_posix> or C<*_modern> functions. Use those
|
||||
exports if you want to ensure consistent behavior as your code ages.>
|
||||
|
||||
Strictly speaking, the year should be specified in a form consistent with
|
||||
C<localtime()>, i.e. the offset from 1900. In order to make the interpretation
|
||||
of the year easier for humans, however, who are more accustomed to seeing
|
||||
years as two-digit or four-digit values, the following conventions are
|
||||
followed:
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
Years greater than 999 are interpreted as being the actual year, rather than
|
||||
the offset from 1900. Thus, 1964 would indicate the year Martin Luther King
|
||||
won the Nobel prize, not the year 3864.
|
||||
|
||||
=item *
|
||||
|
||||
Years in the range 100..999 are interpreted as offset from 1900, so that 112
|
||||
indicates 2012. This rule also applies to years less than zero (but see note
|
||||
below regarding date range).
|
||||
|
||||
=item *
|
||||
|
||||
Years in the range 0..99 are interpreted as shorthand for years in the rolling
|
||||
"current century," defined as 50 years on either side of the current
|
||||
year. Thus, today, in 1999, 0 would refer to 2000, and 45 to 2045, but 55
|
||||
would refer to 1955. Twenty years from now, 55 would instead refer to
|
||||
2055. This is messy, but matches the way people currently think about two
|
||||
digit dates. Whenever possible, use an absolute four digit year instead.
|
||||
|
||||
=back
|
||||
|
||||
The scheme above allows interpretation of a wide range of dates, particularly
|
||||
if 4-digit years are used. But it also means that the behavior of your code
|
||||
changes as time passes, because the rolling "current century" changes each
|
||||
year.
|
||||
|
||||
=head2 Limits of time_t
|
||||
|
||||
On perl versions older than 5.12.0, the range of dates that can be actually be
|
||||
handled depends on the size of C<time_t> (usually a signed integer) on the
|
||||
given platform. Currently, this is 32 bits for most systems, yielding an
|
||||
approximate range from Dec 1901 to Jan 2038.
|
||||
|
||||
Both C<timelocal()> and C<timegm()> croak if given dates outside the supported
|
||||
range.
|
||||
|
||||
As of version 5.12.0, perl has stopped using the time implementation of the
|
||||
operating system it's running on. Instead, it has its own implementation of
|
||||
those routines with a safe range of at least +/- 2**52 (about 142 million
|
||||
years)
|
||||
|
||||
=head2 Ambiguous Local Times (DST)
|
||||
|
||||
Because of DST changes, there are many time zones where the same local time
|
||||
occurs for two different GMT times on the same day. For example, in the
|
||||
"Europe/Paris" time zone, the local time of 2001-10-28 02:30:00 can represent
|
||||
either 2001-10-28 00:30:00 GMT, B<or> 2001-10-28 01:30:00 GMT.
|
||||
|
||||
When given an ambiguous local time, the timelocal() function will always
|
||||
return the epoch for the I<earlier> of the two possible GMT times.
|
||||
|
||||
=head2 Non-Existent Local Times (DST)
|
||||
|
||||
When a DST change causes a locale clock to skip one hour forward, there will
|
||||
be an hour's worth of local times that don't exist. Again, for the
|
||||
"Europe/Paris" time zone, the local clock jumped from 2001-03-25 01:59:59 to
|
||||
2001-03-25 03:00:00.
|
||||
|
||||
If the C<timelocal()> function is given a non-existent local time, it will
|
||||
simply return an epoch value for the time one hour later.
|
||||
|
||||
=head2 Negative Epoch Values
|
||||
|
||||
On perl version 5.12.0 and newer, negative epoch values are fully supported.
|
||||
|
||||
On older versions of perl, negative epoch (C<time_t>) values, which are not
|
||||
officially supported by the POSIX standards, are known not to work on some
|
||||
systems. These include MacOS (pre-OSX) and Win32.
|
||||
|
||||
On systems which do support negative epoch values, this module should be able
|
||||
to cope with dates before the start of the epoch, down the minimum value of
|
||||
time_t for the system.
|
||||
|
||||
=head1 IMPLEMENTATION
|
||||
|
||||
These routines are quite efficient and yet are always guaranteed to agree with
|
||||
C<localtime()> and C<gmtime()>. We manage this by caching the start times of
|
||||
any months we've seen before. If we know the start time of the month, we can
|
||||
always calculate any time within the month. The start times are calculated
|
||||
using a mathematical formula. Unlike other algorithms that do multiple calls
|
||||
to C<gmtime()>.
|
||||
|
||||
The C<timelocal()> function is implemented using the same cache. We just
|
||||
assume that we're translating a GMT time, and then fudge it when we're done
|
||||
for the timezone and daylight savings arguments. Note that the timezone is
|
||||
evaluated for each date because countries occasionally change their official
|
||||
timezones. Assuming that C<localtime()> corrects for these changes, this
|
||||
routine will also be correct.
|
||||
|
||||
=head1 AUTHORS EMERITUS
|
||||
|
||||
This module is based on a Perl 4 library, timelocal.pl, that was
|
||||
included with Perl 4.036, and was most likely written by Tom
|
||||
Christiansen.
|
||||
|
||||
The current version was written by Graham Barr.
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
The whole scheme for interpreting two-digit years can be considered a bug.
|
||||
|
||||
Bugs may be submitted at L<https://github.com/houseabsolute/Time-Local/issues>.
|
||||
|
||||
There is a mailing list available for users of this distribution,
|
||||
L<mailto:datetime@perl.org>.
|
||||
|
||||
I am also usually active on IRC as 'autarch' on C<irc://irc.perl.org>.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Time-Local can be found at L<https://github.com/houseabsolute/Time-Local>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Dave Rolsky <autarch@urth.org>
|
||||
|
||||
=head1 CONTRIBUTORS
|
||||
|
||||
=for stopwords Florian Ragwitz J. Nick Koston Unknown
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
Florian Ragwitz <rafl@debian.org>
|
||||
|
||||
=item *
|
||||
|
||||
J. Nick Koston <nick@cpanel.net>
|
||||
|
||||
=item *
|
||||
|
||||
Unknown <unknown@example.com>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 1997 - 2020 by Graham Barr & Dave Rolsky.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
The full text of the license can be found in the
|
||||
F<LICENSE> file included with this distribution.
|
||||
|
||||
=cut
|
||||
1190
database/perl/lib/Time/Piece.pm
Normal file
1190
database/perl/lib/Time/Piece.pm
Normal file
File diff suppressed because it is too large
Load Diff
266
database/perl/lib/Time/Seconds.pm
Normal file
266
database/perl/lib/Time/Seconds.pm
Normal file
@@ -0,0 +1,266 @@
|
||||
package Time::Seconds;
|
||||
use strict;
|
||||
|
||||
our $VERSION = '1.3401';
|
||||
|
||||
use Exporter 5.57 'import';
|
||||
|
||||
our @EXPORT = qw(
|
||||
ONE_MINUTE
|
||||
ONE_HOUR
|
||||
ONE_DAY
|
||||
ONE_WEEK
|
||||
ONE_MONTH
|
||||
ONE_YEAR
|
||||
ONE_FINANCIAL_MONTH
|
||||
LEAP_YEAR
|
||||
NON_LEAP_YEAR
|
||||
);
|
||||
|
||||
our @EXPORT_OK = qw(cs_sec cs_mon);
|
||||
|
||||
use constant {
|
||||
ONE_MINUTE => 60,
|
||||
ONE_HOUR => 3_600,
|
||||
ONE_DAY => 86_400,
|
||||
ONE_WEEK => 604_800,
|
||||
ONE_MONTH => 2_629_744, # ONE_YEAR / 12
|
||||
ONE_YEAR => 31_556_930, # 365.24225 days
|
||||
ONE_FINANCIAL_MONTH => 2_592_000, # 30 days
|
||||
LEAP_YEAR => 31_622_400, # 366 * ONE_DAY
|
||||
NON_LEAP_YEAR => 31_536_000, # 365 * ONE_DAY
|
||||
# hacks to make Time::Piece compile once again
|
||||
cs_sec => 0,
|
||||
cs_mon => 1,
|
||||
};
|
||||
|
||||
use overload
|
||||
'fallback' => 'undef',
|
||||
'0+' => \&seconds,
|
||||
'""' => \&seconds,
|
||||
'<=>' => \&compare,
|
||||
'+' => \&add,
|
||||
'-' => \&subtract,
|
||||
'-=' => \&subtract_from,
|
||||
'+=' => \&add_to,
|
||||
'=' => \©
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my ($val) = @_;
|
||||
$val = 0 unless defined $val;
|
||||
bless \$val, $class;
|
||||
}
|
||||
|
||||
sub _get_ovlvals {
|
||||
my ($lhs, $rhs, $reverse) = @_;
|
||||
$lhs = $lhs->seconds;
|
||||
|
||||
if (UNIVERSAL::isa($rhs, 'Time::Seconds')) {
|
||||
$rhs = $rhs->seconds;
|
||||
}
|
||||
elsif (ref($rhs)) {
|
||||
die "Can't use non Seconds object in operator overload";
|
||||
}
|
||||
|
||||
if ($reverse) {
|
||||
return $rhs, $lhs;
|
||||
}
|
||||
|
||||
return $lhs, $rhs;
|
||||
}
|
||||
|
||||
sub compare {
|
||||
my ($lhs, $rhs) = _get_ovlvals(@_);
|
||||
return $lhs <=> $rhs;
|
||||
}
|
||||
|
||||
sub add {
|
||||
my ($lhs, $rhs) = _get_ovlvals(@_);
|
||||
return Time::Seconds->new($lhs + $rhs);
|
||||
}
|
||||
|
||||
sub add_to {
|
||||
my $lhs = shift;
|
||||
my $rhs = shift;
|
||||
$rhs = $rhs->seconds if UNIVERSAL::isa($rhs, 'Time::Seconds');
|
||||
$$lhs += $rhs;
|
||||
return $lhs;
|
||||
}
|
||||
|
||||
sub subtract {
|
||||
my ($lhs, $rhs) = _get_ovlvals(@_);
|
||||
return Time::Seconds->new($lhs - $rhs);
|
||||
}
|
||||
|
||||
sub subtract_from {
|
||||
my $lhs = shift;
|
||||
my $rhs = shift;
|
||||
$rhs = $rhs->seconds if UNIVERSAL::isa($rhs, 'Time::Seconds');
|
||||
$$lhs -= $rhs;
|
||||
return $lhs;
|
||||
}
|
||||
|
||||
sub copy {
|
||||
Time::Seconds->new(${$_[0]});
|
||||
}
|
||||
|
||||
sub seconds {
|
||||
my $s = shift;
|
||||
return $$s;
|
||||
}
|
||||
|
||||
sub minutes {
|
||||
my $s = shift;
|
||||
return $$s / 60;
|
||||
}
|
||||
|
||||
sub hours {
|
||||
my $s = shift;
|
||||
$s->minutes / 60;
|
||||
}
|
||||
|
||||
sub days {
|
||||
my $s = shift;
|
||||
$s->hours / 24;
|
||||
}
|
||||
|
||||
sub weeks {
|
||||
my $s = shift;
|
||||
$s->days / 7;
|
||||
}
|
||||
|
||||
sub months {
|
||||
my $s = shift;
|
||||
$s->days / 30.4368541;
|
||||
}
|
||||
|
||||
sub financial_months {
|
||||
my $s = shift;
|
||||
$s->days / 30;
|
||||
}
|
||||
|
||||
sub years {
|
||||
my $s = shift;
|
||||
$s->days / 365.24225;
|
||||
}
|
||||
|
||||
sub _counted_objects {
|
||||
my ($n, $counted) = @_;
|
||||
my $number = sprintf("%d", $n); # does a "floor"
|
||||
$counted .= 's' if 1 != $number;
|
||||
return ($number, $counted);
|
||||
}
|
||||
|
||||
sub pretty {
|
||||
my $s = shift;
|
||||
my $str = "";
|
||||
if ($s < 0) {
|
||||
$s = -$s;
|
||||
$str = "minus ";
|
||||
}
|
||||
if ($s >= ONE_MINUTE) {
|
||||
if ($s >= ONE_HOUR) {
|
||||
if ($s >= ONE_DAY) {
|
||||
my ($days, $sd) = _counted_objects($s->days, "day");
|
||||
$str .= "$days $sd, ";
|
||||
$s -= ($days * ONE_DAY);
|
||||
}
|
||||
my ($hours, $sh) = _counted_objects($s->hours, "hour");
|
||||
$str .= "$hours $sh, ";
|
||||
$s -= ($hours * ONE_HOUR);
|
||||
}
|
||||
my ($mins, $sm) = _counted_objects($s->minutes, "minute");
|
||||
$str .= "$mins $sm, ";
|
||||
$s -= ($mins * ONE_MINUTE);
|
||||
}
|
||||
$str .= join " ", _counted_objects($s->seconds, "second");
|
||||
return $str;
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=encoding utf8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Time::Seconds - a simple API to convert seconds to other date values
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Time::Piece;
|
||||
use Time::Seconds;
|
||||
|
||||
my $t = localtime;
|
||||
$t += ONE_DAY;
|
||||
|
||||
my $t2 = localtime;
|
||||
my $s = $t - $t2;
|
||||
|
||||
print "Difference is: ", $s->days, "\n";
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module is part of the Time::Piece distribution. It allows the user
|
||||
to find out the number of minutes, hours, days, weeks or years in a given
|
||||
number of seconds. It is returned by Time::Piece when you delta two
|
||||
Time::Piece objects.
|
||||
|
||||
Time::Seconds also exports the following constants:
|
||||
|
||||
ONE_DAY
|
||||
ONE_WEEK
|
||||
ONE_HOUR
|
||||
ONE_MINUTE
|
||||
ONE_MONTH
|
||||
ONE_YEAR
|
||||
ONE_FINANCIAL_MONTH
|
||||
LEAP_YEAR
|
||||
NON_LEAP_YEAR
|
||||
|
||||
Since perl does not (yet?) support constant objects, these constants are in
|
||||
seconds only, so you cannot, for example, do this: C<print ONE_WEEK-E<gt>minutes;>
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
The following methods are available:
|
||||
|
||||
my $val = Time::Seconds->new(SECONDS)
|
||||
$val->seconds;
|
||||
$val->minutes;
|
||||
$val->hours;
|
||||
$val->days;
|
||||
$val->weeks;
|
||||
$val->months;
|
||||
$val->financial_months; # 30 days
|
||||
$val->years;
|
||||
$val->pretty; # gives English representation of the delta
|
||||
|
||||
The usual arithmetic (+,-,+=,-=) is also available on the objects.
|
||||
|
||||
The methods make the assumption that there are 24 hours in a day, 7 days in
|
||||
a week, 365.24225 days in a year and 12 months in a year.
|
||||
(from The Calendar FAQ at http://www.tondering.dk/claus/calendar.html)
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Matt Sergeant, matt@sergeant.org
|
||||
|
||||
Tobias Brox, tobiasb@tobiasb.funcom.com
|
||||
|
||||
Balázs Szabó (dLux), dlux@kapu.hu
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
Copyright 2001, Larry Wall.
|
||||
|
||||
This module is free software, you may distribute it under the same terms
|
||||
as Perl.
|
||||
|
||||
=head1 Bugs
|
||||
|
||||
Currently the methods aren't as efficient as they could be, for reasons of
|
||||
clarity. This is probably a bad idea.
|
||||
|
||||
=cut
|
||||
95
database/perl/lib/Time/gmtime.pm
Normal file
95
database/perl/lib/Time/gmtime.pm
Normal file
@@ -0,0 +1,95 @@
|
||||
package Time::gmtime;
|
||||
use strict;
|
||||
use 5.006_001;
|
||||
|
||||
use Time::tm;
|
||||
|
||||
our (@ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS, $VERSION);
|
||||
our ( $tm_sec, $tm_min, $tm_hour, $tm_mday,
|
||||
$tm_mon, $tm_year, $tm_wday, $tm_yday,
|
||||
$tm_isdst,
|
||||
);
|
||||
|
||||
BEGIN {
|
||||
use Exporter ();
|
||||
@ISA = qw(Exporter Time::tm);
|
||||
@EXPORT = qw(gmtime gmctime);
|
||||
@EXPORT_OK = qw(
|
||||
$tm_sec $tm_min $tm_hour $tm_mday
|
||||
$tm_mon $tm_year $tm_wday $tm_yday
|
||||
$tm_isdst
|
||||
);
|
||||
%EXPORT_TAGS = ( FIELDS => [ @EXPORT_OK, @EXPORT ] );
|
||||
$VERSION = 1.04;
|
||||
}
|
||||
|
||||
sub populate (@) {
|
||||
return unless @_;
|
||||
my $tmob = Time::tm->new();
|
||||
@$tmob = (
|
||||
$tm_sec, $tm_min, $tm_hour, $tm_mday,
|
||||
$tm_mon, $tm_year, $tm_wday, $tm_yday,
|
||||
$tm_isdst )
|
||||
= @_;
|
||||
return $tmob;
|
||||
}
|
||||
|
||||
sub gmtime (;$) { populate CORE::gmtime(@_ ? shift : time)}
|
||||
sub gmctime (;$) { scalar CORE::gmtime(@_ ? shift : time)}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Time::gmtime - by-name interface to Perl's built-in gmtime() function
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Time::gmtime;
|
||||
$gm = gmtime();
|
||||
printf "The day in Greenwich is %s\n",
|
||||
(qw(Sun Mon Tue Wed Thu Fri Sat Sun))[ $gm->wday() ];
|
||||
|
||||
use Time::gmtime qw(:FIELDS);
|
||||
gmtime();
|
||||
printf "The day in Greenwich is %s\n",
|
||||
(qw(Sun Mon Tue Wed Thu Fri Sat Sun))[ $tm_wday ];
|
||||
|
||||
$now = gmctime();
|
||||
|
||||
use Time::gmtime;
|
||||
use File::stat;
|
||||
$date_string = gmctime(stat($file)->mtime);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module's default exports override the core gmtime() function,
|
||||
replacing it with a version that returns "Time::tm" objects.
|
||||
This object has methods that return the similarly named structure field
|
||||
name from the C's tm structure from F<time.h>; namely sec, min, hour,
|
||||
mday, mon, year, wday, yday, and isdst.
|
||||
|
||||
You may also import all the structure fields directly into your namespace
|
||||
as regular variables using the :FIELDS import tag. (Note that this
|
||||
still overrides your core functions.) Access these fields as variables
|
||||
named with a preceding C<tm_> in front their method names. Thus,
|
||||
C<$tm_obj-E<gt>mday()> corresponds to $tm_mday if you import the fields.
|
||||
|
||||
The gmctime() function provides a way of getting at the
|
||||
scalar sense of the original CORE::gmtime() function.
|
||||
|
||||
To access this functionality without the core overrides,
|
||||
pass the C<use> an empty import list, and then access
|
||||
function functions with their full qualified names.
|
||||
On the other hand, the built-ins are still available
|
||||
via the C<CORE::> pseudo-package.
|
||||
|
||||
=head1 NOTE
|
||||
|
||||
While this class is currently implemented using the Class::Struct
|
||||
module to build a struct-like class, you shouldn't rely upon this.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Tom Christiansen
|
||||
91
database/perl/lib/Time/localtime.pm
Normal file
91
database/perl/lib/Time/localtime.pm
Normal file
@@ -0,0 +1,91 @@
|
||||
package Time::localtime;
|
||||
use strict;
|
||||
use 5.006_001;
|
||||
|
||||
use Time::tm;
|
||||
|
||||
our (@ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS, $VERSION);
|
||||
our (
|
||||
$tm_sec, $tm_min, $tm_hour, $tm_mday,
|
||||
$tm_mon, $tm_year, $tm_wday, $tm_yday,
|
||||
$tm_isdst
|
||||
);
|
||||
|
||||
BEGIN {
|
||||
use Exporter ();
|
||||
@ISA = qw(Exporter Time::tm);
|
||||
@EXPORT = qw(localtime ctime);
|
||||
@EXPORT_OK = qw(
|
||||
$tm_sec $tm_min $tm_hour $tm_mday
|
||||
$tm_mon $tm_year $tm_wday $tm_yday
|
||||
$tm_isdst
|
||||
);
|
||||
%EXPORT_TAGS = ( FIELDS => [ @EXPORT_OK, @EXPORT ] );
|
||||
$VERSION = 1.03;
|
||||
}
|
||||
|
||||
sub populate (@) {
|
||||
return unless @_;
|
||||
my $tmob = Time::tm->new();
|
||||
@$tmob = (
|
||||
$tm_sec, $tm_min, $tm_hour, $tm_mday,
|
||||
$tm_mon, $tm_year, $tm_wday, $tm_yday,
|
||||
$tm_isdst )
|
||||
= @_;
|
||||
return $tmob;
|
||||
}
|
||||
|
||||
sub localtime (;$) { populate CORE::localtime(@_ ? shift : time)}
|
||||
sub ctime (;$) { scalar CORE::localtime(@_ ? shift : time) }
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Time::localtime - by-name interface to Perl's built-in localtime() function
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Time::localtime;
|
||||
printf "Year is %d\n", localtime->year() + 1900;
|
||||
|
||||
$now = ctime();
|
||||
|
||||
use Time::localtime;
|
||||
use File::stat;
|
||||
$date_string = ctime(stat($file)->mtime);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module's default exports override the core localtime() function,
|
||||
replacing it with a version that returns "Time::tm" objects.
|
||||
This object has methods that return the similarly named structure field
|
||||
name from the C's tm structure from F<time.h>; namely sec, min, hour,
|
||||
mday, mon, year, wday, yday, and isdst.
|
||||
|
||||
You may also import all the structure fields directly into your namespace
|
||||
as regular variables using the :FIELDS import tag. (Note that this still
|
||||
overrides your core functions.) Access these fields as
|
||||
variables named with a preceding C<tm_> in front their method names.
|
||||
Thus, C<$tm_obj-E<gt>mday()> corresponds to $tm_mday if you import
|
||||
the fields.
|
||||
|
||||
The ctime() function provides a way of getting at the
|
||||
scalar sense of the original CORE::localtime() function.
|
||||
|
||||
To access this functionality without the core overrides,
|
||||
pass the C<use> an empty import list, and then access
|
||||
function functions with their full qualified names.
|
||||
On the other hand, the built-ins are still available
|
||||
via the C<CORE::> pseudo-package.
|
||||
|
||||
=head1 NOTE
|
||||
|
||||
While this class is currently implemented using the Class::Struct
|
||||
module to build a struct-like class, you shouldn't rely upon this.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Tom Christiansen
|
||||
33
database/perl/lib/Time/tm.pm
Normal file
33
database/perl/lib/Time/tm.pm
Normal file
@@ -0,0 +1,33 @@
|
||||
package Time::tm;
|
||||
use strict;
|
||||
|
||||
our $VERSION = '1.00';
|
||||
|
||||
use Class::Struct qw(struct);
|
||||
struct('Time::tm' => [
|
||||
map { $_ => '$' } qw{ sec min hour mday mon year wday yday isdst }
|
||||
]);
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Time::tm - internal object used by Time::gmtime and Time::localtime
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
Don't use this module directly.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module is used internally as a base class by Time::localtime And
|
||||
Time::gmtime functions. It creates a Time::tm struct object which is
|
||||
addressable just like's C's tm structure from F<time.h>; namely with sec,
|
||||
min, hour, mday, mon, year, wday, yday, and isdst.
|
||||
|
||||
This class is an internal interface only.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Tom Christiansen
|
||||
Reference in New Issue
Block a user