Bug 6118 - [OSX] File.GetCreationTime returns last modified time instead
Summary: [OSX] File.GetCreationTime returns last modified time instead
Alias: None
Product: Runtime
Classification: Mono
Component: io-layer ()
Version: unspecified
Hardware: Macintosh Mac OS
: --- enhancement
Target Milestone: ---
Assignee: Bugzilla
: 8038 ()
Depends on:
Reported: 2012-07-13 15:35 UTC by dj_technohead
Modified: 2017-07-11 23:32 UTC (History)
6 users (show)

Is this bug a regression?: ---
Last known good build:

Mscorlib.dll (997.50 KB, application/octet-stream)
2012-07-19 23:23 UTC, dj_technohead

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description dj_technohead 2012-07-13 15:35:24 UTC
Hey guys,
   just noticed something weird. I wanted to get the creation date of a file that I know has entries dating back to last month. 

     Using the following call File.GetCreationTime(filepath) returns {7/13/2012 12:17:13 PM} which is obviously the last modified timestamp, but if I use this:

            NSFileManager fileManager = NSFileManager.DefaultManager;

            NSFileAttributes attrs = fileManager.GetAttributes(filepath);

            NSDate nsCreationDate = attrs.CreationDate;
            DateTime dtCreationDate = (DateTime)nsCreationDate;

I get back the correct timestamp of {6/17/2012 9:57:27 PM}.

Comment 1 Sebastien Pouliot 2012-07-19 10:10:06 UTC
Good catch! I'm pretty sure it's the linker removing a field that is shared with the runtime (so the wrong one gets assigned).
Comment 2 Sebastien Pouliot 2012-07-19 10:53:32 UTC
I'm not able to duplicate the issue (even with MonoIOStat unpreserved).

If you're still able to duplicate this could you attach the mscorlib.dll from inside your application .app directory ? That will allow me to be 100% certain that my fix covers your issue. Thanks!
Comment 3 Sebastien Pouliot 2012-07-19 15:14:38 UTC
That change was required and (likely) fix your issue. I'm closing the bug but I would be grateful if you could still attach an mscorlib.dll from your application (in case there's something else I missed).

master: e4bd4e294652aeec713636543ef886ca40a2bd56
5.2-series: a2030d6be7cc753dbd316668c931533d8d94c806
Comment 4 dj_technohead 2012-07-19 23:23:43 UTC
Created attachment 2237 [details]
Comment 5 Sebastien Pouliot 2012-07-20 09:42:04 UTC
hmm... the structure was not modified in the mscorlib.dll you attached. Something else must be happening. I'll try again to duplicate this
Comment 6 dj_technohead 2012-07-20 10:59:54 UTC
Hi Sebastien,

Here's the code that I have:

		private Logger ()
			filepath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "logger.log");

            if (File.Exists(filepath))
                NSFileManager fileManager = NSFileManager.DefaultManager;

                NSFileAttributes attrs = fileManager.GetAttributes(filepath);

                NSDate nsCreationDate = attrs.CreationDate;
                DateTime dtCreationDate = (DateTime)nsCreationDate;

                DateTime dtCreate = File.GetCreationTime(filepath);
                Console.WriteLine("File.GetCreationTime = " + dtCreate);
                Console.WriteLine("FileManager.GetAttributes = " + nsCreationDate);

                TimeSpan ts = DateTime.Now - dtCreationDate;
                if (ts.TotalDays > 5)

The console output that I see now:

File.GetCreationTime = 7/19/2012 11:42:51 PM
FileManager.GetAttributes = 2012-07-20 06:42:48 +0000

This is from the simulator.

Comment 7 Sebastien Pouliot 2012-07-20 11:03:50 UTC
oh, that's a different case. The "+0000" on FileManager.GetAttributes means it's time in UTC

If you convert your File.GetCreationTime to UTC, e.g. File.GetCreationTime.ToUniversalTime(), then the results will match.

The time difference in your original description did not match (for a time zone shift) but I guess it could have been taken on different files / execution ?
Comment 8 dj_technohead 2012-07-20 11:28:54 UTC
Oh sorry about that Sebastien, I didn't realize that was in UTC. Yes, the output I last gave you was from a different execution.
Comment 9 Sebastien Pouliot 2012-07-20 11:32:01 UTC
No problem :) It's a good thing you reported this as the structure should have been protected (even if the BCL itself seems to use every fields so they can't be linked away).
Comment 10 dj_technohead 2012-07-20 11:37:27 UTC
Actually, thinking about it a bit more, the reason I raised this as a bug was because I wasn't getting the expected datetime stamp from the File.GetCreationTime() since it should have been a difference of at least a month. But I guess your fix resolved that in this case?
Comment 11 Sebastien Pouliot 2012-07-20 11:53:02 UTC
Maybe but I can't be sure if I can't duplicate the issue. Please re-open the issue if you can duplicate a (non-UTC) difference between those two cases.
Comment 12 dj_technohead 2012-07-20 12:48:55 UTC
Ok will do. Thanks Sebastien.
Comment 13 dj_technohead 2012-07-20 14:35:17 UTC
Hi Sebastien,
   I did a bit more testing with the code modified as below:

if (File.Exists(filepath))
                NSFileManager fileManager = NSFileManager.DefaultManager;

                NSFileAttributes attrs = fileManager.GetAttributes(filepath);

                NSDate nsCreationDate = attrs.CreationDate;
                DateTime dtCreationDate = (DateTime)nsCreationDate;

                DateTime dtNSCreateDate = (DateTime)nsCreationDate;

                DateTime dtCreate = File.GetCreationTime(filepath);
                Console.WriteLine("File.GetCreationTime = " + dtCreate.ToLocalTime());
                Console.WriteLine("FileManager.GetAttributes = " + dtNSCreateDate.ToLocalTime());


Note that all date time outputted to the console have been converted to local time. When I run the above in the simulator I get the following output:

File.GetCreationTime = 7/20/2012 11:21:45 AM
FileManager.GetAttributes = 7/19/2012 11:42:48 PM

Since I just ran the app, the File.GetCreationTime is showing the last modified time. 

Comment 14 Sebastien Pouliot 2012-07-23 12:01:15 UTC
Doh, it's a mono limitation (I'd forgotten about). Many file systems don't report the "real" creation time. IIRC that property is only supported correctly on Windows (the io-layer code being different).

OSX (HFS+) support this, which is why you get different values on the simulator (I assume the same for iOS). The workaround is to use OSX/iOS API to get the right values.

I'm moving the bug to mono/io-layer.
Comment 15 Sebastien Pouliot 2012-10-29 09:45:41 UTC
*** Bug 8038 has been marked as a duplicate of this bug. ***
Comment 16 Rodrigo Kumpera 2017-07-11 23:32:03 UTC
This is a OS limitation.