Backport #6385
closedmtime vie File.stat(filename).utime vs File.open(filename, 'r').mtime in Windows
Description
=begin
Seems that File.stat is not working well under Windows, specifically the mtime member.
This thing maybe related to local time (timezones) which should not because time which is used is unixtime.
On Mac works fine.
Windows: ruby 1.9.3p194 (2012-04-20) [i386-mingw32]
Mac: ruby 1.9.3p202 (2012-04-27 revision 35484) [x86_64-darwin11.3.0]
To reproduce:
RESOURCES_DIR = File.expand_path(File.dirname(FILE) + "/test")
MOD_TIME_CONTENTS = Time.at 1306527039
def test_local_os
Dir.mkdir(RESOURCES_DIR) unless (File.exists?(RESOURCES_DIR))
file_path = "#{RESOURCES_DIR}/local_os_test.test"
file = File.open(file_path, "w", 0777) do |file|
file.puts("kuku")
end
file_stats = File.stat(file_path)
p "MOD_TIME_CONTENTS: #{MOD_TIME_CONTENTS}."
p "MOD_TIME_CONTENTS: #{MOD_TIME_CONTENTS.to_i}."
p "file_stat.mtime: #{file_stats.mtime}."
p "file_stat.mtime: #{file_stats.mtime.to_i}."
p "File.mtime: #{File.mtime(file_path)}."
p "File.mtime: #{File.mtime(file_path).to_i}."
File.utime File.atime(file_path), MOD_TIME_CONTENTS, file_path
file_stats = File.stat(file_path)
p "file_stat.mtime: #{file_stats.mtime}."
p "file_stat.mtime: #{file_stats.mtime.to_i}."
p "File.mtime: #{File.mtime(file_path)}."
p "File.mtime: #{File.mtime(file_path).to_i}."
file_mtime = nil
file = File.open(file_path, 'r') do |file|
p "file.open.mtime = #{file.mtime}"
p "file.open.mtime = #{file.mtime.to_i}"
file_mtime = file.mtime
end
assert_equal(MOD_TIME_CONTENTS, file_mtime)
# !!! This fails on windows with different timezone
assert_equal(MOD_TIME_CONTENTS, file_stats.mtime)
end
Second assertion fails:
1) Failure:
test_local_os(BBFS::FileUtils::Test::TestTimeModification) [test/file_utils/time_modification_test.rb:89]:
<2011-05-27 20:10:39 +0000> expected but was
<2011-05-27 18:10:39 +0000>.
Updated by mame (Yusuke Endoh) over 12 years ago
- Status changed from Open to Assigned
- Assignee set to usa (Usaku NAKAMURA)
Updated by nobu (Nobuyoshi Nakada) over 12 years ago
- Description updated (diff)
- Category set to core
- Status changed from Assigned to Feedback
=begin
I can't reproduce this issue in JST, which does not have DST.
In what timezone are you?
=end
Updated by jonforums (Jon Forums) over 12 years ago
This oddity on Win7 32bit may be related...
C:\Users\Jon\Documents\RubyDev\sandbox>ruby --version
ruby 1.9.3p202 (2012-04-27 revision 35484) [i386-mingw32]
C:\Users\Jon\Documents\RubyDev\sandbox>ripl
open('tst', 'w') { |f| f.write '123' }
=> 3
atime = Time.utc(2012)
=> 2012-01-01 00:00:00 UTC
mtime = Time.utc(2011)
=> 2011-01-01 00:00:00 UTC
File.utime(atime, mtime, 'tst')
=> 1
s = File.stat('tst')
=> #<File::Stat dev=0x2, ino=0, mode=0100644, nlink=1, uid=0, gid=0, rdev=0x2, size=3, blksize=nil, blocks=nil, atime=2011-12-31 18:00:00 -0500, mtime=2010-12-31 18:00:00 -0500, ctime=2012-05-03 16:26:21 -0400>
atime
=> 2012-01-01 00:00:00 UTC
s.atime
=> 2011-12-31 18:00:00 -0500
mtime
=> 2011-01-01 00:00:00 UTC
s.mtime
=> 2010-12-31 18:00:00 -0500
And I've noticed this as part of make test-all TESTS='pathname'
- Failure:
test_utime(TestPathname) [c:/Users/Jon/Documents/RubyDev/ruby-git/test/pathname/test_pathname.rb:934]:
<2000-01-01 00:00:00 UTC> expected but was
<1999-12-31 18:00:00 -0500>.
Updated by kolmanv (Kolman Vornovitsky) over 12 years ago
Here is my run on the same code seems to work :
Maybe the problem is at Time.at
kolman@KOLMAN-PC ~
$ irb
irb(main):001:0> open('tst', 'w') { |f| f.write '123' }
=> 3
irb(main):002:0> atime = Time.utc(2012)
=> 2012-01-01 00:00:00 UTC
irb(main):003:0> mtime = Time.utc(2011)
=> 2011-01-01 00:00:00 UTC
irb(main):004:0> File.utime(atime, mtime, 'tst')
=> 1
irb(main):005:0> s = File.stat('tst')
=> #<File::Stat dev=0x2, ino=0, mode=0100644, nlink=1, uid=0, gid=0, rdev=0x2, size=3, blksize=nil, blocks=nil, atime=2012-01-01 02:00:00 +0200, mtime=2011-01-01 02:00:00 +0200, ctime=2012-05-14 08:41
:26 +0200>
irb(main):006:0> atime
=> 2012-01-01 00:00:00 UTC
irb(main):007:0> s.atime
=> 2012-01-01 02:00:00 +0200
irb(main):008:0> mtime
=> 2011-01-01 00:00:00 UTC
irb(main):009:0> s.mtime
=> 2011-01-01 02:00:00 +0200
irb(main):010:0> s.mtime.utc
=> 2011-01-01 00:00:00 UTC
Updated by djberg96 (Daniel Berger) over 12 years ago
Are we talking about this?
http://search.cpan.org/~shay/Win32-UTCFileTime-1.55/lib/Win32/UTCFileTime.pm#DESCRIPTION
Updated by nobu (Nobuyoshi Nakada) over 12 years ago
=begin
: kolmanv (Kolman Vornovitsky) wrote:
Here is my run on the same code seems to work :
Maybe the problem is at Time.at
kolman@KOLMAN-PC ~
$ irb
irb(main):001:0> open('tst', 'w') { |f| f.write '123' }
=> 3
irb(main):002:0> atime = Time.utc(2012)
=> 2012-01-01 00:00:00 UTC
irb(main):003:0> mtime = Time.utc(2011)
=> 2011-01-01 00:00:00 UTC
irb(main):004:0> File.utime(atime, mtime, 'tst')
=> 1
irb(main):005:0> s = File.stat('tst')
=> #<File::Stat dev=0x2, ino=0, mode=0100644, nlink=1, uid=0, gid=0, rdev=0x2, size=3, blksize=nil, blocks=nil, atime=2012-01-01 02:00:00 +0200, mtime=2011-01-01 02:00:00 +0200, ctime=2012-05-14 08:41:26 +0200>
irb(main):006:0> atime
=> 2012-01-01 00:00:00 UTC
irb(main):007:0> s.atime
=> 2012-01-01 02:00:00 +0200
irb(main):008:0> mtime
=> 2011-01-01 00:00:00 UTC
irb(main):009:0> s.mtime
=> 2011-01-01 02:00:00 +0200
irb(main):010:0> s.mtime.utc
=> 2011-01-01 00:00:00 UTC
Thank you, I could reproduce it with 1.9.3p179, by changing the system
timezone to "((%(UTC+02:00) Athens, Bucharest%))".
But it seems fixed already in the trunk.
=end
Updated by nobu (Nobuyoshi Nakada) over 12 years ago
- Tracker changed from Bug to Backport
- Project changed from Ruby master to Backport193
- Category deleted (
core) - Status changed from Feedback to Assigned
- Assignee changed from usa (Usaku NAKAMURA) to luislavena (Luis Lavena)
Updated by nobu (Nobuyoshi Nakada) over 12 years ago
- Status changed from Assigned to Closed
- % Done changed from 0 to 100
This issue was solved with changeset r35678.
Kolman, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.
merge revision(s) 35109,35110,35651: [Backport #6385]
* win32/win32.c (rb_w32_fstat, rb_w32_fstati64): convert FILETIME
to time_t directly, not to be affected by TZ unnecessarily.
* win32/win32.c (unixtime_to_filetime): convert time_t to FILETIME
simply.