steves has asked for the wisdom of the Perl Monks concerning the following question:

Is there any way within Perl to make the Perl script think it's running at a date/time other than the current date/time?

Replies are listed 'Best First'.
Re: faking real date/time
by Mr. Muskrat (Canon) on Feb 07, 2004 at 17:30 UTC

    That all depends on how you are currently retrieving the date and time now doesn't it? You might be able to simply do something like:

    #my @datetime = localtime(); my @datetime = (1, 0, 0, 1, 0, 99, 5, 0, 0); # Party like it's 1999!

Re: faking real date/time
by Abigail-II (Bishop) on Feb 07, 2004 at 17:26 UTC
    Perl doesn't have a notion of time, so I'm not sure what you really want to ask. If a Perl program needs to know the current time, it'll make perl ask the OS.

    Abigail

Re: faking real date/time
by calin (Deacon) on Feb 07, 2004 at 17:50 UTC

    Depending on OS, you could intercept the time(2) libc call or equivalent function with the LD_PRELOAD mechanism or similar.

Re: faking real date/time
by Vautrin (Hermit) on Feb 07, 2004 at 19:09 UTC
    Can you provide more details about exactly what you're trying to do? It's really hard to give you good advice without understanding the problem better. I can think of a couple of different things you might want.

    Want to support the EFF and FSF buy buying cool stuff? Click here.
Re: faking real date/time
by ysth (Canon) on Feb 09, 2004 at 10:19 UTC
    You can override various time-returning functions via the mechanism documented in perlsub:
    package SetTime; use warnings; use strict; use Exporter (); our @ISA = 'Exporter'; our @EXPORT = qw/time localtime gmtime set_time/; our $VERSION = 0.01; sub import { my $pkg = shift; $pkg->export("CORE::GLOBAL", "time", "localtime", "gmtime"); $pkg->export(scalar(caller(0)), "set_time"); } my $time; sub set_time { $time = shift } sub time () { defined($time) ? $time : CORE::time; } sub localtime (;$) { @_ ? CORE::localtime($_[0]) : defined($time) ? CORE::localtime($time) : CORE::localtime(); } sub gmtime (;$) { @_ ? CORE::gmtime($_[0]) : defined($time) ? CORE::gmtime($time) : CORE::gmtime(); } 1;
    But beware of conflict with other modules that override these (offhand, Time::localtime and Time::gmtime do this), or other ways of getting the time (POSIX, or other XS modules).
Re: faking real date/time
by ysth (Canon) on Feb 09, 2004 at 04:12 UTC
    No idea what exactly your looking for, but you can influence what the -M, -A, and -C operators consider the base time by setting $^T.

      Sorry I wasn't clear. $^T is along the lines of what I'm looking for, but I also already thought of this. What I want is to make all time calls transparently return times relative to some known starting point rather than the current time; i.e., make it look like the script is running in the past or future. If $^T were also used as some sort of relative base time, that seems like it could work. But it's not used that way so time() and other calls return the true time.

      I'd have two uses for something like this:
      • Testing date/time interfaces;
      • Forcing certain scripts to run "back in time" for the purposes of creating specific time stamped files, or whatever.
      I understand the dangers and tradeoffs of doing this. I just wanted to know if it was possible. Setting a local $^T value is along the lines of what I was looking for, only with more widespread effect.