I'll post the full code below in case anyone is interested. This allows to calculate the age in years, months and days from the date of birth specified by the user to the current day (today).
The code works from a button on the toolbar, in JScript mode. I would really appreciate it if someone identifies a bug and lets me know, or if they have any suggestions.
Before I finish I want to thank everyone who helped me write this code, @Jon, @Leo , @lxp and very especially @bytespiller, not only for everything he helped me but also for everything he taught me!!!
function OnClick(clickData)
{
var dlg = clickData.func.Dlg;
//Birthdate
var date1String = dlg.getString("Enter birthdate (YYYY-MM-DD):");
if (!date1String) {
return;
}
//Convert birthdate (text) to true date (Date object)
var date1Array = date1String.split("-");
var yearString = date1Array[0];
var monthString = date1Array[1];
var dayString = date1Array[2];
var date1 = new Date(yearString, monthString - 1, dayString);
//Current date
var date2 = new Date();
if (!date2) {
return;
}
//Customize dates to show in the result (YYYY-MM-DD format, and days and months with 2 digits (0 to the left))
var yearF1 = date1.getFullYear();
var monthF1 = ("0" + (date1.getMonth()+1)).slice(-2);
var dayF1 = ("0" + date1.getDate()).slice(-2);
var date1Short = yearF1 + "-" + monthF1 + "-" + dayF1
var yearF2 = date2.getFullYear();
var monthF2 = ("0" + (date2.getMonth()+1)).slice(-2);
var dayF2 = ("0" + date2.getDate()).slice(-2);
var date2Short = yearF2 + "-" + monthF2 + "-" + dayF2
//Calculate time
var difference = date2 - date1; //In milliseconds
var total_days = Math.floor(difference / 24 * 60 * 60 * 1000); //In days
//Error message if birthdate > current date
if(difference < 0){
dlg.title = "Current age";
dlg.message = "Error: Birthdate must be less than current date.\n\nBirthdate: " + date1Short + "\nCurrent date: " + date2Short;
dlg.icon = "error";
dlg.buttons = "OK";
dlg.Show();
return;
}
//Calculate age
var age = new Date(0);
age.setMilliseconds(date2 - date1);
var years = age.getFullYear() - 1970;
var months = age.getMonth();
var days = age.getDate();
//Ignore 0 values and set singular or plural
var SEPARATOR = ", ";
function que(value, singular, plural) {
if (!value) {
return "";
}
var suffix = (Math.abs(value) > 1) ? plural : singular;
return value + " " + suffix + SEPARATOR;
}
var str_years = que(years, "year", "years");
var str_months = que(months, "month", "months");
var str_days = que(days, "day", "days");
var str_total = (str_years + str_months + str_days).slice(0, -SEPARATOR.length);
var result = str_total || "Born today";
//Show result
dlg.title = "Current age";
dlg.message = "Birthdate: " + date1Short + "\nCurrent age: " + date2Short + "\n\nEdad: " + result;
dlg.icon = "info";
dlg.buttons = "OK";
dlg.Show();
}
@Leo now that this topic is solved, you could change the name to make it more intuitive and can help more people, for example "Calculate age in years, months and days". Thank you
@fkast here I was also giving 1 day difference, +1 day, I commented with @lxp, that's why I put the -1 in the var days = age.getDate()-1; line. Try to reverse that situation by leaving the line like this var days = age.getDate(); I hope it works for you.
Regarding the renaming, what I wanted initially was that, when selecting a photo, a script, based on the birthdate that I had specified internally, would calculate the age of that person on the day the photo was taken, that is, datetaken - birthdate, and yes, I got that result, the script is available at...
Oi @qiuqiu, the same thing is happening with you it was happening here with me, it's giving you + 1 day, solve it by modifying this line var days = age.getDate(); to var days = age.getDate() - 1;
I don't know why this behavior, for some people + 1 day, for others -1 day?!?
I have added the "Nuevo cĂĄlculo" (New calculation) button to the result window to be able to perform new calculations, but I have not been able to assign it its action, which would be to re-execute all the code.
I would also like, if possible, to move the button to the far left, and if it's not difficult, keep the window always on top. Can someone help me?!?
But nevermind, here's the code for that dialog along with helpful comments in the code:
// Mostrar resultado
dlg.title = "Edad actual";
dlg.message = "Fecha nacimiento: " + fecha1Corta + "\nFecha actual: " + fecha2Corta + "\n\nEdad: " + resultado;
dlg.icon = "info";
dlg.buttons = "Nuevo cĂĄlculo|Salir"; // Docs: https://www.gpsoft.com.au/help/opus12/index.html#!Documents/Scripting/Dialog.htm
var sel = dlg.Show(); // After this line the execution is PAUSED until the user clicks a button. Then it resumes to the next line.
if (sel === 1) { // Check what was clicked by the user. Number represents a clicked button from right to left (rightmost starting with 0).
OnClick(clickData); // Fun fact: recursion depth (also known as "nested calls") of the JS is 10000, so in theory if you click "Nuevo cĂĄlculo" button 10001 times this line will then fail :)
}
Also...
This dialog should already be on top (and modal) relative to the Opus main window. If you mean globally on top, then it's not really feasible.
How wonderful, everything is working very well, I don't know how to thank you so much, here I am laughing a lot with happiness, thank you very much.
Regarding trying to keep the window always on top, it was in order to be able to go to Excel pages and copy the results easily, always having the window visible, but that is not very important, the truth is that I am very, very happy, many thanks again!!!