// CalcDates // (c) 2024 Cris // This is a script for Directory Opus. // See https://www.gpsoft.com.au/DScripts/redirect.asp?page=scripts for development information. // Called by Directory Opus to initialize the script function OnInit(initData) { initData.name = "CalcDates"; initData.version = "1.0.0"; initData.copyright = "(c) 2024 Cris"; initData.desc = "Calculate the difference between two given dates in a user-friendly format"; initData.default_enable = true; initData.min_version = "12.33"; initData.config_desc = DOpus.Create.Map(); initData.config.debug = DOpus.Create.Vector(1, 'ALL', 'WARNING', 'OFF'); initData.config_desc('debug') = DOpus.strings.Get('debug'); initData.config.date_format = ""; initData.config_desc('date_format') = DOpus.strings.Get('date_format'); initData.config.use_today = true; initData.config_desc('use_today') = DOpus.strings.Get('use_today'); initData.config.value_sep = ", "; initData.config_desc('value_sep') = DOpus.strings.Get('value_sep'); } // Called to add commands to Opus function OnAddCommands(addCmdData) { var cmd = addCmdData.AddCommand(); cmd.name = "CalcDates"; cmd.method = "CalcDates"; cmd.desc = "Calculate the difference between two given dates in a user-friendly format"; cmd.label = "CalcDates"; cmd.template = ""; cmd.hide = false; cmd.icon = "setdate"; } function CalcDates(scriptCmdData) { Log(1, "===CalcDates Custom Command initiated==="); var msg, fecha_inicio, fecha_fin, ini_date, end_date; var dlg = scriptCmdData.func.dlg; var today = DOpus.Create.Date().format("D#dd-MM-yyyy"); var str_values = DOpus.Create.Map(); if (DOpus.Version.AtLeast("13.0.55")) { var str_tools = DOpus.Create.StringTools(); str_values("day") = str_tools.LanguageStr(9310); str_values("days") = str_tools.LanguageStr(9314); str_values("month") = str_tools.LanguageStr(9312); str_values("months") = str_tools.LanguageStr(9316); str_values("year") = str_tools.LanguageStr(9313); str_values("years") = str_tools.LanguageStr(9317); str_tools = null; } else { str_values("day") = DOpus.strings.Get("day"); str_values("days") = DOpus.strings.Get("days"); str_values("month") = DOpus.strings.Get("month"); str_values("months") = DOpus.strings.Get("months"); str_values("year") = DOpus.strings.Get("year"); str_values("years") = DOpus.strings.Get("years"); } var sep = Script.config.value_sep; if (!sep) sep = ", "; var date_format = Script.config.date_format; if (!date_format) date_format = "D#MMMM d', 'yyyy"; dlg.template = "dialog"; dlg.title = DOpus.strings.Get("title"); dlg.Create(); var res_dlg = dlg.Control("resultado"); var inistr_dlg = dlg.Control("f_ini_string"); var finstr_dlg = dlg.Control("f_fin_string"); var toclip_dlg = dlg.Control("to_clip_btn"); var ini_dlg = dlg.Control("fecha_inicio"); var fin_dlg = dlg.Control("fecha_fin"); res_dlg.style = "bi"; dlg.AddHotkey("today", "t"); dlg.Show(); fin_dlg.value = Script.config.use_today ? today : ""; while (true) { msg = dlg.GetMsg(); if (!msg.result) break; // Log("event: " + msg.event + '; control: "' + msg.control + '"'); if (msg.event === "editchange" && (msg.control === "fecha_fin" || msg.control === "fecha_inicio")) { eval(msg.control + "= msg.value"); if ((ini_date = esfechaValida(fecha_inicio)) && (end_date = esfechaValida(fecha_fin))) { // ini_date = DOpus.Create.Date(fecha_inicio); // end_date = DOpus.Create.Date(fecha_fin); res_dlg.label = CalcDiff(ini_date, end_date, sep, str_values); if (!datesinLabels(inistr_dlg, ini_date, finstr_dlg, end_date, date_format)) date_format = "D#MMMM d', 'yyyy"; toclip_dlg.enabled = true; } else { res_dlg.label = DOpus.strings.Get("nores_str"); inistr_dlg.label = ""; finstr_dlg.label = ""; toclip_dlg.enabled = false; } } if (msg.event === "click" && msg.control === "to_clip_btn") Copy_to_Clip(dlg, ini_date, end_date); if (msg.event === "click" && msg.control === "clear_btn") fin_dlg.value = ini_dlg.value = ""; if (msg.event === "timer" && msg.control === "notify_clip_copy") { dlg.KillTimer("notify_clip_copy"); dlg.Control("notify").visible = false; dlg.Control("banner").visible = true; } if (msg.event === "hotkey" && msg.control === "today") { if (ini_dlg.focus) ini_dlg.value = today; else if (fin_dlg.focus) fin_dlg.value = today; } } dlg = null; str_values = null; Log(1, "===CalcDates Custom Command finished==="); } function datesinLabels(ini_c, ini_date, fin_c, end_date, date_format) { try { ini_c.label = ini_date.format(date_format); fin_c.label = end_date.format(date_format); return true; } catch (err) { Log(3, "Check the format set in date_format, it seems to be invalid"); ini_c.label = ini_date.format("D#MMMM d', 'yyyy"); fin_c.label = end_date.format("D#MMMM d', 'yyyy"); return false; } } function CalcDiff(fecha_inicio, fecha_fin, sep, str_values) { Log(1, "================================="); Log(1, "Start date : " + fecha_inicio.format("D#dd-MM-yyyy")); Log(1, "End date : " + fecha_fin.format("D#dd-MM-yyyy")); if (fecha_inicio.Compare(fecha_fin) === 1) return DOpus.strings.Get("err_str");; var año_inicio = fecha_inicio.year; var mes_inicio = fecha_inicio.month; var dia_inicio = fecha_inicio.day; var dia_fin = fecha_fin.day; var mes_fin = fecha_fin.month; var año_fin = fecha_fin.year; var m = mes_fin - mes_inicio; var d = dia_fin - dia_inicio; var y = año_fin - año_inicio; if (d < 0) { m--; d += new Date(año_inicio, mes_inicio, 0).getDate(); } if (m < 0) { y--; m += 12; } Log(1, "years : " + y); Log(1, "months : " + m); Log(1, "days : " + d); y = formatNumber(y, str_values("year"), str_values("years")); m = formatNumber(m, str_values("month"), str_values("months")); d = formatNumber(d, str_values("day"), str_values("days"), y || m ? false : true); res = y; res += (res && m ? sep : "") + m; res += (res && d ? sep : "") + d; Log(1, "result : " + res); Log(1, "================================="); return res; } function Copy_to_Clip(dlg, fecha_inicio, fecha_fin) { try { DOpus.SetClip(fecha_inicio.format("D#dd-MM-yyyy") + "\t" + fecha_fin.format("D#dd-MM-yyyy") + "\t" + dlg.Control("resultado").label); dlg.SetTimer(1000, "notify_clip_copy"); dlg.Control("notify").visible = true; dlg.Control("banner").visible = false; dlg.Control("notify").label = DOpus.strings.Get("notify_str"); } catch (err) { Log(3, "Error when copying to clipboard : " + err); } return; } function esfechaValida(fecha) { var regex = /^(0?[1-9]|[12][0-9]|3[01])[/,\-](0?[1-9]|1[0-2])[/,\-](\d{2}|\d{4})$/; var match = regex.exec(fecha); if (!match) return false; var dia = parseInt(match[1], 10); var mes = parseInt(match[2], 10); var anio = (match[3].length <= 2) ? ((match[3] > 30) ? 19 + match[3] : 20 + match[3]) : match[3]; var ultimoDiaMes = new Date(anio, mes, 0).getDate(); if (dia > ultimoDiaMes) return false; var fecha = DOpus.Create.Date(); fecha.year = anio; fecha.month = mes; fecha.day = dia; return fecha; } function formatNumber(numero, singular, plural, force) { if (numero === 1) return numero + " " + singular; else if (numero > 1 || force) //useful when there's nothing but zero days return numero + " " + plural; else return ""; } function Log(level, text) { if (Script.config.debug < level || level == 3) { if (level == 1) DOpus.Output("INFO => " + text); else if (level == 2) DOpus.Output("WARNING => " + text); else DOpus.Output("ERROR => " + text, true); } } ==SCRIPT RESOURCES Valid DOpus syntax for displaying dates in a specific format. day days Logging level to be displayed. OFF to shows none. ALL to shows all the messages. WARNING to shows error conditions that are of consideration. Error: Start date is later than end date month months Waiting for valid dates to continue... Copied to clipboard! Calculating dates... If true, prefill end date with today's date value. Separator to use between the years, months and day calculated. year years Sintaxis de DOpus válida para mostrar fechas con un formato especifico. día días Nivel de registro a mostrar. OFF para no mostrar ninguno. INFO para mostrar todos los mensajes. WARNING para mostrar errores de consideración. Error: Fecha de inicio es posterior a la fecha final mes meses Esperando fechas válidas para continuar... Copiado al portapapeles! Calculando fechas... Usar fecha actual como fecha final Separador a usar entre los años, meses y día calculados año años