Game Development Community

Sorting File List by Date Modified

by Phoenix Online Studios · in Torque Game Engine · 04/30/2009 (6:05 am) · 12 replies

Hello,

I'm using a Save GUI similar to Torque's, with a GuiTextListCtrl to display the list of files in a directory. Currently, it is sorting files alphabetically. Is there a way to get them to sort by Date Modified?

This is the code I'm using:

function initSaveGui()
{
	%name = "";
	$SG_filespec = "*.sav";
	SG_nameEdit.setValue(%name);
	SG_directoryList.setValue("game/saves");

	//display files
	SG_fileList.clear();
	%filespec = SG_directoryList.getValue() @ "/" @ $SG_filespec;
	for(%file = findFirstFile(%filespec); %file !$= ""; %file = findNextFile(%filespec))
		if (strStr(%file, "/CVS/") == -1)
			SG_fileList.addRow(%i++, fileName(%file));
	SG_fileList.sort(0);

	//auto-select last selected game
	if ($SaveGame !$= "")
		SG_fileList.setSelectedRow(SG_fileList.findTextIndex($SaveGame));
}

SG_fileList is the name given to the GuiTextListCtrl.


#1
04/30/2009 (7:04 am)
%control.sort(column, true/false); // Increasing (true) sort on column xy

%control.sortByNumerical(column, true/false); // Decreasing (false) numeric sort on column xy

You could calculate the timestamp of each file to sort by this value.
But you have to insert the timestamp in a separate column. If you dont want to show the timestamp simply set the width of this column to 0.
#2
04/30/2009 (7:10 am)
Thanks! I'll probably show the timestamp (assuming it appears in a legible format). What's the function to get the timestamp from a file?
#3
04/30/2009 (7:52 am)
You need the Unix Timestamp.

The Timestamp is a large value in seconds since 1.1.1970.
So you have to convert a File-Time/-Date to this Timestamp.

Unfortunately i cannot give you a snippet in C++.
But i can write you a special DLL to handle this.
#4
04/30/2009 (7:59 am)
But it can be easier. You only have to get the Date and Time of a File. Someting like

%datetime = "2009-05-07-15-15-30";

Format: Year-Month-Day-Hour-Minute-Second

Now it is easy to sort such strings.
#5
04/30/2009 (8:11 am)
I'd rather not use a .dll, but you're right that I could just store this info in an array, and sort based on that. Unfortunately, I'm still not sure how to get the date & time of a file.

Does know if there's already an TorqueScript function for getting the unix timestamp of a file? If there isn't one, a C++ snippit would be very helpful.

Thanks
#6
04/30/2009 (9:39 am)
Look at GetFileTime( ); in the Platform SDK.
#7
04/30/2009 (8:06 pm)
Do you mean getFileTimes() ? I see the function in consoleFunctions.cc, but unfortunately it doesn't seem to work when when I type it in the console.
#8
05/04/2009 (7:43 am)
Ok, it turns out there is no TorqueScript function for getting the date modified. Here's the C++ code I used:

In main.cc, after the getRealTime ConsoleFunction, add:

ConsoleFunction(dateModified, const char *, 2, 3, "dateModified(string fileName, bool convertToInt=false)")
{
   argc;

   char file[1024];
   Con::expandScriptFilename(file, sizeof(file), argv[1]);
   
   // check to make sure file exists
   ResourceObject* obj = ResourceManager->find(file);
   if(!obj)
   {
      Con::errorf("Unable to find file '%s'...", argv[1]);
      return "";
   }
   else
   {
	  bool convToInt = (argc > 2)? dAtob(argv[2]): false;

      FileTime scrModifyTime;
	  obj->getFileTimes(NULL, &scrModifyTime);

	  if (!convToInt)
	  {
			Platform::LocalTime lt;

			Platform::fileToLocalTime(scrModifyTime, &lt);


			char *retBuffer = Con::getReturnBuffer(128);  
			dSprintf(retBuffer, 128, "%d %d %d %02d %02d %02d",  
				lt.year + 1900,
				lt.month,  
				lt.monthday,  
				lt.hour,  
				lt.min,  
				lt.sec);  

			return retBuffer;
	  }
	  else 
	  {
		   char *retBuffer = Con::getReturnBuffer(128);
		   Platform::fileTimeToString(&scrModifyTime, retBuffer, 128);

		   return retBuffer;
	  }
   }
}

Usage in TorqueScript is:
dateModified(filepath);

Where filepath is the full path to the file you want to know the date modified.

If you use
dateModified(filepath, true);
, it will return an numeric string that you can use for sorting. Otherwise, it will return the date modified in the format:

year month day hour minute second

For example: 2009 12 31 22 00 00
#9
05/04/2009 (8:22 am)
thanks for following up!
that seems like it might make a nice resource.
it might be nice to pass in an optional formatting string, if FileTime has methods to take advantage of something like that.
#10
05/04/2009 (8:38 am)
Thanks! I think I will create a resource for this, since sorting saved games by date is pretty handy.

Actually, the nice thing about the output being space separated is that you can take the output and perform whatever formatting you like in TorqueScript using getWord().

This is what I use:

function formatDate(%timestamp)
{
	%month 	= getWord(%timestamp, 1);
	%day 	= getWord(%timestamp, 2);
	%year 	= getWord(%timestamp, 0);
	%hour 	= getWord(%timestamp, 3);
	%min 	= getWord(%timestamp, 4);
	
	switch$(%month)
	{
		case "1":
			%month = "January";
		case "2":
			%month = "February";
		case "3":
			%month = "March";
		case "4":
			%month = "April";
		case "5":
			%month = "May";
		case "6":
			%month = "June";
		case "7":
			%month = "July";
		case "8":
			%month = "August";
		case "9":
			%month = "September";
		case "10":
			%month = "October";
		case "11":
			%month = "November";
		case "12":
			%month = "December";
	}
	
	if (%hour > 12)
	{
		%hour = %hour - 12;
		%AMPM = "PM";
	}
	else
	{
		if (%hour == 0)
			%hour = 12;
		%AMPM = "AM";
	}

	%output = "<just:center>" @ %month @ " " @ %day @ ", " @ %year @ "n" @ %hour @ ":" @ %min @ " " @ %AMPM;
	
	return %output;
}

So my formatting function would convert "2009 12 31 22 00 00" to something more legible:

December 31, 2009
11:00 PM
#11
05/04/2009 (8:47 am)
when i first saw your example output "2009 12 31 22 00 00" that was my first reaction as well - "hey, how great, i get getWord() these guys and format it however i want" but then i remembered that there's already a C function, strftime(), to deal with formatting dates and times in a very flexible yet standard way. i don't know if strftime has been wrapped up in the torque dSprintf form etc yet, tho.
#12
05/04/2009 (9:03 am)
I'll need to check what paramaters exist in the Platform::LocalTime class first. I don't know if all the format specifiers (such as "Thursday") exist already or not.