Random header image... Refresh for more!

Time Is An Illusion, Anyway

This week has been rough.

I’ve been working through a new strategy that promises to make our company’s deployments to production at least ten times faster than our current process.  While it’s going to make things easier for us in the end, getting there is anything but easy.

I’ve gotten permission errors.

I’ve hit ACL problems.

I’ve come across registry access violations.

I’ve had writeable UNC shares turn read-only.

I’ve seen application pools die and IIS refuse to start.

I watched installers fail to run remotely, successfully run locally, then fail to run locally under the exact same circumstances two minutes later.

I even had UAC end up locking my account because it decided that I’m not trustworthy enough to enter a password for a installation tool from an unelevated command prompt.

It’s been a never ending stream of failure and frustration.

I thought I’d seen it all.  Then today happened.

I left the office last night feeling really good about where things were at.  I finally worked through all of the permission problems, all of the path access issues.  Everything was running under the right accounts, and stuff was flowing through the system and installing flawlessly.

Put a checkmark on the list, I’m done!

I planned on coming in this morning, updating some release instructions, then moving on to the second piece of the process.  The second piece is very similar to the first, so I figured I’d breeze through the day and have everything up and running in time to leave work during rush hour.  I want to preface the release instructions with a link to the progress I made, so I go to the site that installed flawlessly last night and try to pull it up.

IIS Yellow Screen Of Death

Ah crap.  That sucks.  I sort of expected something like that, though.  We’re doing things that are wild and new for our company, and most of the problems we’re seeing are the result of inexperience with the technology.  I figured the site would have died sometime in the middle of the night for some reason or another.  I figured that it would be something we’d just overlooked, something easy to fix.

I didn’t figure on getting an error message that was last seen in 1997.

An error occurred loading a configuration file: Failed to start monitoring changes to ‘[filename]’ because the network BIOS command limit has been reached.

The network BIOS command limit has been reached…?  WTF?

Am I running low on “System Resources” now, too?

What in the hell does that mean?  Network BIOS command limit…

I do a search and immediately find many other people with the same problem, all of whom are saying that the KB article the error message points at is completely useless.  Instead, they say you have to pull a registry setting out of thin air, and that’ll solve your problems. 1  Turns out that the way IIS monitors file system changes on UNC shares can clog the tubes, and that magical reg key tries to unclog them.  Eventually, I get it to work and carry on with the tasks of the day.

It all goes fairly well and smoothly.  As I had hoped, the experience from setting up the first piece of the deployment process translated very closely to setting up the second piece.  It only took two hours to get through the same amount of the process that had taken three days the first go around.  And most of that two hours was spent keeping detailed instructions so that next time only takes half an hour and the time after that can be fully automated.

All is well.

In the very last part of the setup, I had to install a Windows component, then reboot the box. 2  I give the box a minute, then try to remote back in.  Terminal Services Client blinks at me, but does nothing.  I try again and again it blinks.  A third time, and I get a failed to connect message.  Fine, maybe it’s still rebooting.  I give it another minute and try again.

Remote Desktop cannot connect to the remote computer because the authentication certificate received from the remote computer is expired or invalid.  In some cases, this error might also be caused by a large time discrepancy between the client and server computers.

Uh, okay…  Never seen that error before.  Did the network flip out, is the server confused?  Maybe I just have to give it a bit more time before trying to connect again.

So I give it another minute.  It gives me the error again.

The second sentence intrigues me.  A large time discrepancy, eh?  Hmmm…

Last year, during a brief foray into temporal mechanics, I learned all about how Windows deals with time and time synchronization.  One of the things I found was a command line tool in Windows called “w32tm”.  That program has a command line switch, “/stripchart”, which can show you how far off your system’s clock is from that of another system.  Normally, when dealing with a pair of computers on a corporate network, tied to a domain, you’ll find that the clocks will only differ by a few seconds at most.  You can run w32tm /stripchart and watch as the two machines drift around in time, speeding up, slowing down, and dancing around the time synchronization point.  Try, for instance, “w32tm /stripchart /computer:time.windows.com”, and see where you are in comparison to the Windows time server.

