http://qs321.pair.com?node_id=660460


in reply to Simulating the Future

Update 2: This module has been cleaned up a little bit and some small features added (not updated in the code in this node), and I've uploaded it to CPAN as Time::Fake. It will appear on CPAN after the normal processing time...

Here's a little module that I just threw together. It overrides the builtin time sub (Update: and also localtime and gmtime) to adjust the output by some offset:

package TimeOffset; sub import { my $pkg = shift; my $offset = shift || "+0"; if ($offset !~ /^[+-]/) { $offset = $offset - time; } *CORE::GLOBAL::time = sub { CORE::time() + $offset }; *CORE::GLOBAL::localtime = sub { return @_ ? CORE::localtime(@_) : CORE::localtime(CORE::time() + $offset); }; *CORE::GLOBAL::gmtime = sub { return @_ ? CORE::gmtime(@_) : CORE::gmtime(CORE::time() + $offset); }; } 1;
You can use this as follows:
use TimeOffset '+3600'; # pretend it's 1hr in the future
or
use TimeOffset '-60'; # pretend it's 1min in the past
or
use TimeOffset 12345678; # pretend the program was started # at 12345678 epoch seconds
This is just a proof of concept but you can probably extend it to however your code figures out the current time. I.e, there may be other ways to obtain the time in perl that I haven't thought of.

Perhaps I could make this a little nicer, package it up, and send it off to CPAN? That is, if something like this really isn't on CPAN already..

Update: some caveats that I can think of, off the top of my head:

blokhead

Replies are listed 'Best First'.
Re^2: Simulating the Future
by dynamo (Chaplain) on Jan 04, 2008 at 19:57 UTC
    This looks more like what I was getting at. Thanks. I'd say package it up, I'd have used it if it were there this morning. The competition requires a compile.

    - d

Re^2: Simulating the Future
by dsheroh (Monsignor) on Jan 05, 2008 at 19:38 UTC
    Very nice... A couple extra ideas, which may or may not already be in the changes you made before sending it to CPAN:

    - Change $offset from my to our (or add a method for setting it) so that tests can, e.g., do something now (at an offset of +0) which expires in an hour, then set offset to +3600 and check whether it has expired.

    - Add an our $fixed_time which, if defined, returns that time (instead of actual time + offset) for all calls. This would be useful for cases where you're testing that a sub stores the time correctly and don't want to have to worry about whether the system clock rolled over from 12345678 to 12345679 between when the time is stored and when you test the stored value's correctness.