Estimate date of delivery from last menstrual period using calculate question

calculations
#1

Help me to estimate date of birth from last menstrual period. I need the formula. Thanks

1 Like

#2

google “estimating date of birth”…

0 Likes

#3

Thank u but it doesn’t answer my question

0 Likes

#4

I think what you’re looking for is format-date(date(decimal-date-time(${LMP})+280), "%Y-%m-%d") [edited, thanks to @Xiphware] .

A minimal XLSForm might look like:

type name label calculation
start start
end end
date LMP What was the first day of the last menstrual period?
calculate EDD format-date(date(decimal-date-time(${LMP})+280), “%Y-%m-%d”)
note The_estimated_date_of_delivery_is_EDD The estimated date of delivery is ${EDD}
4 Likes

#5

This will not work. ${LMP} may be a date, but it is stored internally in XForms as a string, so the sub-expression ${LMP}+280 is invalid because you are trying to add a number to a string. XPath will attempt to cast this string - eg “2019-01-02” - to a number using the number() function (which obviously will fail and give you NaN instead).

[@jnm hmm. interesting, your formula does appear to work under Enketo!? I’m not sure why its not throwing an XPath error. I’ll have to check].

@rickaza if there is a specific mathematical formula you are having trouble implementing in Kobo, please clearly state what it is so that others with technical expertise might assist. For example:

“How do I calculate the date 280 days after another date?”

In this example, as you are dealing with dates, you will need to use XPath date functions, which are well documented in ODK Form Operators and Functions. Specifically, in order to add/subtract a period of days to/from a date, you must explicitly convert the dates to/from a number to perform the addition/subtraction, using the decimal-date-time() and date() functions. eg

date(decimal-date-time(${some_date})+280)

which will give you the date 280 days after ${some_date}. At this point you can choose to display the new date in whatever format you desire using format-date().

3 Likes

#6

I find that it works in ODK Collect as well, at least in the version I have, 1.18.2. I wouldn’t post something untested, of course :wink:

I appreciate the clarification, though, and would certainly suggest that everyone use decimal-date-time() as you describe to avoid any unexpected behavior :+1: I’ll edit my post.

0 Likes

#7

After a bit of digging, I think I know what’s happening here: in both Enketo, and Collect, when evaluating arithmetic expressions, their respective XPath evaluators will perform an implicit number() operation on any operands they run across. That is, your expression:

date(${LMP}+280)

actually gets evaluated as:

date(number(${LMP})+280)

Strictly speaking, the formal W3C XPath number() function should throw a NaN error when given a date string like “2019-01-02” (you can test this for yourself here).

However, and although it is not clearly documented in ODK Form Operators and Functions, it is documented in the ODK Xforms Specification that

number(* arg) number As in XPath 1.0. In addition it will convert date- and dateTime-formatted strings to a number of days since January 1, 1970 UTC.

Which is to say, if and only if you are using these forms within the ODK ecosystem, then you can optionally omit converting dates/dateTimes to a number using the prescribed decimal-date-time() because the (non-standard) ODK number() function will in fact do it implicitly for you! That said, IMHO it is probably better to be explicit about it and use decimal-date-time().

So I learned something new today too! :wink:

2 Likes

#8

FYI it turns out there’s currently a bug in ODK Validate around decimal-date-time(), which may mean you cant convert/upload a form using this function to XML without disabling the validation step. But the form itself runs fine on Collect and Enketo, and exporting the form (as XLS or XML) from Kobo works too since it doesn’t do this validation.

The interim workaround if you are using other ODK tools, eg https://opendatakit.org/xlsform/, is to the use number() function instead, which performs the same date-to-decimal conversion.

1 Like

#9

@jnm Thank U. It has been perfectly applied

0 Likes

#10

Thank u so much. it really helps

0 Likes