0
|
1 /****************************************************************************/
|
2
|
2 /* Entai.go ( ver 0.2 ) */
|
|
3 /* Last Change: 2016-10-07 Fri 18:32:08. */
|
0
|
4 /****************************************************************************/
|
|
5
|
|
6 package entai
|
|
7
|
|
8 import (
|
|
9 "fmt"
|
|
10 "time"
|
|
11 )
|
|
12
|
|
13 var rate0s, rate1s []float64
|
|
14 var nyds []time.Time
|
|
15
|
|
16 type Entai struct {
|
|
17 tax int // 税額
|
|
18 ed int // 経過日数
|
|
19 yd0 []int // 各年の 1カ月以内の日数
|
|
20 yd1 []int // 各年の 1カ月超えの日数
|
|
21
|
|
22 due time.Time
|
|
23 paid time.Time
|
|
24 am time.Time
|
|
25 }
|
|
26
|
|
27 func init() {
|
|
28 // 1カ月まで, 1カ月経過後, 元旦
|
|
29 createRates( 4.3, 14.6, "20120101" ) // H24
|
|
30 createRates( 4.3, 14.6, "20130101" ) // H25
|
|
31 createRates( 4.3, 14.6, "20140101" ) // H26
|
|
32 createRates( 2.9, 9.2, "20150101" ) // H27
|
|
33 createRates( 2.8, 9.1, "20160101" ) // H28
|
2
|
34 createRates( 2.8, 9.1, "20170101" ) // H29 *****
|
0
|
35 }
|
|
36
|
2
|
37 func createRates( r0, r1 float64, nyd string ) {
|
|
38 t, _ := time.Parse( "20060102", nyd )
|
0
|
39 rate0s = append( rate0s, r0 / 100 )
|
|
40 rate1s = append( rate1s, r1 / 100 )
|
|
41 nyds = append( nyds, t )
|
|
42 }
|
|
43
|
|
44 func ( e Entai ) String() string {
|
|
45 return "Entai....."
|
|
46 }
|
|
47
|
|
48 func ( e Entai ) GetRate() string {
|
|
49 var str string
|
|
50 for i, n := range nyds {
|
|
51 str += fmt.Sprintf( " (H%d) ", n.Year() - 1988 )
|
|
52 str += fmt.Sprintf( "%s :%4.1f / %4.1f\n", n.Format("2006.01.02"), rate0s[i] * 100, rate1s[i] * 100 )
|
|
53 }
|
|
54 return str
|
|
55 }
|
|
56
|
|
57 func ( e *Entai ) countDays() {
|
|
58
|
2
|
59 for i, _ := range nyds {
|
|
60 e.yd0[i] = 0
|
|
61 e.yd1[i] = 0
|
0
|
62 }
|
|
63
|
|
64 // 1カ月後の算出
|
|
65 for tmp := e.due; ; {
|
|
66 tmp = tmp.AddDate( 0, 0, 1 )
|
|
67 for i, nyd := range nyds {
|
|
68 if tmp.Year() == nyd.Year() {
|
|
69 e.yd0[i]++
|
|
70 }
|
|
71 }
|
|
72 if tmp.Day() == e.due.Day() {
|
|
73 e.am = tmp
|
|
74 break
|
|
75 }
|
2
|
76 if tmp == e.due.AddDate( 0, 1, 0 ) {
|
|
77 tmp = tmp.AddDate( 0, 0, -1 )
|
|
78 e.am = tmp
|
|
79 break
|
|
80 }
|
0
|
81 }
|
|
82
|
|
83 // 過ぎた日数の算出
|
|
84 for i := 1; ; i++ {
|
|
85 tmp := e.due.AddDate( 0, 0, i )
|
|
86 for j, nyd := range nyds {
|
|
87 if tmp.Year() == nyd.Year() {
|
|
88 e.yd1[j]++
|
|
89 }
|
|
90 }
|
|
91 if e.paid.Sub( tmp ) == 0 {
|
|
92 for j, _ := range nyds {
|
|
93 e.yd1[j] -= e.yd0[j]
|
|
94 }
|
|
95 e.yd1[len(e.yd1)-1]--
|
|
96 e.ed = i - 1
|
|
97 break
|
|
98 }
|
|
99 }
|
|
100 }
|
|
101
|
2
|
102 func ( e *Entai ) Create() {
|
|
103 for range nyds {
|
|
104 e.yd0 = append( e.yd0, 0 )
|
|
105 e.yd1 = append( e.yd1, 0 )
|
|
106 }
|
|
107 }
|
|
108
|
0
|
109 func ( e *Entai ) Set( d, p time.Time, g int ) {
|
|
110 e.due, e.paid = d, p
|
|
111 e.tax = g
|
|
112 e.countDays()
|
|
113 }
|
|
114
|
|
115 func ( e *Entai ) Result() ( int, string ) {
|
|
116
|
|
117 /* 税額の前処理 */
|
|
118 if e.tax < 2000 {
|
|
119 return 0, "tax < 2000"
|
|
120 }
|
|
121 e.tax = int( e.tax / 1000 * 1000 ) // 端数処理
|
|
122
|
|
123 /* 本計算 */
|
|
124 var tmp float64
|
|
125 for i, _ := range nyds {
|
2
|
126 tmp += float64( e.yd0[i] ) * rate0s[i] + float64( e.yd1[i] ) * rate1s[i]
|
0
|
127 }
|
2
|
128 tmp *= float64( e.tax ) / 365.0
|
0
|
129
|
|
130 /* 利息の後処理&端数処理 */
|
|
131 var intrst int
|
|
132 if tmp < 1000 {
|
|
133 intrst = 0
|
|
134 } else {
|
|
135 intrst = int( tmp / 100 ) * 100
|
|
136 }
|
|
137
|
|
138 /* 追加情報 */
|
2
|
139 detail := fmt.Sprintf( "%d,%.0f,%d =", e.tax, tmp, e.ed )
|
0
|
140 for i, _ := range nyds {
|
2
|
141 tmp1 := float64( e.yd0[i] ) * rate0s[i] * float64( e.tax ) / 365.0
|
|
142 tmp2 := float64( e.yd1[i] ) * rate1s[i] * float64( e.tax ) / 365.0
|
|
143 detail += fmt.Sprintf( ": %d %d (%.0f+%.0f=%.0f)", e.yd0[i], e.yd1[i], tmp1, tmp2, tmp1 + tmp2 )
|
0
|
144 }
|
|
145
|
2
|
146 return intrst, detail
|
0
|
147 }
|
|
148
|