filemtime & "daylight savings time" problem.

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
WaldoMonster
Forum Contributor
Posts: 225
Joined: Mon Apr 19, 2004 6:19 pm
Contact:

filemtime & "daylight savings time" problem.

Post by WaldoMonster »

I use the filemtime stored in a database to check if a files has changed.
This is working good, but gives a problem when changing from summer to wintertime and the other way around.
Is this a windows only behavior?

What do you think of these two workarounds?
The second workaround must have an OS check if the behavior is only on a Windows system.

Instead of comparing:

Code: Select all

if ($filemtime_database == $filemtime)
I could use something like:

Code: Select all

if (CompareDaylightSavingsTime($filemtime_database == $filemtime))

function CompareDaylightSavingsTime($t1, $t2)
{
if ($t1 == ($t2 - 3600) || $t1 == $t2 || $t1 == ($t2 + 3600))
	return true;
else
	return false;
}
Or is it better to adjust the filemtime based on the current "Daylight savings time" and "Timezone" with:

Code: Select all

$filemtime += data('z', time());
if (date('I', time()))
    $filemtime -= 3600;
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Post by pickle »

Aren't these just UNIX timestamps? I know you said this was on Windows, but I think filemtime() still returns a UNIX timestamp.

What exactly is the problem?
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
User avatar
WaldoMonster
Forum Contributor
Posts: 225
Joined: Mon Apr 19, 2004 6:19 pm
Contact:

Post by WaldoMonster »

pickle wrote:Aren't these just UNIX timestamps? I know you said this was on Windows, but I think filemtime() still returns a UNIX timestamp.

What exactly is the problem?
On Windows (Windows 2003 Server) when changing from winter to summer time the filemtime will add 3600 seconds.
Also when changing the time zone the filemtime changes.
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post by Kieran Huggins »

Are you serious??? Windows bends time (and space?)!!!!

That is demented behaviour if it's true, and should be considered a bug. Only the date / hour / etc.. should be affected by DST, since the number of seconds since Jan 1, 1970 doesn't change.

Are you sure you're not strtotime()ing (or similar) the date from the files? That would affect the outcome. Posting more of your code would help us.

Cheers,
Kieran
User avatar
WaldoMonster
Forum Contributor
Posts: 225
Joined: Mon Apr 19, 2004 6:19 pm
Contact:

Post by WaldoMonster »

Kieran Huggins wrote:Are you serious??? Windows bends time (and space?)!!!!

That is demented behaviour if it's true, and should be considered a bug. Only the date / hour / etc.. should be affected by DST, since the number of seconds since Jan 1, 1970 doesn't change.

Are you sure you're not strtotime()ing (or similar) the date from the files? That would affect the outcome. Posting more of your code would help us.

Cheers,
Kieran
Here is a very simple script:

Code: Select all

<?php
clearstatcache();

$file = 'C:\test.txt';
$filemtime =  filemtime($file);

echo 'file: ' . $file . '<br>';
echo 'date: ' . date('r', time()) . '<br>';
echo 'filemtime: ' . $filemtime;
?>
I have run this script two times.
First with the current time, and the second set the clock back to 22 June:

Code: Select all

file: C:\test.txt
date: Fri, 22 Dec 2006 17:56:26 +0100
filemtime: 1166806327

file: C:\test.txt
date: Thu, 22 Jun 2006 17:57:42 +0200
filemtime: 1166809927
As you can see it is exactly 3600 seconds different from each other.

Update:
I was forgotten I had installed eAccelerator for PHP 4.4.4
But after disabling eAccelerator I got the same 3600 seconds difference.
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post by Kieran Huggins »

ugh... you could kludge around the problem with:

Code: Select all

if(date('I',$filemtime)==1) $filemtime-='3600';
Cheers,
Kieran
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Post by pickle »

Kieran Huggins wrote:ugh... you could kludge around the problem with:

Code: Select all