Anyway, w32tm’s stripchart seemed like the perfect tool to investigate this potential “large time discrepancy”.  What would it be, an hour, two hours, maybe even a day?

The current time is 3/3/2011 4:52:43 PM.
16:52:43 d:+00.0020000s o:-31607977.8967224s  [@                          |                         ]

The current time is correct.  I ran it at 4:52 PM on March 3rd, 2011.  “d:” is, I believe, the “delay”, the round trip time between the servers.  2 ms response time.  Not bad.  And “o:” is the time offset, in seconds, between your computer and the remote computer.

o:, in this case, is -31.6 million seconds.

In case you don’t feel like doing the math, 31.6 million seconds is one year, 19 hours, 59 minutes, and 37 seconds.

The computer rebooted and came back one year, 19 hours, 59 minutes, and 37 seconds in the past.  I think I’d agree with the error’s assessment of a “large time discrepancy”.

The computer now believes that it is March 2nd, 2010, at around 8:50 PM.  And I can’t convince it otherwise.  If I go on the box and try to change the time manually, it immediately corrects itself to March 2nd, 2010.

Now, ordinarily, I’d say that such an error was the result of time synchronization service gone awry, or maybe some failing system hardware.  However, given the events of this past week and all of the strange behavior that I’ve seen, I believe it is equally likely that that particular computer has actually travelled back in time and is running in our datacenter exactly one year, 19 hours, 59 minutes and 37 seconds ago.

Now, if you’ll excuse me, I have a hole in time to exploit and profit from.

  1. Under HKLM\Software\Microsoft\ASP.NET, create a new value called “FCNMode” and set it to 2 to change the way IIS monitors file change notifications, or set it to 1 to disable the notifications altogether.  Other sites suggest the same value, but under the HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\ASP.NET key instead.  Try both.  Then reboot. []
  2. Why they haven’t figured out the whole rebooting thing for the case where I just installed a minor application, I don’t know, but whatever… []

March 3, 2011   No Comments

Temporal Mechanics: Changing the Speed of Time, Part II

So, you want to change the speed of time, eh?  Now, I trust that you’re only going to change this on your own computer and not do anything to your coworker’s computer when they go for coffee and leave their machine unlocked and unattended for a few minutes, correct?  Okay, let’s begin.

First, before you go changing the speed of time, let’s see how fast time is going.  In order to do that, there’s a Win32 function called “GetSystemTimeAdjustment”.  Here’s the signature:

BOOL WINAPI GetSystemTimeAdjustment(
    __out PDWORD lpTimeAdjustment,
    __out PDWORD lpTimeIncrement,
    __out PBOOL lpTimeAdjustmentDisabled
);

Of course, Win32 C is terribly ugly and nasty to work with, so I’m going to do this in C#.  That means a P/Invoke, but at least I won’t have to deal with __out PDWORDs and the like.  Here’s that bit:

[DllImport("kernel32.dll")]
public static extern bool GetSystemTimeAdjustment(out uint timeAdjustment, out uint timeIncrement, out bool timeAdjustmentDisabled);

It’s still sort of ugly, but not nearly as totally ugly, so it’s all right.  If you’re not completely familiar with all of this DllImport stuff and static externs and out parameters, that’s okay.  I’m going to mock your ignorance of the language, but aside from that, it’s no big deal.  Now let’s give it a call and see who answers.

uint timeAdjustment;
uint timeIncrement;
bool timeAdjustmentDisabled;

GetSystemTimeAdjustment(out timeAdjustment, out timeIncrement, out timeAdjustmentDisabled);

Console.WriteLine("Adjustment: {0} Increment: {1} Adjustment Disabled: {2}", timeAdjustment, timeIncrement, timeAdjustmentDisabled);

