Rename photos calculating the age of the person

I'm wanting to create code that allows me to rename photos by calculating the person's age.

Example: Esther.jpg > Esther (1a 3m 5d).jpg

To calculate the age, it would take into account the date of birth, incorporated in a fixed way in the code, and the datetaken, obtained from the metadata of the photo.

The following code is executed completely without generating an error, but the result of the years, months and days is expressed in the form of NaN (Not a Number), apparently due to an error in the date formats.

Current result: Esther (NaNy NaNm NaNd).jpg

function OnGetNewName(getNewNameData) {
    var birthdate = new Date("2019-02-13T00:00:00");

    var item = getNewNameData.item;
    var metadata = item.metadata;
 
    if (metadata && metadata.image && metadata.image.datetaken) {
        var datetaken = new Date(metadata.image.datetaken);
        var diff = datetaken - birthdate;

        var years = Math.floor(diff / (365.25 * 24 * 60 * 60 * 1000));
        var months = Math.floor((diff % (365.25 * 24 * 60 * 60 * 1000)) / (30.44 * 24 * 60 * 60 * 1000));
        var days = Math.floor((diff % (30.44 * 24 * 60 * 60 * 1000)) / (24 * 60 * 60 * 1000));

        var age = "(" + years + "y " + months + "m " + days + "d)";

        var result = item.name_stem + " " + age + item.ext;
        return result;
    } else {
        return item.name;
    }
}
1 Like

The problem in your code is that the WSH JScript doesn't support ISO string dates for Date initialization, so all your date values (birthdate and datetaken) are NaN. You should initialize the Dates like so: new Date(2019, 2, 13); but be careful I think that the months are zero-based so it may be off-by-one.

Once you've initialized proper dates, the values will be in milliseconds since epoch, and your Math.floor functions should work.

1 Like

Change the 2nd line to:

var birthdate = new Date(2019,02,13,00,00,00);

(Seems to be a difference between the JScript and Javascript data objects.)

Edit: Posted at the same time as Bytespiller, so we've both given similar advice.

Many thanks to both @bytespiller and @Leo, but I modified the code as per your instructions and the NaN result is no longer displayed, but the calculated age is incorrect.

For example, I select a photo with datetaken 2019-02-14, barely 1 day apart from birthdate (2019-02-13), so the result should be: Esther (0y 0m 1d).jpg and it is being Esther (-1y -1m -27d).

Maybe it's the off-by-one that @bytespiller tells me about, but I don't know how to correct that detail?!?

The code and calculations seem ok:

birthdate = Wed Feb 13 2019 00:00:00
datetaken = Thu Feb 14 2019 00:00:00
diff = 86400000
years = 0
months = 0
days = 1
age = (0y 0m 1d)
1 Like

Thanks @Jon, so I don't know why my result with negative values

Correct result with JScript in Opus as well, when using two hardcoded dates:

My bet is it's a timezone/UTC issue.

Try changing new Date(metadata.image.datetaken) to one of these. If one works, the other should make it worse. If both seem to work (or both make it worse) then I might be wrong about it being timezone related.

  • new Date(metadata.image.datetaken.FromUTC())
  • new Date(metadata.image.datetaken.ToUTC())

Edit: You could also use Opus's own Date object, instead of the JScripts ones. That should avoid the issue as you'd no longer be mixing the two objects together, and you can compare the y/m/d values separately without all the extra math:

https://www.gpsoft.com.au/help/opus12/index.html#!Documents/Scripting/Date.htm

I tried the 3 recommended ways and the result is still the same.

  1. FromUTC()

  2. ToUTC()

  3. Opus

Last one isn't using Opus's Date objects...

But, taking a step back, what are the dates if you output them?

In other words:

DOpus.Output(datetaken);
DOpus.Output(birthdate);

Presumably one of those is not the expected value.

True Leo, I simply used DOpus.Output from what I saw, I know practically nothing programming

@Leo I don't want to use your kindness, but seeing that it is difficult to solve this situation and that I know so little about programming, couldn't you do me the great favor of creating a completely new code for me, in the way that you find best?

The code may work for me but not you due to the timezone you are in, or the data in the file you're testing against, neither of which I can easily recreate here.

What do you get if you output the two dates like I asked just above?

Sorry, I did not understand. You recommend me to do what with:

DOpus.Output(datetaken);
DOpus.Output(birthdate);

I inserted the lines in the code and the two dates with different UTC are displayed, and the month of birth in 3 when it should be 2, as said @bytespiller.

The JScript Date month values are in range 0-11 (and not 1-12 as you would expect, so the month value 0 means January and the month value 11 means December).

To fix this, simply put the birthdate as: var birthdate = new Date(2019,01,13); or if you prefer: var birthdate = new Date(2019,02-1,13);

2 Likes

Perfect, that was the detail that was complicating things, thank you very much!

How could you insert a condition so that when some of the values years, months or days are 0, they are not displayed?

Example: Esther (2y 0m 5d).jpg > Esther (2y 5d).jpg

One day I saw that condition in a script, but no matter how hard I search I can't find it

This should do what you want, and as a bonus if all the values are zero it will say "today".

pssst...

And as a bonus bonus there is no stinkin' regex :slight_smile:

// Conditional date parts
var strYears = (years != 0) ? (years + "y ") : "";
var strMonths = (months != 0) ? (months + "m ") : "";
var strDays = (days != 0) ? (days + "d ") : "";
var strTotal = (strYears + strMonths + strDays).slice(0,-1);

var age = "(" + (strTotal || "today") + ")";
DOpus.Output(age);

Replace your var age = ... with the code above.

1 Like

Thank you very much once again, look at the code that I was writing...

if (**anos === 0**) {
var edad = "(" + meses + "m " + dias + "d)";
} else if (**meses === 0**) {
var edad = "(" + anos + "a " + dias + "d)";
} else if (**dias === 0**) {
var edad = "(" + anos + "a " + meses + "m)";
} else if (**anos === 0** && **meses === 0**) {
var edad = "(" + dias + "d ")";
} else if (**anos === 0** && **dias === 0**) {
var edad = "(" + meses + "m ")";
} else if (**meses === 0** && **dias === 0**) {
var edad = "(" + anos + "a ")";
} else if (**anos === 0** && **meses === 0** && **dias === 0**) {
var edad = "(" 0 tiempo")";
} else {
var edad = "(" + anos + "a " + meses + "m " + dias + "d)";
}
}
1 Like

Everything almost perfect, correct years and months, but the days have a difference of 7-8 days with reality. I have tried to replace this code with the other one but without success.

var years = Math.floor(diff / (365.25 * 24 * 60 * 60 * 1000));
var months = Math.floor((diff % (365.25 * 24 * 60 * 60 * 1000)) / (30.44 * 24 * 60 * 60 * 1000));
var days = Math.floor((diff % (30.44 * 24 * 60 * 60 * 1000)) / (24 * 60 * 60 * 1000));
var years = datetaken.getFullYear() - birthdate.getFullYear();
var months = datetaken.getMonth() - birthdate.getMonth();
var days = datetaken.getDay() - birthdate.getDay();