php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #40568 filemtime shifted by one hour on win32
Submitted: 2007-02-20 22:28 UTC Modified: 2009-03-04 10:28 UTC
Votes:24
Avg. Score:4.3 ± 0.8
Reproduced:22 of 22 (100.0%)
Same Version:10 (45.5%)
Same OS:19 (86.4%)
From: JPlissonneauDuquene at bellhelicopter dot textr Assigned: pajoye
Status: Closed Package: Filesystem function related
PHP Version: 5.2.1 OS: win32 only - WinXP
Private report: No CVE-ID:
 [2007-02-20 22:28 UTC] JPlissonneauDuquene at bellhelicopter dot textr
Description:
------------
Hi,

PHP filemtime/fileatime/filectime (and maybe stat itself) functions should use GetFileTime() Win32API (or GetFileAttributesEx()), not stat() to retrieve the actual times from files. Otherwise the returned time is shifted by one hour in some conditions.

This (mis)behaviour is actually DOCUMENTED by Microsoft, so it does not qualify for "bogus - fix microsoft libraries" bug rejection -- Microsoft already fixed their documentation and even indicated that "This behavior is by design."

References:
http://support.microsoft.com/kb/158588
http://support.microsoft.com/kb/190315
http://msdn2.microsoft.com/en-gb/library/ms724290.aspx
http://us3.php.net/manual/en/function.stat.php#58404
http://www.codeproject.com/datetime/dstbugs.asp

Thanks!


Reproduce code:
---------------
<?php
print date(DATE_ISO8601) . ' ' . time() . "\r\n";
$summer_date = gmmktime(12,34,56,06,21,2006);
$winter_date = gmmktime(12,34,56,12,21,2006);
if (!file_exists("summer_file")) touch("summer_file", $summer_date);
if (!file_exists("winter_file")) touch("winter_file", $winter_date);
print "summer_file " . $summer_date . ' ' . filemtime("summer_file") . "\r\n";
print "winter_file " . $winter_date . ' ' . filemtime("winter_file") . "\r\n";
?>

Expected result:
----------------
D:\test>php test.php
2007-02-20T15:14:45-0500 1172002485
summer_file 1150893296 1150893296
winter_file 1166704496 1166704496

D:\test>dir
06/21/2006  08:34 AM                 0 summer_file
12/21/2006  07:34 AM                 0 winter_file


Actual result:
--------------
# NOTE - run tests in order. Test 1 will create the files.
# Do NOT remove the files before tests 2-4.

# test 1. Winter time, DST adj. checked
D:\test>php test.php
2007-02-20T17:07:47-0500 1172009267
summer_file 1150893296 1150893296
winter_file 1166704496 1166704496

# test 2. Winter time, DST adj. unchecked
D:\test>php test.php
2007-02-20T17:08:05-0500 1172009285
summer_file 1150893296 1150896896
winter_file 1166704496 1166704496
# note summer_file timestamp is now 1 hour later

# test 3. Summer time, DST adj. unchecked
D:\test>php test.php
2007-08-20T18:08:34-0400 1187647714
summer_file 1150893296 1150896896
winter_file 1166704496 1166704496
# same as test 2.
# note that time /t or GUI clock will show 17:08, while
# PHP time reports 18:08, but this is another bug.

# test 4. Summer time, DST adj. now checked
D:\test>php test.php
2007-08-20T18:11:04-0400 1187647864
summer_file 1150893296 1150896896
winter_file 1166704496 1166708096
# note that winter_file timestamp is now 1 hour later
# time /t and GUI clock jumped 1 hour later (18:11) when
# checking automatic DST adj.


D:\test>dir *_file
# after test1
06/21/2006  08:34 AM                 0 summer_file
12/21/2006  07:34 AM                 0 winter_file
# after test2
06/21/2006  08:34 AM                 0 summer_file
12/21/2006  07:34 AM                 0 winter_file
# after test3
06/21/2006  08:34 AM                 0 summer_file
12/21/2006  07:34 AM                 0 winter_file
# after test4
06/21/2006  09:34 AM                 0 summer_file
12/21/2006  08:34 AM                 0 winter_file


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-02-20 22:49 UTC] helly@php.net
They should fix the design then. And not wrongly implement stuff and make everybody follow their errors.
 [2007-02-21 14:54 UTC] JPlissonneauDuquene at bellhelicopter dot textr
