1 <?php
2
3
4 $start = '2019-01-30';
5 $end = '2020-01-29';
6
7
8 // 月账单
9 function billMonth($start, $end) {
10 $m = [];
11 do {
12 $mend = getNextMonthEnd($start);
13 if (strtotime($mend) > strtotime($end)) {
14 $mend = $end;
15 }
16 $m[] = [
17 's' => preDate($start),
18 'e' => $mend
19 ];
20 $start = date('Y-m-d', strtotime($mend) + 3600*24);
21 }
22 while(strtotime($mend) < strtotime($end));
23 return $m;
24 }
25
26 //季度账单
27 function billQuarter($start, $end) {
28 $bill = billMonth($start, $end);
29
30 }
31
32
33 //获得下个月年,月
34 function getNextDate($year, $m) {
35 if ($m == 12) {
36 $m = 1;
37 $year += 1;
38 } else {
39 $m++;
40 }
41 return [$year, $m];
42 }
43
44 //获取月份的最后一天
45 function getMonthLastDay($year, $m) {
46 $t = date('t', strtotime($year .'-'. $m.'-01'));
47 return $t;
48 }
49
50 //获取一个账单结束日
51 function getNextMonthEnd($start) {
52 //获取开始年
53 $year = date('Y', strtotime($start));
54 //获取开始日
55 $d = date('j', strtotime($start));
56 //获取开始月
57 $m = date('n', strtotime($start));
58
59 if ($d == 1) { //如果是第一天,自然月处理
60 $t = getMonthLastDay($year, $m);
61 return sprintf("%s-%s-%s", $year, preNum($m), preNum($t));
62 } else {
63 //判断下个月最大天数
64 list($year, $m) = getNextDate($year, $m);
65 $nextMonthLastDay = getMonthLastDay($year, $m);
66 if ($nextMonthLastDay>$d) { //如果下个月最后一天 大于开始时间的日期, 说明可以做一个月账期
67 return sprintf("%s-%s-%s", $year, preNum($m), preNum($d-1));
68 } else { //做不到,直接截到月末
69 return sprintf("%s-%s-%s", $year, preNum($m), preNum($nextMonthLastDay));
70 }
71 }
72 }
73
74
75
76 //有前导0的日期
77 function preDate($date) {
78 return date('Y-m-d', strtotime($date));
79 }
80
81 //处理前导0
82 function preNum($num) {
83 return substr("0".$num, -2);
84 }
85
86
87 function feeMonth($start, $end, $total_fee) {
88 $bill = billMonth($start, $end);
89 //先算月账单
90
91
92 $perMonth_fee = round($total_fee/count($bill), 2); //每月平均价格
93
94 //看看是不是算多了或少了, 补齐到第一个月
95
96 $tmp = $perMonth_fee * (count($bill) - 1);
97 if (($perMonth_fee + $tmp) > $total_fee) {
98 $firstMonth_fee = $perMonth_fee - (($perMonth_fee + $tmp) - $total_fee);
99 } else {
100 $firstMonth_fee = $total_fee - $tmp;
101 }
102 for($i = 0; $i<count($bill); $i++) {
103 if ($i==0) {
104 $bill[$i]['fee'] = $firstMonth_fee;
105 } else {
106 $bill[$i]['fee'] = $perMonth_fee;
107 }
108 }
109 return $bill;
110 }
111
112 //季度账单
113 function feeQuarter($start, $end, $total_fee) {
114 $feeMonth = feeMonth($start, $end, $total_fee);
115 $q = array_chunk($feeMonth, 3);
116 $quarterFee = [];
117 for($j = 0; $j<count($q); $j++) {
118 $quarterFee[$j] = [
119 'fee' => 0
120 ];
121 for($i=0; $i<count($q[$j]); $i++) {
122 if ($i == 0) {
123 $quarterFee[$j]['s'] = $q[$j][$i]['s'];
124 }
125 $quarterFee[$j]['fee'] += $q[$j][$i]['fee'];
126 if ($i == count($q[$j]) - 1) {
127 $quarterFee[$j]['e'] = $q[$j][$i]['e'];
128 }
129 }
130
131 }
132 return $quarterFee;
133 }
134
135 //年
136 function feeYear($start, $end, $total_fee, $times = 1, $type = 0) {
137 $split = $times * 12;
138 $feeMonth = feeMonth($start, $end, $total_fee);
139 $q = array_chunk($feeMonth, $split);
140 $yearFee = [];
141 for($j = 0; $j<count($q); $j++) {
142 $yearFee[$j] = [
143 'total_taxes' => 0
144 ];
145 if ($type == 1) { //中付 计算中间日期
146 $mid = ceil(count($q[$j])/2) - 1;
147 $mid_start = $q[$j][$mid]['s'];
148 $mid_date = date("Y-m-d", strtotime($mid_start) + 3600 *24 *15);
149 $yearFee[$j]['bill_day'] = $mid_date;
150 }
151
152 for($i=0; $i<count($q[$j]); $i++) {
153 if ($i == 0) {
154 $yearFee[$j]['bill_start_time'] = $q[$j][$i]['s'];
155 if ($type == 0) {
156 $yearFee[$j]['bill_day'] = $q[$j][$i]['s'];
157 }
158 }
159
160 $yearFee[$j]['total_taxes'] += $q[$j][$i]['fee'];
161 if ($i == count($q[$j]) - 1) {
162 $yearFee[$j]['bill_end_time'] = $q[$j][$i]['e'];
163 if ($type == 2) {
164 $yearFee[$j]['bill_day'] = date('Y-m-d', strtotime($q[$j][$i]['e']) + 3600 * 24);
165 }
166 }
167 }
168
169 }
170 return $yearFee;
171 }
172
173 $total_fee = 200000;
174 echo "月账单:\n";
175 print_r(feeYear($start, $end, $total_fee, 0.1, 1));
176 echo "季账单:\n";
177 print_r(feeYear($start, $end, $total_fee, 0.3, 1));
178 //echo "半年账单:\n";
179 //print_r(feeYear($start, $end, $total_fee, 0.5));
180 //echo "全年账单:\n";
181 //print_r(feeYear($start, $end, $total_fee, 1));
182 //echo "2年账单:\n";
183 //print_r(feeYear($start, $end, $total_fee, 2));
184 //echo "5年账单:\n";
185 //print_r(feeYear($start, $end, $total_fee, 5));
186
187 /*
188 echo "总月数:".count($bill)."\n";
189 echo "总费用:". $total_fee."\n";
190 echo "首月价格:".$firstMonth_fee."\n";
191 echo "每月价格:".$perMonth_fee."\n";
192 echo "总费用计算:". ( $firstMonth_fee + $perMonth_fee*(count($bill)-1))."\n";
193 */
194 //如果需要季度账单
195
196
197 ///print_r($bill);