65
|
1 /*
|
|
2 Last Change: 2021-09-07 火 14:39:09.
|
|
3 */
|
41
|
4 package main
|
|
5
|
|
6 import (
|
65
|
7 "bufio"
|
41
|
8 "encoding/csv"
|
|
9 "encoding/json"
|
|
10 "fmt"
|
|
11 "log"
|
|
12 "os"
|
|
13 "sort"
|
|
14 "strings"
|
|
15 "time"
|
|
16
|
|
17 "golang.org/x/text/encoding/japanese"
|
|
18 "golang.org/x/text/transform"
|
|
19 )
|
|
20
|
|
21 const jsonfile = "porori.json"
|
|
22
|
|
23 type Sinsei struct {
|
|
24 No string
|
|
25 Name string
|
|
26 Ymd string
|
|
27 Kbn string
|
|
28 Ccn string
|
|
29 Bgn string
|
|
30 End string
|
65
|
31 Hist string
|
|
32 ReqI string
|
|
33 Acc string
|
|
34 ReqC string
|
|
35 Visit string
|
|
36 Remark string
|
41
|
37 }
|
|
38
|
|
39 func (s Sinsei) String() string {
|
65
|
40 s.ChangeExpression()
|
|
41
|
|
42 var ymd, ccn, bgn, end, reqi, acc, reqc, visit, remark time.Time
|
|
43 ymd, s.Ymd = s.TransDate(s.Ymd)
|
|
44 ccn, s.Ccn = s.TransDate(s.Ccn)
|
|
45 bgn, s.Bgn = s.TransDate(s.Bgn)
|
|
46 end, s.End = s.TransDate(s.End)
|
|
47 reqi, s.ReqI = s.TransDate(s.ReqI)
|
|
48 acc, s.Acc = s.TransDate(s.Acc)
|
|
49 reqc, s.ReqC = s.TransDate(s.ReqC)
|
|
50 visit, s.Visit = s.TransDate(s.Visit)
|
|
51 remark, s.Remark = s.TransDate(s.Remark)
|
|
52
|
|
53 term := fmt.Sprintf("%d", s.CalcTerm(bgn, end))
|
|
54 ridays := fmt.Sprintf("%d", s.CountDay(ymd, reqi))
|
|
55 adays := fmt.Sprintf("%d", s.CountDay(reqi, acc))
|
|
56 rcdays := fmt.Sprintf("%d", s.CountDay(ymd, reqc))
|
|
57 vdays := fmt.Sprintf("%d", s.CountDay(reqc, visit))
|
|
58 tdays := fmt.Sprintf("%d", s.CountDay(visit, remark))
|
|
59 rdays := fmt.Sprintf("%d", s.CountDay(ymd, ccn))
|
|
60 return strings.Join([]string{s.No, s.Name, s.Ymd, s.Kbn, s.Bgn, s.End, term, s.Ccn, rdays, s.ReqI, ridays, s.Acc, adays, s.ReqC, rcdays, s.Visit, vdays, s.Remark, tdays}, ",")
|
41
|
61 }
|
|
62
|
|
63 func (s Sinsei) TransDate (ymd string) (time.Time, string) {
|
|
64 zero := time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)
|
|
65 if !strings.HasPrefix(ymd, "20") {
|
|
66 return zero, "" // it's dummy
|
|
67 }
|
|
68 t, _ := time.Parse("20060102", ymd)
|
|
69 return t, t.Format(" 2006-01-02")
|
|
70 }
|
|
71
|
65
|
72 func (s Sinsei) CalcTerm(bgn, end time.Time) int {
|
|
73 if bgn.IsZero() || end.IsZero() {
|
41
|
74 return 0
|
|
75 }
|
|
76
|
|
77 m := (end.Year() * 12 + int(end.Month())) - (bgn.Year() * 12 + int(bgn.Month()))
|
|
78 if bgn.Day() == 1 {
|
|
79 m++
|
|
80 }
|
|
81 return m
|
|
82 }
|
|
83
|
65
|
84 func (s Sinsei) CountDay(bgn, end time.Time) int {
|
|
85 if bgn.IsZero() || end.IsZero() {
|
|
86 return -9999
|
|
87 }
|
|
88
|
|
89 if bgn.Year() == end.Year() {
|
|
90 return end.YearDay() - bgn.YearDay()
|
|
91 }
|
|
92 if end.Year() - bgn.Year() == 1 {
|
|
93 d := 365 - bgn.YearDay() + end.YearDay()
|
|
94 if bgn.Year() % 4 == 0 { // can use 2001 - 2099
|
|
95 d++
|
|
96 }
|
|
97 return d
|
|
98 }
|
|
99
|
|
100 return -9999
|
|
101 }
|
|
102
|
41
|
103 func (s *Sinsei) ChangeExpression() {
|
|
104 s.No = "=\"" + strings.TrimSpace(s.No) + "\""
|
|
105
|
|
106 switch s.Kbn {
|
|
107 case "01":
|
|
108 s.Kbn = "新規"
|
|
109 case "02":
|
|
110 s.Kbn = "更新"
|
|
111 case "10":
|
|
112 s.Kbn = "支介"
|
|
113 case "05":
|
|
114 s.Kbn = "区変"
|
|
115 case "03":
|
|
116 s.Kbn = "転入"
|
|
117 case "09":
|
|
118 s.Kbn = "証交"
|
|
119 }
|
|
120 s.Kbn, _, _ = transform.String(japanese.ShiftJIS.NewEncoder(), s.Kbn)
|
65
|
121 }
|
41
|
122
|
65
|
123 func read_line(file string) ([]string, error) {
|
|
124 f, err := os.Open(file)
|
|
125 if err != nil {
|
|
126 return nil, err
|
|
127 }
|
|
128 defer f.Close()
|
41
|
129
|
65
|
130 var s []string
|
|
131 scanner := bufio.NewScanner(f)
|
|
132 for scanner.Scan() {
|
|
133 s = append(s, scanner.Text())
|
|
134 }
|
|
135 if err := scanner.Err(); err != nil {
|
|
136 return nil, err
|
|
137 }
|
|
138 return s, nil
|
41
|
139 }
|
|
140
|
|
141 func main() {
|
|
142
|
65
|
143 if len(os.Args) != 5 {
|
41
|
144 fmt.Fprint(os.Stderr, "bat input.")
|
|
145 os.Exit(1)
|
|
146 }
|
|
147
|
|
148 // Filter Setting
|
|
149 type YF struct {
|
|
150 From string
|
|
151 To string
|
|
152 }
|
|
153 var yf YF
|
|
154
|
65
|
155 content, err := os.ReadFile(jsonfile)
|
41
|
156 if err != nil {
|
|
157 log.Fatal(err)
|
|
158 }
|
|
159 if err := json.Unmarshal(content, &yf); err != nil {
|
|
160 log.Fatal(err)
|
|
161 }
|
|
162
|
|
163 // Read CSV
|
65
|
164 content, err = os.ReadFile(os.Args[1]) // nintei.csv
|
41
|
165 if err != nil {
|
|
166 log.Fatal(err)
|
|
167 }
|
|
168
|
|
169 r := csv.NewReader(strings.NewReader(string(content)))
|
|
170
|
|
171 records, err := r.ReadAll()
|
|
172 if err != nil {
|
|
173 log.Fatal(err)
|
|
174 }
|
|
175
|
65
|
176 ikensho, err := read_line(os.Args[2]) // i.csv
|
|
177 if err != nil {
|
|
178 log.Fatal(err)
|
|
179 }
|
|
180 chosa, err := read_line(os.Args[3]) // c.csv
|
|
181 if err != nil {
|
|
182 log.Fatal(err)
|
|
183 }
|
|
184
|
|
185 remark, err := read_line(os.Args[4]) // t.csv
|
|
186 if err != nil {
|
|
187 log.Fatal(err)
|
|
188 }
|
|
189
|
41
|
190 // Main Proccess
|
|
191 var sinsei []Sinsei
|
|
192
|
|
193 for _, record := range records {
|
65
|
194 if record[5] < yf.From || record[5] > yf.To {
|
41
|
195 continue
|
|
196 }
|
65
|
197 var riymd, aymd, rcymd, vymd string
|
|
198 key := strings.Join([]string{record[0], record[1]}, ",")
|
|
199 for _, i := range ikensho {
|
|
200 if strings.HasPrefix(i, key) {
|
|
201 riymd = strings.Split(i, ",")[2]
|
|
202 aymd = strings.Split(i, ",")[3]
|
|
203 break
|
|
204 }
|
|
205 }
|
|
206 for _, c := range chosa {
|
|
207 if strings.HasPrefix(c, key) {
|
|
208 rcymd = strings.Split(c, ",")[2]
|
|
209 vymd = strings.Split(c, ",")[3]
|
|
210 break
|
|
211 }
|
|
212 }
|
|
213 var rymd string
|
|
214 for _, t := range remark {
|
|
215 h := strings.TrimSpace(record[0])
|
|
216 c := strings.Split(t, ",")
|
|
217 if strings.EqualFold(h, c[0]) && strings.EqualFold(record[3], c[1]) {
|
|
218 rymd = c[2]
|
|
219 break
|
|
220 }
|
|
221 }
|
41
|
222
|
|
223 ss := Sinsei{
|
|
224 No: record[0],
|
65
|
225 Hist: record[1],
|
|
226 Name: record[2],
|
|
227 Ymd: record[3],
|
|
228 Kbn: record[4],
|
|
229 Ccn: record[5],
|
|
230 Bgn: record[6],
|
|
231 End: record[7],
|
|
232 ReqI: riymd,
|
|
233 Acc: aymd,
|
|
234 ReqC: rcymd,
|
|
235 Visit: vymd,
|
|
236 Remark: rymd,
|
41
|
237 }
|
|
238 sinsei = append(sinsei, ss)
|
|
239 }
|
|
240
|
|
241 sort.Slice(sinsei, func(i, j int) bool {
|
|
242 return sinsei[i].Ymd < sinsei[j].Ymd
|
|
243 })
|
|
244
|
|
245 // Output
|
65
|
246 header := strings.Join([]string{"被保番", "氏名", "申請日", "区分", "開始日", "終了日", "期間", "審査会", "日数", "意見書依頼", "日数", "意見書入手", "日数", "調査依頼", "日数", "調査", "日数", "特記", "日数"}, ",")
|
41
|
247 header, _, _ = transform.String(japanese.ShiftJIS.NewEncoder(), header)
|
|
248 fmt.Println(header)
|
|
249
|
65
|
250 /*
|
|
251 for i, s := range sinsei {
|
|
252 fmt.Print(s)
|
|
253 fmt.Printf(",=\"0\"&A%d\n", i + 2)
|
|
254 }
|
|
255 */
|
41
|
256 for _, s := range sinsei {
|
|
257 fmt.Println(s)
|
|
258 }
|
|
259 }
|
|
260
|