Column - Age

Version 1.4 - 28 October 2023

Updated script:

Version 1.3.1 - 5 October 2022

Version 1.3 - 9 September 2021

Updated script:

  • new config option allowing user to adjust decimal place accuracy of automated column calculations for both created and modified dates

image

  • renamed automated columns:
    • Age-M
    • Age-C
  • renamed manual columns:
    • Age-M (y:d:h:m:s)
    • Age-C (y:d:h:m:s)

Column.Generic_Age.js.txt (18.7 KB)

Version 1.2 - 9 December 2016

Broke columns down into Age (M-Units), Age (M-Auto), Age (C-Units), and Age (C-Auto). In addition, added config options for column size and justification.

Version 1.1 - 9 December 2016

Based on tbone's ModifiedWithin column script, this script provides two columns:

Age (M) - age since last modified of the folder/file
Age (C) - age since created of the folder/file

The script allows the user to independently choose each column's config as follows:

Auto: age is presented as number with corresponding time measure

examples:

  • 2.3 yrs
  • 142 days
  • 10.1 hrs
  • 27 min

Units: age is presented as yy:ddd:hh:mm:ss

Examples:

  • 02:071:10:27:32
  • 00:172:05:22:18

Thanks to tbone for the inspiration and help, and to the DOpus team for the multicol fix!
Column.Generic_Age.js.txt (17.4 KB)

3 Likes

Rethinking the approach to toggle the formatting of the columns via the script config.. it might not be the best thing to do.

If we look at what DO does natively, toggling column formats does not match. DO provides several columns in different flavors (formatting wise) like the size column with bytes/auto etc. Given that script columns can be used in find operations and filters, the result of these will always depend on the script config, which is not very obvious. Imagine if someone downloads column set X and looks up a filter definition Y. There is a high chance that things won't work as expected, since the columns output might be different because of the default/user configuration of the script/column.

Not sure what you/others think, but I think it makes more sense to provide multiple columns, each one offering a specific format. If there really is the need for a custom formatting, provide all the default columns and an "Age (Custom)" or something on top, so it's obvious that this columns output is subject to change, whereas all others will always deliver the same known format and values.

Don't get me wrong, nothing wrong with your columns and we surely learned something along the way.
Just saying that we can do even better! o)

Half the exercise for me was to learn something about scripting. I count that as a success. Along the way it identified a multicol issue, which the latest beta solves. That's a success, as well.

Going the multiple column route makes a lot of sense given the way columns are typically presented now in DOpus. That and the script already has the code ready. It won't take much to build the other columns.

... And I think we're there. Version 1.2 breaks it down into four column choices, rather than two with independent configs. Version 1.2 loaded into original post.

There is a slight difference in calculating age,it's not accurate,for some other files also i have seen same problem.The first pic is from xyplorer and second is opus'sxy age

op age

Hard to tell which is accurate when we can't see the file dates or current time. That would be better information to include than bringing up a different piece of software.

