FormCalc String, Date, and Finance Functions

XFA calculate scripts support the implemented function families beyond arithmetic: string functions, date conversion, and the finance library, with string literals and mixed-type expressions

String functions

Values and References documents Ref, value-copy semantics, reference assignment, null detachment, function arguments, object identity comparisons and retained handles across repeated-instance movement

Dynamic Eval executes source text through the native compiler and general runtime, including locally declared variables, functions, loops, field mutations, locale requests and recorded host transport responses

Concat, Len, Left, Right, Substr, Replace, Lower, Upper, Trim, and Space operate on quoted literals and field references; numeric sub-expressions convert to text automatically

Date functions

The native scalar evaluator converts ISO YYYY-MM-DD text with Date2Num and Num2Date; FormCalc serial days use 1900-01-01 as day 1, and Date() returns today's serial

General execution with EnableJavaScript also supports locale pictures through Date2Num(value, picture, locale), Num2Date(serial, picture, locale), DateFmt, TimeFmt, IsoTime2Num, Time2Num, Num2Time, Num2GMTime and Time

In general execution, omitted Num2Date pictures now use the ambient locale's default pattern; pass "YYYY-MM-DD" explicitly to preserve earlier ISO output, and use IsoDate2Num for strict ISO input

FormCalc Locale and Picture Functions documents parameters, inherited locale selection, embedded localeSet overrides, numeric/text pictures, units, encoding and number words

Advanced Picture Clauses documents scientific notation, expressed fractional precision, ordinal and ISO week dates, clock variants, global symbols and compound parsing in general events, calculations and validation

Finance functions

Financial functions now follow XFA FormCalc parameter semantics in the native calculate evaluator and the general event compiler

FunctionParameters and result
Pmt(principal, rate, periods)Positive periodic loan payment; all arguments must be positive
FV(payment, rate, periods)Future value of equal payments; zero rate returns payment times periods
PV(payment, rate, periods)Present value of equal payments; zero rate returns payment times periods
Rate(future, present, periods)Compound rate required to grow the present value to the future value
CTerm(rate, future, initial)Periods required for a compounded initial investment
Term(payment, rate, future)Periods required for equal payments to reach the future value
Apr(principal, monthlyPayment, periods)Annual percentage rate found by a bounded monthly-rate solver
NPV(rate, cashFlow1, ...)Discounted end-of-period cash flows in argument order
IPmt and PPmtInterest or principal paid for (principal, annualRate, monthlyPayment, firstMonth, months); month indices start at 1 and 0 also selects the first month

This corrects earlier spreadsheet-style argument ordering and sign handling: migrate Pmt(rate, periods, principal) to Pmt(principal, rate, periods) and expect a positive result; FV and PV now operate on periodic payments instead of a single initial or final amount

Rate now computes compound growth; NPer(rate, payment, future) remains a nonstandard extension equivalent to Term(payment, rate, future)

Invalid financial domains reject general events atomically; the native calculate evaluator reports a failed expression, and iteration consumes the configured operation and time budgets

General event library

The general FormCalc event compiler supports case-insensitive built-in names, leading decimal literals, Null, scientific trigonometric functions, Pi, degree/radian conversion, Stuff and Str; Count includes empty text and omits null values, and all-null aggregates return null

Mod preserves the dividend sign in both evaluation paths; Mod(-13, 3) returns -1

Typing

Numeric evaluation stays Double-typed: a formula whose head is a string function resolves textually, and finance results convert back into numeric expressions so Round(Pmt(...), 2) works; any type mismatch still degrades to a blank value

Conditional logic and repeated arrays

Comparisons, And, Or, Not, booleans, and lazy If(condition, whenTrue, whenFalse) expressions provide bounded conditional control flow

Sum, Avg, Min, Max, and Count accept repeated numeric selectors such as rows[*].amount, while their ordinary argument-list forms continue to aggregate scalar expressions

Dynamic instance requests

InstanceAdd(name, count) and InstanceRemove(name, index) invoke the validated instance callback configured by the caller and return the resulting instance count

See Bounded XFA FormCalc and JavaScript for the optional QuickJS path, typed arrays, runtime isolation, budgets, and telemetry

Explicit HTTP transport

General event scripts support case-insensitive Get, Post and Put through explicit application host transport; arguments are forwarded in order and the application supplies the response

These functions require EnableJavaScript and a configured HostTransport callback in the widget runtime; the native scalar evaluator does not perform network requests