if(date('I',$filemtime)==1) $filemtime-='3600';
Ya, that seems to be about the best way.
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
User avatar
WaldoMonster
Forum Contributor
Posts: 225
Joined: Mon Apr 19, 2004 6:19 pm
Contact:

Post by WaldoMonster »

Kieran Huggins wrote:ugh... you could kludge around the problem with:

Code: Select all

if(date('I',$filemtime)==1) $filemtime-='3600';
Cheers,
Kieran
Sorry, your example doesn't work.
Let say a file made in the summertime gives one-hour difference when changing from summer to wintertime.
So there is one hour difference witch doesn't trigger the date('I',$filemtime)==1.
When using the current time it does work:

Code: Select all

if (date('I', time())==1) $filemtime -= 3600;
What I read in this post and on the internet this problem is only affected on Windows systems.
I want to make an update system that is working on Linux, Unix, OSX and Windows.
I hope you can give me some feedback if this problem is affected on your OS?
I already found the "daylight savings time" problem on Windows 2003, is this also affected on Windows 2000, XP and Vista?
Any feedback would be very appreciated.

Thanks,

Willem
User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Post by volka »

Same on windows xp prof sp2.
And it's not limited to php. i had the php script open in UltraEdit when the system clock changed and it told me the file was changed and wether I want to reload it :-S
User avatar
WaldoMonster
Forum Contributor
Posts: 225
Joined: Mon Apr 19, 2004 6:19 pm
Contact:

Post by WaldoMonster »

Googleing for "filemtime 3600" I found these two articles:

http://nl3.php.net/manual/nl/function.stat.php#58404
There's an important (yet little-known) problem with file dates on Windows and Daylight Savings. This affects the 'atime' and 'mtime' elements returned by stat(), and it also affects other filesystem-related functions such as fileatime() and filemtime().

During the winter months (when Daylight Savings isn't in effect), Windows will report a certain timestamp for a given file. However, when summer comes and Daylight Savings starts, Windows will report a DIFFERENT timestamp! Even if the file hasn't been altered at all, Windows will shift every timestamp it reads forward one full hour during Daylight Savings.

This all stems from the fact that M$ decided to use a hackneyed method of tracking file dates to make sure there are no ambiguous times during the "repeated hour" when DST ends in October, maintain compatibility with older FAT partitions, etc. An excellent description of what/why this is can be found at http://www.codeproject.com/datetime/dstbugs.asp

This is noteworthy because *nix platforms don't have this problem. This could introduce some hard-to-track bugs if you're trying to move scripts that track file timestamps between platforms.

I spent a fair amount of time trying to debug one of my own scripts that was suffering from this problem. I was storing file modification times in a MySQL table, then using that information to see which files had been altered since the last run of the script. After each Daylight Savings change, every single file the script saw was considered "changed" since the last run, since all the timestamps were off by +/- 3600 seconds.

This one-liner is probably one of the most incorrect fixes that could ever be devised, but it's worked flawlessly in production-grade environments... Assuming $file_date is a Unix timestamp you've just read from a file:

<?php
if (date('I') == 1) $file_date -= 3600;
?>

That will ensure that the timestamp you're working with is always consistently reported, regardless of whether the machine is in Daylight Savings or not.
http://www.codeproject.com/datetime/dstbugs.asp
Not many Windows developers seem aware of it, but Microsoft deliberately designed Windows NT to report incorrect file creation, modification, and access times. This decision is documented in the Knowledge Base in articles Q128126 and Q158588. For most purposes, this behavior is innocuous, but as Microsoft writes in Q158588,
User avatar
WaldoMonster
Forum Contributor
Posts: 225
Joined: Mon Apr 19, 2004 6:19 pm
Contact:

Post by WaldoMonster »

volka wrote:Same on windows xp prof sp2.
And it's not limited to php. i had the php script open in UltraEdit when the system clock changed and it told me the file was changed and wether I want to reload it :-S
Thanks Volka,

Maybe you find the above articles interesting.

Willem
Post Reply