I'd use approach A and hide it behind an interface, since it'll make the algorithm easily exchangeable where you use it.
I'd only use B when I have to store/cache multiple values that are created by a single algorithm. If the costs of a calculation are cheap and I only have to calculate two dates then I'd stick with A and calculate the dates whenever necessary. You can also use a combination of A and B where B is the container and contains the strategy interface (A) internally. But, as I said, I'd only create such a container if I really have to deal with many values (more than 4?)
I'd refrain from the extension methods as you can't have multiple implementations and as you can't interchange the algorithm easily during runtime, which may or may not be a requirement some day, who can predict the future after all?
Edit:
...separate class as it is complicated and can be subject to change for administrative reasons.
Use a strategy pattern. Will you need to have half the forms calculated with the old algorithm and the other half calculated with a newer algorithm or even worse? Will it be likely that you need two or more implementations of the algorithm simultaneously? Do you want to keep the algorithms or configure which one to use? If you have to answer one of these questions with "yes" then C is not an option anymore.
Option C is plain and simple and totally does the job when you are only ever going to need a single algorithm in place for every point in time.