Question

I am currently working on a form in InfoPath where users enter a specific date in a field.

I then want a formula to calculate how many days that remain of the year. I also want to value each day to a cost. Say each day cost 2$ and the entered date is December 29th. I then want the function to return "price: 4$"

Était-ce utile?

La solution

XPath 2.0 has an awful lot of date/time functions:

To get the days between the last day of 2012 and the current day, you can use:

days-from-duration(date("2012-12-31") - current-date() )

If you have an user inputed date $user-date you need to replace current-date() with that $user-date and to construct a date object for the last december day in that year, which you can do like:

days-from-duration(date(concat(year-from-date($user-date), "-12-31")) - $user-date )

(or use date($user-date), if $user-date is a string)

And to get the final price string use:

concat("price: ", 2  *  days-from-duration(date(concat(year-from-date($user-date), "-12-31")) - $user-date ), "$")

XPath 1.0:

Without date function you need to do all these stupid calculation by hand.

You need a map mapping the days from each month to the end of the year. Then you can do Map[$month] - $day. (Or use a map mapping the months to the days to the beginning of the year and subtract that from 365, what I do, since I have that map already lying around)

Now XPath 1.0 does not have maps, but you can simulate one with a string:

 365 - substring-before(substring-after( "1:00, 2:31, 3:59, 4:90, 5:120, 6:151, 7:181, 8:212, 9:243, 10:273, 11:304, 12:334, 13:365", concat($month, ":")), ",") - $day

This works for every non leap year.

For a leap year, you just use 366 and add 1 to each month after february:

 366 - substring-before(substring-after( "1:00, 2:31, 3:60, 4:91, 5:121, 6:152, 7:182, 8:213, 9:244, 10:274, 11:305, 12:335, 13:366", concat($month, ":")), ",") - $day

To detect the leap year you could do some modulo calculation, it is probably easier to just use a map of all leap years:

concat("0", substring-before(substring-after("...,2000:1,2004:1,2008:1,2012:1,2016:1,...", concat($year, ":")), ",")) * 1

this returns 1 if the year is a leap year in the range

Then put it all together:

 ( 365 - substring-before(substring-after( "1:00, 2:31, 3:59, 4:90, 5:120, 6:151, 7:181, 8:212, 9:243, 10:273, 11:304, 12:334, 13:365", concat($month, ":")), ",") - $day)  * ( 1 - concat("0", substring-before(substring-after("...,2000:1,2004:1,2008:1,2012:1,2016:1,...", concat($year, ":")), ",")) * 1)     +     (366 - substring-before(substring-after( "1:00, 2:31, 3:60, 4:91, 5:121, 6:152, 7:182, 8:213, 9:244, 10:274, 11:305, 12:335, 13:366", concat($month, ":")), ",") - $day) * concat("0", substring-before(substring-after("...,2000:1,2004:1,2008:1,2012:1,2016:1,...", concat($year, ":")), ","))
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top