(Also important for understanding if DST changes between the start and end date could be in play. "1 day" may mean 23 or 25 hours sometimes, depending on at which level things are calculated. It's probably just different rounding methods though.)

Where is the problem? 14 days 23 hrs is 14.9583 days, rounded to one decimal is 15.0 days. It doesn't get better than this.

2 Likes

@Jon @Leo @lxp
Gents,

tried to update with user config option to set decimal place accuracy. The script/DOpus often crashes when opening the script's config dialog:

image

In addition, DOpus subsequently has issues opening Script Preferences then crashing.

Finally, when I can open the config dialog and set parameters, DOpus locks up and restarts.

Appreciate any assistance you might offer.

//v1.3 - 4 September 2021
//- added config options to set both auto-calculated Age Created and Age Modified column decimal place accuracy 
//v1.2 - 10 December 2016
//- split columns out into auto and unit options, rather than config options
//v1.1 - 9 December 2016
//- updated to work with multicol appropriately (thanks tbone!)
//v1.0 - 27 November 2016
//- initial release based on tbone's ModifiedWithin column script (http://resource.dopus.com/viewtopic.php?f=35&t=23192)

//==================================================
function OnInit(data) {
   //uid added via script wizard (do not change after publishing this script)
   var uid = "4CBC870D-C8E5-435F-8F68-FA1AA7E16DBB";
   //resource center url added via script wizard (required for updating)
   var url = ""
   data.name = "Item Age"
   data.desc = "Adds sortable columns that indicate folder/file age since creation or modification"
   data.copyright = "(c) 2016 Chuck"
   data.url = "http://resource.dopus.com/viewtopic.php?f=35&t=28433"
   data.version = "1.3"
   data.min_version = "12.24"
   data.default_enable = true;
   //==================================================
   function ConfigHelper(data){
      this.data=data; this.descriptions=null; this.last=null;
      this.add = function(name, val, description){
         this.data.config[name]=val; this.last=[this.data.config[name],name];
         if (description!=undefined) this.des(description); return this;}
      this.des = function(description){
         if (!(description && DOpus.version.AtLeast("11.6.1"))) return this;
         if (!this.descriptions){ this.descriptions=DOpus.NewMap();
            data.config._descriptions=this.descriptions; }
         this.descriptions(this.last[1])=description; return this;}
      this.val = function(val){
         if (typeof this.last[0]=="object") this.last[0].push_back(val);
         else this.last[0]=val; return this;}
   }
   //==================================================
   var cfg = new ConfigHelper(data);
   cfg.add("Column.Width",       "60px").
      des("Standard column width");
   cfg.add("Column.Justify",    DOpus.Create.Vector()).
      des("Column text alignment right, left or center").
      val(0).val("right").val("left").val("center");
   cfg.add("Accuracy_Auto_Created",     "0").
      des("Decimal place accuracy for automatically calculated Age-Created column");
   cfg.add("Accuracy_Auto_Modified",     "0").
      des("Decimal place accuracy for automatically calculated Age-Modified column");	  
}

//==================================================
function OnAddColumns(data) {

	var cmd = data.AddColumn();
	cmd.multicol = true;
	cmd.name = "TimeSinceModified";
	cmd.label = "Time Since Modification (Auto)";
	cmd.header = "Age-M";
	cmd.method = "Auto";
	cmd.autorefresh = true;
	cmd.namerefresh = true;
	cmd.defwidth = Script.config["Column.Width"];
	cmd.type = "text";
	var justify = ["right","left","center"]
	cmd.justify = justify[Script.config["Column.Justify"]];

	var cmd = data.AddColumn();
	cmd.multicol = true;
	cmd.name = "TimeSinceCreated";
	cmd.label = "Time Since Creation (Auto)";
	cmd.header = "Age-C";
	cmd.method = "Auto";
	cmd.autorefresh = true;
	cmd.namerefresh = true;
	cmd.defwidth = Script.config["Column.Width"];
	cmd.type = "text";
	var justify = ["right","left","center"]
	cmd.justify = justify[Script.config["Column.Justify"]];
	
	var cmd = data.AddColumn();
	cmd.multicol = true;
	cmd.name = "TimeSinceModifiedUnits";
	cmd.label = "Time Since Modification (Units)";
	cmd.header = "Age-M (y:d:h:m:s)";
	cmd.method = "Units";
	cmd.autorefresh = true;
	cmd.namerefresh = true;
	cmd.defwidth = Script.config["Column.Width"];
	cmd.type = "text";
	var justify = ["right","left","center"]
	cmd.justify = justify[Script.config["Column.Justify"]];

	var cmd = data.AddColumn();
	cmd.multicol = true;
	cmd.name = "TimeSinceCreatedUnits";
	cmd.label = "Time Since Creation (Units)";
	cmd.header = "Age-C (y:d:h:m:s)";
	cmd.method = "Units";
	cmd.autorefresh = true;
	cmd.namerefresh = true;
	cmd.defwidth = Script.config["Column.Width"];
	cmd.type = "text";
	var justify = ["right","left","center"]
	cmd.justify = justify[Script.config["Column.Justify"]];
}

//==================================================
function Auto(data) {
	var dateMod = new Date(data.item.modify).valueOf();
	var dateCre = new Date(data.item.create).valueOf();
	var dateNow = new Date().valueOf();
	var diffCre = (dateNow-dateCre)/60000;
	var diffMod = (dateNow-dateMod)/60000;
	var accuracy_ac = Number(Script.config["Accuracy_Auto_Created"]);
	var accuracy_am = Number(Script.config["Accuracy_Auto_Modified"]);

	//setting defaults (no value to clutter columns)
	data.columns("TimeSinceCreated".value) = "";
	data.columns("TimeSinceModified".value) = "";
	
	//Determine age in minutes since file/folder created and add appropriate suffix to calculation
	if (diffCre < 60){
		data.columns("TimeSinceCreated").value = (diffCre).toFixed(0) + " min";
	}	else if (diffCre < 1440){
			data.columns("TimeSinceCreated").value = ((diffCre)/60).toFixed(accuracy_ac) + " hrs";
	}   else if (diffCre < 525960){
			data.columns("TimeSinceCreated").value = ((diffCre)/1440).toFixed(accuracy_ac) + " days";
	}	
		else {
			data.columns("TimeSinceCreated").value = ((diffCre)/525960).toFixed(accuracy_ac) + " yrs";
	}
	data.columns("TimeSinceCreated").sort = diffCre;
	
	//Determine age in minutes since file/folder modified and add appropriate suffix to calculation
	if (diffMod < 60){
		data.columns("TimeSinceModified").value = (diffMod).toFixed(0) + " min";
	}	else if (diffMod < 1440){
			data.columns("TimeSinceModified").value = ((diffMod)/60).toFixed(accuracy_am) + " hrs";
	}   else if (diffMod < 525960){
			data.columns("TimeSinceModified").value = ((diffMod)/1440).toFixed(accuracy_am) + " days";
	}	
		else {
			data.columns("TimeSinceModified").value = ((diffMod)/525960).toFixed(accuracy_am) + " yrs";
	}
	data.columns("TimeSinceModified").sort = diffMod;
}
//==================================================

function Units(data) {
	var dateMod = new Date(data.item.modify).valueOf();
	var dateCre = new Date(data.item.create).valueOf();
	var dateNow = new Date().valueOf();
	var diffCre = (dateNow-dateCre)/60000;
	var diffMod = (dateNow-dateMod)/60000;
	var y = d = h = m = sc = sm = 0;

	//setting defaults (no value to clutter columns)
	data.columns("TimeSinceCreatedUnits".value) = "";
	data.columns("TimeSinceModifiedUnits".value) = "";
	
	//Determine age since file/folder created and add appropriate suffix to calculation
	sc = (dateNow-dateCre)/1000;
	switch (true) {
	case (sc > 31557600):
		y = Math.floor(sc / 31557600);
		sc %= 31557600;
	case (sc > 86400):
		d = Math.floor(sc / 86400);
		sc %= 86400;
	case (sc > 3600):
		h = Math.floor(sc / 3600);
		sc %= 3600;
	case (s > 60):
		m = Math.floor(sc / 60);
		sc %= 60;
		sc = sc.toFixed(0);
	}
	
	//Determine age since file/folder modified and add appropriate suffix to calculation
	sm = (dateNow-dateMod)/1000;
	switch (true) {
	case (sm > 31557600):
		y = Math.floor(sm / 31557600);
		sm %= 31557600;
	case (sm > 86400):
		d = Math.floor(sm / 86400);
		sm %= 86400;
	case (sm > 3600):
		h = Math.floor(sm / 3600);
		sm %= 3600;
	case (sm > 60):
		m = Math.floor(sm / 60);
		sm %= 60;
		sm = sm.toFixed(0);
	}
	
	//Correct numbers < 10 to add leading 0
	var yy = y.toString();
	var dd = d.toString();
	var hh = h.toString();
	var mm = m.toString();
	var ssc = sc.toString();
	var ssm = sm.toString();
	
	yy = yy.replace(yy, (y < 10) ? "0" + y : y);
	dd = dd.replace(dd, (d < 10) ? "0" + d : d);
	dd = dd.replace(dd, (dd < 100) ? "0" + dd : dd); //add second leading 0 since may have > 99 days
	hh = hh.replace(hh, (h < 10) ? "0" + h : h);
	mm = mm.replace(mm, (m < 10) ? "0" + m : m);
	ssc = ssc.replace(ssc, (sc < 10) ? "0" + sc : sc);
	ssm = ssm.replace(ssm, (sm < 10) ? "0" + sm : sm);
	
	//Format columns to display
	var fc = yy + ':' + dd + ':' + hh + ':' + mm + ':' + ssc;
	data.columns("TimeSinceCreatedUnits").value = fc;
	data.columns("TimeSinceCreatedUnits").sort = diffCre;
	
	var fm = yy + ':' + dd + ':' + hh + ':' + mm + ':' + ssm;
	data.columns("TimeSinceModifiedUnits").value = fm;
	data.columns("TimeSinceModifiedUnits").sort = diffMod;
}
//==================================================
function OnScriptConfigChange(data) {
	Script.InitColumns();
	Script.RefreshColumn("TimeSinceCreated");
	Script.RefreshColumn("TimeSinceModified");
	Script.RefreshColumn("TimeSinceCreatedUnits");
	Script.RefreshColumn("TimeSinceModifiedUnits");
}
///////////////////////////////////////////////////////////////////////////////
function OnAboutScript(data){ //v0.1
   var cmd = DOpus.Create.Command();
   if (!cmd.Commandlist('s').exists("ScriptWizard")){
      if (DOpus.Dlg.Request("The 'ScriptWizard' add-in has not been found.\n\n"+
"Install 'ScriptWizard' from [resource.dopus.com].\nThe add-in enables this dialog and also offers "+
"easy updating of scripts and many more.","Yes, take me there!|Cancel", "No About.. ", data.window))
      cmd.RunCommand('http://resource.dopus.com/viewtopic.php?f=35&t=23179');}
   else
      cmd.RunCommand('ScriptWizard ABOUT WIN='+data.window+' FILE="'+Script.File+'"');
}
//MD5 = "8f56f14954a42d94d8c5cd5181afb987"; DATE = "2016.12.09 - 20:17:45"

That's due to a bug in the current beta. It'll be fixed in the next update, but if you drop back to 12.24 it should work as well.

Thanks Leo!

@carter

Script updated in first post. It now allows user to determine automated created and modified column accuracy. Note the column names were changed as well.

I'm getting incorrect or blank times from the "Units" columns when the file is less than 1 hour old.
(screenshot taken at 8:08 AM)

Clipboard Image

1 Like

Changing line 174 from

case (s > 60):

to

case (sc > 60):

seems to fix the problem.

3 Likes

Updated OP with fixed script. Thanks @Hoosh for pointing it out and @lxp for identifying the fix!

2 Likes

Nice one, thanks!

1 Like

See first post in thread for 1.4 update. Now includes age since accessed columns

1 Like