On my current home machine (XP, not on a domain), I get this as the output:

Adjustment: 156250  Increment: 156250  Adjustment Disabled: True

If you recall my previous entry on this topic, you’ll remember that the Windows Time Service would add a certain number of 100ns units to the system clock every 15.6 ms or so.  The Adjustment number is the number of 100ns ticks it will add, and the Increment number is the number of 100ns ticks of supposedly “real” time that will elapse between time adjustments.  Obviously, Increment is not completely accurate, it doesn’t mean precisely 15.625 ms of real world time, because if it did, then Adjustment would always equal Increment, and your clock would be completely accurate with no drift whatsoever, so there would be no need for automatic adjustments.  In this case, Adjustment does equal Increment.  However, if you look at the final value, Adjustment Disabled is true.  That means the automatic time adjustments are disabled.  When that’s disabled, the Windows Time Service isn’t doing any of the gradual corrections that I talked about in the last post, instead, it considers your physical clock ticks to be good enough.  Your computer clock will likely drift over time.  On my machine, I’m not joined to a domain or anything like that.  Instead, I’m configured to talk to time.windows.com once a week and resync my clock.

Of course, printing that information out just once is somewhat boring.  I strongly recommend putting it in a loop and printing it out every couple of seconds.

while (true)
{
    GetSystemTimeAdjustment(out timeAdjustment, out timeIncrement, out timeAdjustmentDisabled);
    Console.WriteLine("Adjustment: {0} Increment: {1} Adjustment Disabled: {2}", timeAdjustment, timeIncrement, timeAdjustmentDisabled);
    Thread.Sleep(5000);
}

If you’re on a domain or otherwise have your system clock actively and frequently being kept in line by something, I would strongly urge you to do the following fun experiment at this point.

  1. Compile this program.
  2. Run this program.
  3. If Adjustment Disabled == false, put your computer’s clock ahead or back a minute or so.
  4. Watch the program for a while.

You’ll see something like this over the course of the next 20 minutes or so (Your numbers will vary).

Adjustment: 156250  Increment: 156250  Adjustment Disabled: False
Adjustment: 145125  Increment: 156250  Adjustment Disabled: False
Adjustment: 154412  Increment: 156250  Adjustment Disabled: False
Adjustment: 156159  Increment: 156250  Adjustment Disabled: False
Adjustment: 156225  Increment: 156250  Adjustment Disabled: False
Adjustment: 156247  Increment: 156250  Adjustment Disabled: False
Adjustment: 156249  Increment: 156250  Adjustment Disabled: False
Adjustment: 156250  Increment: 156250  Adjustment Disabled: False

Remember that adjustment is how much time is being added to your system’s clock at each tick.  The Windows Time Service synced with your domain controller and realized that your system time was off by about a minute.  Because of that, it decided that it needed to run slow for a bit to allow reality to catch up.  When Adjustment went to 145125, it meant that every 15.6 ms, the computer only added 14.5 ms to its timer.  A difference of only 1.1 ms per tick, but when you consider that there are about 64 ticks in a second and 60 seconds in a minute, you’re talking a difference of over 4 seconds per minute of real time.  Which means that at a rate like that, every minute of real time will only be 56 seconds in warped computer time.  That will very quickly add up and within 15 minutes, that minute you set your clock off will be made up.

However, the Time Service is cautious and doesn’t wish to over correct, so it will shoot for lower than the full time offset.  That means basically that instead of trying to close the full minute in one shot, it’ll pull back only 50 seconds.  Then it will go seven seconds, then two seconds, then a fraction of a second.  My experience with the time service is that the adjust will try to softly land on Increment, getting closer and closer until the two are even.

Under normal circumstances, if Adjustment is higher than Increment, it means that your clock is running slow and the Time Service is speeding up your system’s time to catch up with reality.  If Adjustment is lower than Increment, your clock is ahead and the Windows Time Service will put on the brakes and decelerate time to allow reality to catch up.

