view src/entai/entai.go @ 8:bf5d764cd80d

New: csv2json.go
author pyon@macmini
date Sun, 13 Nov 2016 14:44:16 +0900
parents e4066309b04f
children
line wrap: on
line source

/****************************************************************************/
/* Entai.go ( ver 0.3 )                                                     */
/*                                    Last Change: 2016-10-22 Sat 15:06:28. */
/*                                    By T.Mutoh                            */
/****************************************************************************/

package entai

import (
    "fmt"
    "strconv"
    "time"
)

var rate0s, rate1s []float64
var nyds           []time.Time

type Entai struct {
    tax    int	 // 税額
	ed     int   // 経過日数
	yd0    []int // 各年の 1カ月以内の日数
	yd1    []int // 各年の 1カ月超えの日数

    due     time.Time
    paid    time.Time
    am      time.Time
}

func init() {
}

func ( e *Entai ) DefaultRates() {
    // 1カ月まで, 1カ月経過後, 元旦
	createRates( 4.3, 14.6, "20120101" )	// H24
	createRates( 4.3, 14.6, "20130101" )	// H25
	createRates( 2.9,  9.2, "20140101" )	// H26
	createRates( 2.8,  9.1, "20150101" )	// H27
	createRates( 2.8,  9.1, "20160101" )	// H28
	createRates( 2.8,  9.1, "20170101" )	// H29 *****

	for range nyds {
		e.yd0 = append( e.yd0, 0 )
		e.yd1 = append( e.yd1, 0 )
	}
}

func createRates( r0, r1 float64, nyd string ) {
	t, _ := time.Parse( "20060102", nyd )
	rate0s = append( rate0s, r0 / 100 )
	rate1s = append( rate1s, r1 / 100 )
	nyds   = append( nyds, t )
}

func ( e *Entai ) AddRates( nyd, r0, r1 string ) error {
	rf0, err := strconv.ParseFloat( r0, 64 ); if err != nil {
        return err
    }
	rf1, err := strconv.ParseFloat( r1, 64 ); if err != nil {
        return err
    }
	createRates( rf0, rf1, nyd )
    e.yd0 = append( e.yd0, 0 )
    e.yd1 = append( e.yd1, 0 )
    return nil
}

func ( e Entai ) String() string {
    return "Entai....."
}

func ( e Entai ) GetRates() ( str string ) {
	for i, n := range nyds {
		str += fmt.Sprintf( " (H%d) ", n.Year() - 1988 )
		str += fmt.Sprintf( "%s :%4.1f / %4.1f\n", n.Format("2006.01.02"), rate0s[i] * 100, rate1s[i] * 100 )
	}
	return str
}

func ( e *Entai ) countDays() {

	for i, _ := range nyds {
		e.yd0[i] = 0
		e.yd1[i] = 0
	}

	// 1カ月後の算出
    for tmp := e.due; ; {
        tmp = tmp.AddDate( 0, 0, 1 )
		for i, nyd := range nyds {
			if tmp.Year() == nyd.Year() {
				e.yd0[i]++
			}
		}
        if tmp.Day() == e.due.Day() {
			e.am = tmp
            break
        }
		if tmp == e.due.AddDate( 0, 1, 0 ) {
			tmp = tmp.AddDate( 0, 0, -1 )
			e.am = tmp
            break
		}
    }

	// 過ぎた日数の算出
	for i := 1; ; i++ {
		tmp := e.due.AddDate( 0, 0, i )
		for j, nyd := range nyds {
			if tmp.Year() == nyd.Year() {
				e.yd1[j]++
			}
		}
		if e.paid.Sub( tmp ) == 0 {
			for j, _ := range nyds {
				e.yd1[j] -= e.yd0[j]
			}
			e.ed = i
			//e.yd1[len(e.yd1)-1]-- // コメントアウト:最終日を参入しない
            //e.ed--                // 同上
            break
		}
    }
}

func ( e *Entai ) Set( d, p time.Time, g int ) {
    e.due, e.paid = d, p
    e.tax = g
    e.countDays()
}

func ( e *Entai ) Result() ( int, string ) {

	/* 税額の前処理 */
	if e.tax < 2000 {
		return 0, "tax < 2000"
	}
	e.tax = int( e.tax / 1000 ) * 1000 // 端数処理

	/* 本計算 */
	var tmp float64
	for i, _ := range nyds {
		tmp += float64( e.yd0[i] ) * rate0s[i] + float64( e.yd1[i] ) * rate1s[i]
	}
	tmp *= float64( e.tax ) / 365.0

	/* 利息の後処理&端数処理 */
	var intrst int
	if tmp < 1000 {
		intrst = 0
	} else {
		intrst = int( tmp / 100 ) * 100
	}

	/* 追加情報 */
	detail := fmt.Sprintf( "%d,%.0f,%d =", e.tax, tmp, e.ed )
	for i, _ := range nyds {
		tmp1 := float64( e.yd0[i] ) * rate0s[i] * float64( e.tax ) / 365.0
		tmp2 := float64( e.yd1[i] ) * rate1s[i] * float64( e.tax ) / 365.0
		detail += fmt.Sprintf( ": %d %d (%.1f+%.1f=%.1f)", e.yd0[i], e.yd1[i], tmp1, tmp2, tmp1 + tmp2 )
	}

    return intrst, detail
}