To compute the cash flow dates you need to know the maturity date, the tenor, the payment frequency, the business day convention and the holiday calendar.
The cash flow dates step backward from the maturity of the bond, in units of the payment frequency. For example, for a two year bond maturing on 31/12/2017 with a semi-annual coupon, you step back in units of six months, getting
- 31/12/2017
- 30/06/2017
- 31/12/2016
- 30/06/2016
You then need to make a business day adjustment for dates that don't fall on a business day. For example, the 30th Jun 2017 is a Saturday, and the 31st Dec 2016 is a Sunday. You would also need to adjust if a day was a holiday (e.g. Independence Day in the US, or Christmas Day in many countries).
There are four business day conventions in common use -
- Following (move payments to the next business day)
- Previous (move payments to the previous business day)
- Modified Following (move to the next business day, unless it falls in a different month, in which case use the previous business day)
- Modified Previous (move to the previous business day, unless it falls in a different month, in which case use the next business day)
I believe that the convention for US treasuries is Modified Following, though it is worth checking this.
For the payment on 30/06/2017 (Saturday) the next business day is 02/07/2017, but this falls in a different month, so the payment actually happens on 29/06/2017 (a Friday).
For the payment on 31/12/2016 (Sunday) the next business day is 02/01/2017 (which is a Tuesday - note that Monday 1st Jan is a public holiday, even though it is not a weekend) which again falls in a different month, so the payment happens on 29/12/2016 (Friday).
Note that this approach works for most bonds, but not all. For example, Mexican government bonds have a payment frequency of 182 days, rather than 6 months. An advantage of this is that 182 days is exactly 26 weeks, so the payments will always fall on the same day of the week, which reduces the need for business day conventions. On the other hand, it will not always fall on the same day of the month - a payment on Weds 16th March 2016 will be followed by a payment on Weds 14th Sep 2016, rather than Fri 16th Sep 2016. If it is important to get the dates correct for a particular bond, the best thing to do is find a source of static data which can tell you the exact coupon dates (e.g. Bloomberg can do this).