Of course you can fix it the Microsoft way, i.e. in the documentation: "On Windows platforms, file times obtained through stat() filemtime() etc will vary depending on your system's daylight saving time settings. According to Microsoft, 'This is by design.' For further reference see KB190315."

But since there is a known API that returns the right information, it would IMO be better to use it rather than do nothing and blame the [insert your expletives here] design. Fixing PHP stat() and co will improve cross-platform compatibility for PHP scripts. Doing nothing will not.

PHP already fixed a lot of MS-DOS things, like path separators, so it seems to me that implementing a fix for stat() would remain consistent with that policy.
 [2007-07-20 13:53 UTC] levi_tedder at hotmail dot com
We have a system that check file sizes and timestamps, to create a list. We need to keep this system on PHP 5.2.0, since this change was introduced in 5.2.1 due to windows optimalization (?) as far as I understand, and we cannot suddenly change the timestamps in the list.

Will this be handled/changed back in any way in PHP, or do we need to create some kind of workaround?

(Sorry for adding a bug report on this, when this [suspended] bug already exist)

Levi
 [2008-03-30 17:15 UTC] kbrobst at surveyresearchpartners dot com
The same "Microsoft feature" is found under Windows Server 2003, 64-bit.  Though previous test cases are well done, this one may be helpful as well:

Try this experiment:

$timestamp_str = "2005.02.06 14:45:33";
$timestamp_pieces=split('[. :]',$timestamp_str);
$timestamp=mktime($timestamp_pieces[3], $timestamp_pieces[4], $timestamp_pieces[5], $timestamp_pieces[1], $timestamp_pieces[2], $timestamp_pieces[0]);
touch("c:\\timestamp_test.txt",$timestamp);

The file timestamp_test.txt shows up in the operating system as having a modification date of "Sunday, February 06, 2005, 2:45:33 PM" - which is the desired result.

But now look at the results of filemtime (only when in DST - it will report the correct timestamp during standard time):

$compare_timestamp=filemtime("c:\\timestamp_test.txt");
$compare_timestamp_str = date("Y.m.d H:i:s",$compare_timestamp);
echo "$timestamp ($timestamp_str) is the original timestamp.<br />\n";
echo "$compare_timestamp ($compare_timestamp_str) is the timestamp on the file.<br />\n";

The output looks like this:

1107726333 (2005.02.06 14:45:33) is the original timestamp.
1107722733 (2005.02.06 13:45:33) is the timestamp on the file.

The filemtime function reports a timestamp different from what the OS reports.

I understand the "Microsoft should do it right" concept.  But this issue is forcing me to have different PHP code based on the server OS - something I've not had to do much until now.
 [2008-05-01 00:38 UTC] louis at steelbytes dot com
I've build a PHP extension to workaround this ...

http://www.steelbytes.com/?mid=46
 [2008-07-02 10:18 UTC] marcello at vezz dot it
Very easy reproduce code (should try it during daylight saving time):

<?php
  $fullfilename='test.dll';
  $ft=filemtime($fullfilename);
  touch($fullfilename.'.md5',$ft);
  $nt=filemtime($fullfilename.'.md5');
  echo $ft.' : '.$nt;
?>

Please get test.dll from http://www.vezz.it/php/test.zip

Original file modification date: 19 feb 2008, 19.08.47

The script output:
1203440927 : 1203437327

The touched file date is one hour back.
19 feb 2008, 18.08.47 instead of 19 feb 2008, 19.08.47

In my opinion, this should really be fixed.
 [2008-12-03 13:36 UTC] pajoye@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5.3-latest.tar.gz
 
For Windows:

  http://windows.php.net/snapshots/

I changed the underlying code to use the windows native APIs. Please try it.
 [2008-12-11 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2009-03-04 10:28 UTC] pajoye@php.net
We use the new API now in 5.3+.
 [2011-08-12 09:50 UTC] ckatira at hotmail dot com
The fix in 5.3 fixes the problem with the file times reported for NTFS volumes but introduces the problem with file times returned for files in FAT volumes. Now the file times for FAT volumes are not constant across day light saving changes. To keep these constant for FAT volumes Windows stat function should be used.
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Wed Apr 23 07:02:14 2014 UTC