Normal circumstances aren’t much fun, though.  Let’s go for a few abnormal circumstances, shall we?

I did promise that you would be able to change the speed of time on your own.  That means no Time Service involvement.  If you want your clock to take off like a Prius with a stuck accelerator and janky brakes, I can help you make that happen.

There’s a GetSystemTimeAdjustment, so naturally, there’s gotta be a SetSystemTimeAdjustment.

BOOL WINAPI SetSystemTimeAdjustment(
    __in DWORD dwTimeAdjustment,
    __in BOOL bTimeAdjustmentDisabled
);

Let’s sharpen that up a bit…

[DllImport("kernel32.dll")]
public static extern bool SetSystemTimeAdjustment(uint timeAdjustment, bool timeAdjustmentDisabled);

It should be noted that the DWORD parameter of the C turns into a uint argument.  Initially, I had written the P/Invoke signature using a signed integer.  I thought it would be fun to set the time adjustment to -156250, to watch the clock go backwards.  Unfortunately, when -156250 gets treated as an unsigned integer, it becomes, well, 4294811045.  So, instead of watching my computer’s clock run backwards, I saw it zoom to the future at a rate of a day every 3.14 seconds.  Which, I have to admit, was totally awesome.

Anyway, I strongly suggest that you first call GetSystemTimeAdjustment and see what the adjustment value is first, so that you’ll have a good idea of where you want to set the value to get the effect you want.  Rememember, double the base and the clock goes twice as fast, cut the base in half and your clock moves at half speed.  I haven’t found a way to go back in time yet, but that sort of thing only causes universe destroying paradoxes, so perhaps that’s for the best.

So, now, if you run it, giving some reasonable (or unreasonable) number as the value of Adjustment, what you’ll probably find is that ABSOLTELY NOTHING happens.  This is, of course, the unseen impact of the Temporal Security Agency preventing you from tampering with time. 1  They don’t like it when you mess with that sort of thing.  To get around that, you have to ask for the “SE_SYSTEMTIME_NAME” privilege beforehand.  I have no idea at all what that means, I just know that the documentation says you need it and offers you no practical guidance whatsoever as to how you’re supposed to acquire it.

