Skip to content

Commit

Permalink
Merge pull request #8358 from surveyjs/features/8357-datediff
Browse files Browse the repository at this point in the history
Add dateDiff function into function factory fix #8357
  • Loading branch information
andrewtelnov authored Jun 4, 2024
2 parents 76ab02c + 36b59c4 commit 8a7311d
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 13 deletions.
32 changes: 20 additions & 12 deletions src/functionsfactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,22 +235,30 @@ function getDate(params: any[]): any {
}
FunctionFactory.Instance.register("getDate", getDate);

function age(params: any[]): any {
if (!params && params.length < 1) return null;
if (!params[0]) return null;
const birthDate = new Date(params[0]);
const today = new Date();
let age = today.getFullYear() - birthDate.getFullYear();
if(age > 0) {
const m = today.getMonth() - birthDate.getMonth();
if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
age -= 1;
}
function dateDiffMonths(date1Param: any, date2Param: any, type: string): number {
if(type === "days") return diffDays([date1Param, date2Param]);
const date1 = !!date1Param ? new Date(date1Param) : new Date();
const date2 = !!date2Param ? new Date(date2Param) : new Date();
const age = date2.getFullYear() - date1.getFullYear();
type = type || "years";
let ageInMonths = age * 12 + date2.getMonth() - date1.getMonth();
if (date2.getDate() < date1.getDate()) {
ageInMonths -= 1;
}
return age;
return type === "months" ? ageInMonths : ~~(ageInMonths / 12);
}
function age(params: any[]): number {
if(!Array.isArray(params) || params.length < 1 || !params[0]) return null;
return dateDiffMonths(params[0], undefined, (params.length > 1 ? params[1] : "") || "years");
}
FunctionFactory.Instance.register("age", age);

function dateDiff(params: any[]): any {
if(!Array.isArray(params) || params.length < 2 || !params[0] || !params[1]) return null;
return dateDiffMonths(params[0], params[1], (params.length > 2 ? params[2] : "") || "days");
}
FunctionFactory.Instance.register("dateDiff", dateDiff);

function isContainerReadyCore(container: any): boolean {
if (!container) return false;
var questions = container.questions;
Expand Down
32 changes: 31 additions & 1 deletion tests/expressions/expressionParserTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,37 @@ QUnit.test("Run age function, Bug#2562", function(assert) {
values.birthday = date;
assert.equal(runner.run(values), 79, "one day till 80");
});

QUnit.test("Run dateDiff by years function", function(assert) {
const runner = new ExpressionRunner("dateDiff({birthday}, {currentDate}, 'years')");
const values = { birthday: new Date(1974, 10, 10), currentDate: new Date(2014, 11, 11) };
assert.equal(runner.run(values), 40, "Use the second parameter");
});
QUnit.test("Run age by months function", function(assert) {
const runner = new ExpressionRunner("age({birthday}, 'months')");
var date = new Date(Date.now());
date.setFullYear(date.getFullYear() - 10);
const values = { birthday: date };
assert.equal(runner.run(values), 10 * 12, "10 years old, bithday is today");
date = new Date(date.getTime() + 60 * 60 * 24 * 1000);
values.birthday = date;
assert.equal(runner.run(values), 9 * 12 + 11, "9 years + 11 months");
});
QUnit.test("Run dateDiff by months", function(assert) {
const runner = new ExpressionRunner("dateDiff({birthday}, {currentDate}, 'months')");
const values = { birthday: new Date(2012, 10, 10), currentDate: new Date(2014, 11, 11) };
assert.equal(runner.run(values), 2 * 12 + 1, "Use the second parameter, #1");
values.currentDate = new Date(2014, 11, 9);
assert.equal(runner.run(values), 2 * 12, "Use the second parameter, #2");
});
QUnit.test("Run dateDiff by days", function(assert) {
var runner = new ExpressionRunner("dateDiff({d1}, {d2})");
var d1 = new Date("2021-01-01");
var d2 = new Date("2021-02-02");
const values = { d1: d1, d2: d2 };
assert.equal(runner.run(values), 32, "32 days");
(<any>values).d1 = undefined;
assert.equal(runner.run(values), null, "a value is undefined");
});
QUnit.test("Run getYear() function", function(assert) {
var runner = new ExpressionRunner("getYear({birthday})");
var values = { birthday: new Date(1974, 1, 1) };
Expand Down

0 comments on commit 8a7311d

Please sign in to comment.