2

I see a strange behavior while fetching the modification time of a file. we have been calling _stat64 method to fetch the file modification in our project as following.

int my_win_stat( const char *path, struct _stati64 *buf)
{  
 if(_stati64( path, buf) == 0)
 {
   std::cout<<buf->st_mtime << std::endl; //I added to ensure if value is not changing elsewhere in the function.
 }
 ...........
 ...........
}

When I convert the epoch time returned by st_mtime variable using epoch convertor, it shows 2:30 hrs ahead of current time set on my system.

When I call same API as following from different test project, I see the correct mtime (i.e. according to mtime of file shown by my system).

if (_stat64("D:\\engine_cost.frm", &buffer) == 0)
    std::cout << buffer.st_mtime << std::endl;

Even I called GetFileTime() and converted FILETIME to epoch time with the help of this post. I get the correct time according to time set the system.

if (GetFileTime(hFile, &ftCreate, &ftAccess, &ftWrite))
{
    ULARGE_INTEGER ull;
    ull.LowPart = ftWrite.dwLowDateTime;
    ull.HighPart = ftWrite.dwHighDateTime;

    std::cout << (ull.QuadPart / 10000000ULL - 11644473600ULL);
}

What I am not able to figure out is why does the time mtime differ when called through my existing project?
What are the parameters that could affect the output of mtime ?
What else I could try to debug the problem further ?

Note

  1. In VS2013, _stati64 is a macro which is replaced replaced by _stat64.
  2. File system is NTFS on windows 7.
Community
  • 1
  • 1
irsis
  • 952
  • 1
  • 13
  • 33
  • Same filesystem in both cases? I know some Linux filesystems don't store modification date, which could explain why it's not giving the right data? – Mats Petersson Aug 31 '15 at 18:11
  • @MatsPetersson yes, It's NTFS on windows 7 – irsis Aug 31 '15 at 18:12
  • @MatsPetersson: Curious: which one would that be? – too honest for this site Aug 31 '15 at 18:13
  • @Olaf: Ah, I may be wrong, I think it was "accesstime" that isn't supported on some filesystems.... – Mats Petersson Aug 31 '15 at 18:15
  • @MatsPetersson: Well, afaik, for the standard Linux-FS (ext2-4, btrfs, xfs, etc), this does not apply. At most, there is an option to disable updating the atime, but that is normally the user's/admin's discretion. It is sometimes used for Flash-media (USB-sticks, SD-card, etc., not including SSDs). – too honest for this site Aug 31 '15 at 18:21
  • 1
    Could this be a timezone-problem? If the difference is constant, I'd research in this direction. – too honest for this site Aug 31 '15 at 18:23
  • @Olaf I could have considered timezone problem had it been 1 hr difference in time. Secondly , same api returns the correct time when called from different project. – irsis Aug 31 '15 at 18:27
  • Ok, that was just an idea. Sorry, I cannot help further with Windows. Was just curious because you tagged this C, although it is clearly C++-only. – too honest for this site Aug 31 '15 at 18:30
  • What do you get if you pass the "wrong" value to `ctime()`? – Jonathan Potter Aug 31 '15 at 20:11
  • From what you posted, I suspect there is an error in your epoch converter or in passing the information around you gather in `my_win_stat` or in your internal code of `my_win_stat`. – StarPilot Aug 31 '15 at 22:12
  • @StarPilot I am using epochconvertor.com website to convert time. It shows the time correctly later case but not in former so I ruled out that possibility. Second thing I did to cross check is the value is manipulating deep down in my_win_state() but it's not :( – irsis Sep 01 '15 at 02:51

2 Answers2

1

Unix time is really easy to deal with. It's the number of seconds since Jan 1, 1970 (i.e. 0 represents that specific date).

Now, what you are saying is that you are testing your time (mtime) with a 3rd party tool in your browser and expects that to give you the right answer. So... let's do a test, the following number is Sept 1, 2015 at 00:00:00 GMT.

1441065600

If you go to Epoch Converter and use that very value, does it give you the correct GMT? (if not, something is really wrong.) Then look at the local time value and see whether you get what you would expect for GMT midnight. (Note that I use GMT since Epoch Converter uses that abbreviation, but the correct abbreviation is UTC.)

It seems to me that it is very likely that your code extracts the correct time, but the epoch convertor fails on your computer for local time.

Note that you could just test in your C++ program with something like this:

std::cerr << ctime(&buf->st_mtime) << std::endl;

(just watch out as ctime() is not thread safe)

That will give you the data according to your locale on your computer at runtime.

To better control the date format, use strftime(). That function makes use of a tm structure so you have to first call gmtime or localtime.

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
0

An year later I ran into the similar problem but scenario is little different. But this time I understand why there was a +2:30Hrs of gap. I execute the C++ program through a perl script which intern sets the timezone 'GMT-3' and my machine had been in timezone 'GMT+5:30'. As a result there was a difference of '2:30Hrs'. Why ? As Harry mentioned in this post

changing the timezone in Perl is probably causing the TZ environment variable to be set, which affects the C runtime library as per the documentation for _tzset.

Community
  • 1
  • 1
irsis
  • 952
  • 1
  • 13
  • 33