代码拉取完成,页面将自动刷新
package utils
import (
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
"math"
"strconv"
"strings"
)
type (
// ShareFeeItem 计算分摊金额属性
ShareFeeItem struct {
Total float64 // 计算分摊总额,例如:优惠券抵扣金额
TotalFee float64 // 计算比例总额,例如:商品总额
UnitFee float64 // 单价:商品单价
}
// AgeItem 计算年龄
AgeItem struct {
Birthday string // 生日
Type int // 类型:0默认年岁,1年月,2年月日, 3年月日时,4年月日时分
IsFmt bool // 是否格式年月日:false默认格式化,true不格式化返回(岁数,不返月份和天数)
}
)
// ShareFeeOrRate 计算分摊金额和比例
func ShareFeeOrRate(item ShareFeeItem, addShareFee, addRate *float64) (shareFee, rate float64) {
// 累计分摊金额大于计算分摊总额或分摊比例大于1-解引用
if *addShareFee >= item.Total || *addRate >= 1 {
return 0, 0
}
// 计算分摊比例和金额
rate = Div(item.UnitFee, item.TotalFee, 3)
shareFee = Mul(rate, item.Total, 2)
// 确保分摊累计不能超过1:保留两位数精度
if *addRate+rate >= 0.99 {
shareFee = Scale(item.Total-*addShareFee, 2)
rate = Scale(1-*addRate, 3)
}
// 累计分摊金额和比例-引用传递
*addShareFee += shareFee
*addRate += rate
return shareFee, rate
}
// Age 计算年龄
func Age(item AgeItem) (age uint, fmAge string) {
// 格式化时间
var (
birthday int64
ageArr []string
dUnit float64 = 86400
units = []float64{365.25 * dUnit, 30.4375 * dUnit, dUnit, 3600, 60}
)
switch gstr.IsNumeric(item.Birthday) {
case false:
// 格式化时间
birthday = gtime.New(item.Birthday).Timestamp()
default:
// 默认时间戳
birthday = gconv.Int64(item.Birthday)
}
// 获取当前时间-出生年龄,获得时间戳
dayTime := float64(gtime.Timestamp() - birthday)
if dayTime < dUnit && item.Type < 3 {
return 0, ""
}
// 处理计算实际年龄
for key, u := range units {
// 计算年龄
tempAge := math.Floor(dayTime / u)
// 计算出年龄不在计算月日
if age == 0 {
age = uint(tempAge)
// 不允许格式化,只能返回年龄(一年以内直接返回0,若要计算虚岁,则向上取一)
if item.IsFmt == true {
return age, ""
}
}
// 指定类型计算设定类型,截断后续操作
if key == item.Type {
break
}
// 计算出当前等于0,不操作
if tempAge == 0 {
continue
}
fm := strconv.Itoa(int(tempAge))
// 递减去当前等级的时间戳
dayTime -= tempAge * u
// 拼接时间单位
switch key {
case 0:
fm += "岁"
case 1:
fm += "月"
case 2:
fm += "天"
case 3:
fm += "小时"
case 4:
fm += "分"
default:
}
ageArr = append(ageArr, fm)
}
// 拼接并格式化时间
return age, strings.Join(ageArr, "")
}
// Add 加法,两数及以上的数值累计相加之和,并保留小数点后两位
// Example:
// Add(100, 2000, 2, 100.01111)
// Output: 2200.01
func Add(x, y interface{}, decimal float64, z ...interface{}) float64 {
sum := Float64(x) + Float64(y)
if len(z) > 0 {
for _, v := range z {
sum += Float64(v)
}
}
return Scale(sum, decimal)
}
// Sub 减法,两数及以上的数值累计之差,并保留小数点后两位
// Example:
// Sub(100, 2000, 2, 100.01111)
// Output: -2000.01
func Sub(x, y interface{}, decimal float64, z ...interface{}) float64 {
s := Float64(x) - Float64(y)
if len(z) > 0 {
for _, v := range z {
s -= Float64(v)
}
}
return Scale(s, decimal)
}
// Mul 乘法,两数及以上的数值乘积,并保留小数点后两位
// Example:
// Mul(100, 2000, 2, 100.01111)
// Output: 2.0002222e+07
func Mul(x, y interface{}, decimal float64, z ...interface{}) float64 {
s := Float64(x) * Float64(y)
if len(z) > 0 {
for _, v := range z {
s *= Float64(v)
}
}
if s == 0 {
return 0
}
return Scale(s, decimal)
}
// Div 除法, 两数相除
// Example:
// Sub(999, 8989.5645, 2)
// Output: 0.11
func Div(x, y interface{}, decimal float64) float64 {
if Float64(y) == 0 || Float64(x) == 0 {
return 0
}
s := Float64(x) / Float64(y)
return Scale(s, decimal)
}
// Scale 保留小数点-四舍五入算法
// Example:
// Scale(98.88888, 2) 保留两位小数
// Output: 98.89
func Scale(s, decimal float64) float64 {
// 保留小数点,注:避免小数点小于等于0,计算错误
var d float64 = 1
if decimal > 1 {
d = math.Pow(10, decimal) // 10的N次方
}
return math.Round(s*d) / d
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。