What to do when you’re faced with obtuse documentation on an obscure subject like Win32 Privilege Tokens?  Steal the code from the Internet, of course.

        //The code in this block is not mine and I make no claims to it.
        //I don't really even know what it's doing...
        #region Code stolen from the Internet.
        private const int ANYSIZE_ARRAY = 1;
        private const string SE_SYSTEMTIME_NAME = "SeSystemtimePrivilege";
        private const int SE_PRIVILEGE_ENABLED = 0x00000002;
        private const int TOKEN_QUERY = 0x0008;
        private const int TOKEN_ADJUST_PRIVILEGES = 0x0020;

        [StructLayout(LayoutKind.Sequential)]
        public struct LUID
        {
            public int LowPart;
            public int HighPart;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct LUID_AND_ATTRIBUTES
        {
            public LUID Luid;
            public int Attributes;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct TOKEN_PRIVILEGES
        {
            public int PrivilegeCount;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = ANYSIZE_ARRAY)]
            public LUID_AND_ATTRIBUTES[] Privileges;
        }

        [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
        public static extern bool OpenProcessToken(int ProcessHandle, int DesiredAccess, ref int TokenHandle);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern int GetCurrentProcess();

        [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
        public static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, [MarshalAs(UnmanagedType.Struct)] ref LUID lpLuid);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
        public static extern bool AdjustTokenPrivileges(int TokenHandle, int DisableAllPrivileges, [MarshalAs(UnmanagedType.Struct)] ref TOKEN_PRIVILEGES NewState, int BufferLength, [MarshalAs(UnmanagedType.Struct)] ref TOKEN_PRIVILEGES PreviousState, ref int ReturnLength);

        public static bool AdjustPrivileges()
        {
            TOKEN_PRIVILEGES tkNew = new TOKEN_PRIVILEGES();
            tkNew.Privileges = new LUID_AND_ATTRIBUTES[ANYSIZE_ARRAY];
            TOKEN_PRIVILEGES tkOld = new TOKEN_PRIVILEGES();
            tkOld.Privileges = new LUID_AND_ATTRIBUTES[ANYSIZE_ARRAY];

            LUID luid = new LUID();
            int token = -1;
            int oldluidSize = 0;

            if (LookupPrivilegeValue(null, SE_SYSTEMTIME_NAME, ref luid))
            {
                if (OpenProcessToken(GetCurrentProcess(),
                TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref token))
                {
                    tkNew.PrivilegeCount = 1;
                    tkNew.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
                    tkNew.Privileges[0].Luid = luid;
                    int luidSize = Marshal.SizeOf(typeof(TOKEN_PRIVILEGES));
                    if (AdjustTokenPrivileges(token, 0, ref tkNew, luidSize, ref tkOld, ref oldluidSize))
                    {
                        return true;
                    }
                }
            }
            return false;
        }
        #endregion Code stolen from the Internet.

That code isn’t mine.  I don’t know whose it is and I don’t know what it does exactly.  All I know is it magically makes all the time stuff work, and for that I am grateful.  Anyway, now all you should have to do is add a call to AdjustPrivileges() at some point before you try to call SetSystemTimeAdjustment.  Like so:

    if (!AdjustPrivileges())
    {
        throw new Exception("AdjustPrivileges failed.");
    }

    if (!SetSystemTimeAdjustment(312500, false))
    {
        throw new Exception("SetSystemTimeAdjustment failed.");
    }

 

Before you run this, let me just warn you not to run this.  I don’t know what it’s going to do to your computer.  You’re changing time randomly.  That can never be a good thing.  So don’t do it.

Since you’re going to do it anyway, here’s two ways to try to get yourself out of an uncontrolled time slide.  Kill the program first, then try to resynchronize your clock by going into your taskbar clock and telling it to update the time.  If that doesn’t work, stop and restart the Windows Time Service.  And if that doesn’t work, well, I told you not to do it and you didn’t listen to me, so don’t go blaming me.

The source code is located here, in case you don’t feel like typing in everything by hand: http://www.mathpirate.net/svn/Projects/SpeedOfTime/

Now, make sure you have a watch or a clock or something that will display seconds and that’s not tied to your computer in any way.  Make sure it’s roughly synchronized (within a second or two) of your computer.  Then press play and do the time warp.

What’s checked in will cause your computer to travel through time twice as fast as reality.  You can, of course, tweak the number and modify how fast or slow you want to go.  Pay attention to the read-out, though.  If the Windows Time Service is actively adjusting your time, it will likely override your temporal anomaly and either fix the clock outright, or at least modify the adjustment so you start to return to normality.  To prevent unwanted chronometric realignment, you may want to stop the Windows Time Service while you’re messing around.

For those of you smart enough not to play the home game, here’s a video which will demonstrate the effects of time compression and dilation.

And now, here’s the effects of a non-linear temporal anomaly.

  1. I know you’re there, Agent Blackwood! []

March 20, 2010   No Comments

Temporal Mechanics: Changing the Speed of Time

Until last week, I never really thought about my computer’s system clock.  I simply thought that it hummed along at a constant, smooth rate, always heading toward the future.  I figured that once a week, it would call a time server tethered to atomic clock somewhere and make sure that it’s in sync.  If not, it would immediately correct the time and go about its business for another week.

Turns out, I was wrong.  The way Windows handles time, particularly when a member of a domain is a tad more complicated.  And, as it turns out, you generally want it that way.

Think about the implications of the method I described above.  If your system clock is bad, that means that in the span of a week, you can get ten or fifteen minutes off of real time.  Then, in one big jump, your clock gets corrected, jumping your system ten minutes into the future, or forcing it to re-live the past ten minutes over again.  On your home system, that’s probably not a huge deal.  Timestamps on all the movies you’re downloading might be off by a bit, big deal.  But in the business world, that would be bad.  Your Outlook reminders would fire off at different times for different people, e-mails and instant messages would have odd timestamps, and the Kerberos system used for authentication would randomly block people for being outside of an acceptable time range.

In short:  Mayhem.

So, when you’re joined to a domain, Windows typically gets a bit stricter over how it handles time synchronization.  It does this to keep all machines in line.  That’s why you hear the meeting reminder bell rising from fifteen machines in your cubicle farm at nearly the same moment.  The Windows Time Service is keeping everyone synchronized.

Now, there’s a good chance that you already knew that, if you’ve been around networks long enough.  But, there’s an equally good chance that you don’t know how the Windows Time Service is keeping everyone synchronized.  I had always assumed that the Time Service was keeping everyone in sync by resetting everyone’s clocks to the correct time every hour or so, and that no one ever noticed because your internal system clock kept good time.  In other words, at 1:03:27 PM, your computer would be told that it was 1:03:27 PM, so it would set the time, and it would still be 1:03:27 PM.

That ain’t what it does.

In fact, your computer’s clock doesn’t really matter to Windows.  Windows really only pays attention to it when it first starts up.  Beyond that, the magic of the Windows Time Service keeps things in line.

The Windows Time Service doesn’t really like setting your time at all, once it’s running.  It will do so, if your clock gets too far away from the time authority, but in general, it won’t set your time.  So, how does it keep a flock of computers running in perfect Outlook harmony?

Simple.

It changes the speed of time.

I’ll get into that, but first, let’s change your perception of time.  Time, at least from the perspective of a Windows machine, is not linear.  Instead, it’s a step function.  The exact values vary from system to system, but these are the basics:  Every 15 ms or so, the clock bumps its time value by 15 ms or so.  If you’ve ever done a Console.WriteLine(DateTime.Now.Ticks); inside a tight while loop1, you’ve seen the effects of this.  The value will remain constant for many iterations, then leap up, then stay at the new level for a while, then jump.  Similarly, if you’ve ever mistakenly tried to use DateTime for recording performance numbers, you’ve run into something similar.  All of your perf times are reporting 0ms, 15ms, or 31ms.  It’s always one of those three.  Never 7, never 12, never 24.  That’s because the resolution of the time is 15ms.

In other words, time looks like this:

The smooth black line is “real time” and the stepping red line is your computer’s time.

All is well in graph-land.  The time your computer reads might move in discrete chunks, but it’s always centered around real time, so you’re never more than 7.5 ms off of reality.

But what happens if the clock in your computer is bad?  The quartz crystal has gone on a vacation to a big sphinx with the Jackdaws or the cesium atom is vibrating 9192631771 times a second.  Your computer will think that it’s adding 15ms, but it’s actually adding slightly more or less time.  Let’s take a 5% error rate.  For every 15 ms of real time, your computer adds 15.75 ms to its clock.  That looks like this:

You’ve gone off the chart.  The error accumulates and time starts drifting.  At the end of this sample graph, which represents only 135 ms, your clock has already drifted so far that it now will never be correct.  At this rate, after ten minutes, you’ll be 30 seconds off.

Obviously, that’s not good.  What the system could do is reset your clock every ten minutes to the correct time.  Except that you’d notice a jump like that and you’d get annoyed.  Granted, 5% is a large error for a system clock, but the premise is the same regardless of the size of the error.  Small errors add up to big problems.  Even if you only drifted a second every ten minutes, that one second skip would cause trouble to enough people that it would be a major issue.  So, like I said, the Windows Time Service will change the speed of time to correct the clock.

It’s a bit like putting your finger on the second hand of a clock.  You can push it forward gently and the clock will move ahead, or you can resist the motion and the clock will fall behind.  That 15ms that the system adds to the clock is just a number.  On my machine, that number is 156250.2  That’s the number of 100ns units of time that will get added to the clock every time it ticks. 3  But if your clock is too far ahead, all the system has to do is add a smaller number (Say, 150000) for a period of time, causing your computer’s clock to slow down, and letting reality catch up.

Back to the graph, this time with a 50% error for illustration purposes.

It’s adding 22.5ms for every 15ms of real time.  Very quickly, your clock is going off the rails.  Let’s change the speed of time and fix this problem.

The Windows Time Service saw the fact that the time was way off and changed the speed of time, slowing down the clock to two-thirds of its normal speed.  It started adding only 10ms of computer time every 15ms of real time.  This solved the problem very quickly, but has the unfortunate side effect of leaving your computer’s clock running too slow.  Now, instead of zooming ahead, it’s going to be falling further and further behind reality.  The solution, of course, is to speed time back up.

Now, the corrections don’t happen on this scale.  This is a huge simplification of the bizarre reality you’ll uncover if you ever watch the Windows Time Service work its magic.  Usually you’ll see something like a drift of 20ms over 10 minutes, then over the next ten minutes, the time service will slow the clock to lose those extra 20ms.  All day long, you’ll see your system drift in and out of phase with reality, but it should never get that far out of tune, and you’ll never notice what it does just by watching the clock.

Unless, of course, you deliberately set your clock ahead or behind…

You have to be careful, because the time service has a couple of cutoff thresholds where it will force a corrective time jump in order to fix the problem.  However, if you stay within those thresholds, you can watch w32time do some pretty awesome things.  Like make your system time gain seven minutes over the course of five real minutes, or make every second last two seconds.

TAKE THAT, EINSTEIN.

Not that I’m suggesting you try this or anything, but while you’re at work tomorrow (On a computer that’s on a domain and synching regularly with an authoritative time source), get some popcorn, set your clock ahead or behind about 3.5 minutes, and compare your computer’s clock (You have to watch the view with the second hand) to some external time source, like your watch or cell phone.  When I’ve done this, it’ll start slowly.  The time will remain where it is for a while, then all of a sudden, time will accelerate (or decelerate) drastically for a period of a few minutes, then it will level off.  Within about half an hour, that 3.5 minute gap will be pretty much closed, and it never had to skip or repeat a second.

Of course, the specifics change with different machines, different Windows versions, and different network time configurations.  You may have to fiddle and twizzle with knobs and dials to see any noticeable result.  Fortunately, there’s Registry Settings located under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w32time that give you lots of knobs and dials to fiddle and twizzle.  You don’t necessarily want to mess with any of them, and I’d strongly recommend finding a reference to what they do before you set out on a time bending adventure using them.  I’d also strongly recommend exporting a backup copy of that reg key before you go mucking about, otherwise be prepared to be late for everything for the rest of your life.

Oh, and did I mention that you can change the speed of time yourself?  That makes this so much more fun, especially if it’s not your computer that you’re changing the speed of time on.  I’ll show you how to do that next time.

(If there is a next time…  I think I may have triggered a paradox and my hand seems to be disappearing now…)

  1. Go ahead, try it. []
  2. So, I lied.  It’s not 15ms, it’s 15.6ms, but I’m not typing 15.6ms all the time. []
  3. 100 nanoseconds is the base unit of time in the Windows world.  Windows File Time is given in the number of 100ns ticks since January 1st, 1601.  Why that date, I’m not sure, but I think it has something to do with the Illuminati and a Star Trek fan who wasn’t good at remembering numbers exactly.  There are 10000 of these in 1ms, and 10000000 of them in a second. []

March 14, 2010   2 Comments