package helper
import (
"github.com/gogf/gf/os/gtime"
"time"
)
const (
DateFormat = "2006-01-02"
DateTimeFormat = "2006-01-02 15:04:05"
PHPDateForm = "Y-m-d"
PHPDateTimeFormat = "Y-m-d H:i:s"
)
//获取某天的开始时间
func GetDayStartFromTimestamp(timestamp int64) int64 {
dateTimeStamp := gtime.NewFromTimeStamp(timestamp)
//某天0点
dateStr := dateTimeStamp.Format(PHPDateForm) + " 00:00:00"
zeroTime, _ := gtime.StrToTime(dateStr)
return zeroTime.Unix()
}
// 获取某天的开始时间
// dateStr 格式如2006-01-02 15:04:05
func GetDayStartFromStr(dateStr string) int64 {
nowTime, err := gtime.StrToTime(dateStr)
if err != nil {
return 0
}
return GetDayStartFromTimestamp(nowTime.Unix())
}
func GetDayEndFromTimestamp(timestamp int64) int64 {
dateTimeStamp := gtime.NewFromTimeStamp(timestamp)
//某天23:59:59
day := time.Second * 86400
return dateTimeStamp.Add(day).Unix() - 1
}
// 获取某天的结束时间
// dateStr 格式如2006-01-02 15:04:05
func GetDayEndFromStr(dateStr string) int64 {
nowTime, err := gtime.StrToTime(dateStr)
if err != nil {
return 0
}
return GetDayEndFromTimestamp(nowTime.Unix())
}
func TodayStartTime() int64 {
timeStr := time.Now().Format("2006-01-02")
t, _ := time.Parse("2006-01-02", timeStr)
timeNumber := t.Unix()
return timeNumber
}
func TodayEndTime() int64 {
timeStr := time.Now().Add(time.Second * 86400).Format(DateFormat)
t, _ := time.Parse(DateFormat, timeStr)
timeNumber := t.Unix() - 1
return timeNumber
}
//当前时间
func NowTime(args ...int) uint {
var (
nowTime uint
timeAdd int
)
if len(args) > 0 {
timeAdd = args[0]
nowTime = uint(gtime.Now().Unix()) + uint(timeAdd)
} else {
nowTime = uint(gtime.Now().Unix())
}
return nowTime
}
// 同php in_array
func InArray(search interface{}, array interface{}, deep bool) bool {
val := reflect.ValueOf(array)
val = val.Convert(val.Type())
typ := reflect.TypeOf(array).Kind()
switch typ {
case reflect.Map:
s := val.MapRange()
for s.Next() {
s.Value().Convert(s.Value().Type())
for i := 0; i < s.Value().Len(); i++ {
if deep {
if reflect.DeepEqual(search, s.Value().Index(i).Interface()) {
return true
}
} else {
str := s.Value().Index(i).String()
if strings.Contains(str, search.(string)) {
return true
}
}
}
}
case reflect.Slice, reflect.Array:
for i := 0; i < val.Len(); i++ {
if reflect.DeepEqual(search, val.Index(i).Interface()) {
return true
}
}
}
return false
}
// 获取配置信息
func Config(configFileDir string) *gcfg.Config {
//获取当前工作目录
if len(configFileDir) == 0 {
curDir, _ := os.Getwd()
parentDir := GetParentDirectory(curDir)
configFileDir = parentDir + gfile.Separator + "config"
if !gfile.IsDir(configFileDir) {
msg := "配置文件目录不正确:" + configFileDir
log.Fatalln(msg)
}
}
g.Cfg().SetPath(configFileDir)
return g.Cfg()
}
// 获取默认头像
func GetDefaultAvatar() string {
avatar := g.Cfg().GetString("app.defaultAvatar")
return avatar
}
// 截取字符
func Substr(s string, pos, length int) string {
runes := []rune(s)
l := pos + length
if l > len(runes) {
l = len(runes)
}
return string(runes[pos:l])
}
// 获取父级目录
func GetParentDirectory(dir string) string {
return Substr(dir, 0, strings.LastIndex(dir, "/"))
}
func CheckRpcServer() error {
// err := genId.CheckGenIdHealth()
// if err != nil {
// glog.Error(err)
// return errors.New("请开启id grpc 服务")
// }
// err = password.CheckPwdHealth()
// if err != nil {
// glog.Error(err)
// return errors.New("请开启password grpc 服务")
// }
return nil
}
// 日期格式 转 时间戳格式
func DatetimeToInt(datetime string) int64 {
timeLayout := "2006-01-02 15:04:05" //转化所需模板
loc, _ := time.LoadLocation("Local") //获取时区
tmp, _ := time.ParseInLocation(timeLayout, datetime, loc)
return tmp.Unix() //转化为时间戳 类型是int64
}
// SliceDataValueToString 列表数据内容转字符串
func SliceDataValueToString(data interface{}, forceConvert ...string) (listData []map[string]interface{}) {
listData = gconv.SliceMap(data)
if len(listData) > 0 {
for index, value := range listData {
listData[index] = MapDataValueToString(value, forceConvert...)
}
}
return
}
func GetMapKeys(m map[string]interface{}) []string {
// 数组默认长度为map长度,后面append时,不需要重新申请内存和拷贝,效率较高
j := 0
keys := make([]string, len(m))
for k := range m {
keys[j] = k
j++
}
return keys
}
// MapDataValueToString map数据内容转字符串
func MapDataValueToString(data interface{}, forceConvert ...string) map[string]interface{} {
reData := gconv.Map(data)
if len(reData) > 0 {
for index, value := range reData {
kind := reflect.TypeOf(value).Kind()
mapKey := gconv.String(index)
index = gconv.String(index)
if kind == reflect.Slice || kind == reflect.Array {
reData[index] = SliceDataValueToString(value, forceConvert...)
} else if kind == reflect.Map {
reData[index] = MapDataValueToString(value, forceConvert...)
} else {
if len(forceConvert) > 0 {
for _, field := range forceConvert {
if mapKey == gconv.String(field) {
reData[mapKey] = gconv.String(value)
}
}
}
intV := gconv.Int(value)
if intV > math.MaxInt32 {
reData[mapKey] = gconv.String(value)
}
}
}
}
return reData
}
func TrimCdnUrl(url string) string {
cdnUrl := g.Cfg().GetString("qiniu.cdnUrl")
if strings.Contains(url, cdnUrl) {
return gstr.TrimLeftStr(url, cdnUrl)
}
return url
}
func FixUploadUrl(key string) string {
cdnUrl := g.Cfg().GetString("qiniu.cdnUrl")
if strings.Contains(key, ":/") {
return key
}
bg := strings.TrimPrefix(key, "/")
cdnUrl = strings.TrimSuffix(cdnUrl, "/")
url := fmt.Sprintf("%s/%s", cdnUrl, bg)
return url
}
// 指定年月份的开始和结束时间
func GetYearMonthStartEndUnix(y int, m int) (int, int) {
currentLocation := time.Now().Location()
firstOfMonth := time.Date(y, time.Month(m), 1, 0, 0, 0, 0, currentLocation)
start := gconv.Int(firstOfMonth.Unix())
lastOfMonth := firstOfMonth.AddDate(0, 1, -1)
end := gconv.Int(lastOfMonth.Unix() + 24*60*60 - 1)
return start, end
}
func TrimHtml(src string) string {
//将HTML标签全转换成小写
re, _ := regexp.Compile("\<[\S\s]+?\>")
src = re.ReplaceAllStringFunc(src, strings.ToLower)
//去除STYLE
re, _ = regexp.Compile("\<style[\S\s]+?\</style\>")
src = re.ReplaceAllString(src, "")
//去除SCRIPT
re, _ = regexp.Compile("\<script[\S\s]+?\</script\>")
src = re.ReplaceAllString(src, "")
//去除所有尖括号内的HTML代码,并换成换行符
re, _ = regexp.Compile("\<[\S\s]+?\>")
src = re.ReplaceAllString(src, "
")
//去除连续的换行符
re, _ = regexp.Compile("\s{2,}")
src = re.ReplaceAllString(src, "
")
return strings.TrimSpace(src)
}
//解析标注格式的list json
// str @example [{"sort":"1", "title":"", "image":"", "link":""}]
func ListJsonDecode(str string) ([]interface{}, error) {
buf := []byte(str)
var res []interface{}
err := json.Unmarshal(buf, &res)
if err != nil {
return res, err
}
return res, nil
}
//解析标注格式的map list json
// str @example ["a":{"sort":"1", "title":"", "image":"", "link":""},"b":{"sort":"1", "title":"", "image":"",
//"link":""}]
func MapsJsonDecode(str string) (map[string]interface{}, error) {
buf := []byte(str)
var res map[string]interface{}
err := json.Unmarshal(buf, &res)
if err != nil {
return res, err
}
return res, nil
}
func UrlEncode(url string) string {
return netURL.QueryEscape(url)
}
func GetDataFileType(fileUrl string) int {
dataFileType := g.Cfg().GetJsons("dataFileType")
fileExt := gfile.ExtName(fileUrl)
value := 0
for _, val := range dataFileType {
data := val.ToMap()
if len(data) == 0 {
continue
}
for _, v := range data {
arrVal := gconv.SliceMap(v)
innerData := arrVal[0]
if len(innerData) == 0 {
continue
}
extArr := gstr.SplitAndTrim(gconv.String(innerData["ext"]), "|", "|")
for _, e := range extArr {
if e == fileExt {
value = gconv.Int(innerData["value"])
break
}
}
if value > 0 {
break
}
}
if value > 0 {
break
}
}
return value
}
// 手机号中间4位替换为*号
func FormatMobileStar(mobile string) string {
if len(mobile) <= 10 {
return mobile
}
return mobile[:3] + "****" + mobile[6:]
}
func IsEmpty(value interface{}) bool {
if value == nil {
return true
}
switch value := value.(type) {
case int:
return value == 0
case int8:
return value == 0
case int16:
return value == 0
case int32:
return value == 0
case int64:
return value == 0
case uint:
return value == 0
case uint8:
return value == 0
case uint16:
return value == 0
case uint32:
return value == 0
case uint64:
return value == 0
case float32:
return value == 0
case float64:
return value == 0
case bool:
return !value
case string:
return value == ""
case []byte:
return len(value) == 0
default:
// Finally using reflect.
rv := reflect.ValueOf(value)
switch rv.Kind() {
case reflect.Chan,
reflect.Map,
reflect.Slice,
reflect.Array:
return rv.Len() == 0
case reflect.Func,
reflect.Ptr,
reflect.Interface,
reflect.UnsafePointer:
if rv.IsNil() {
return true
}
}
}
return false
}
//支持中文截取, 支持end 负数截取
func SubStr(source interface{}, start int, end int) string {
str := source.(string)
var r = []rune(str)
length := len(r)
subLen := end - start
for {
if start < 0 {
break
}
if start == 0 && subLen == length {
break
}
if end > length {
subLen = length - start
}
if end < 0 {
subLen = length - start + end
}
var substring bytes.Buffer
if end > 0 {
subLen = subLen + 1
}
for i := start; i < subLen; i++ {
substring.WriteString(string(r[i]))
}
str = substring.String()
break
}
return str
}
// 获取指定时间所在月的开始 结束时间
func GetMonthStartEnd(t time.Time) (time.Time, time.Time) {
monthStartDay := t.AddDate(0, 0, -t.Day()+1)
monthStartTime := time.Date(monthStartDay.Year(), monthStartDay.Month(), monthStartDay.Day(), 0, 0, 0, 0, t.Location())
monthEndDay := monthStartTime.AddDate(0, 1, -1)
monthEndTime := time.Date(monthEndDay.Year(), monthEndDay.Month(), monthEndDay.Day(), 23, 59, 59, 0, t.Location())
return monthStartTime, monthEndTime
}
//处理金额 分 转换元
func FormatAmount(amount uint64) string {
formatAmount := fmt.Sprintf("%.2f", gconv.Float64(amount)/100)
//formatAmount, _ := strconv.ParseFloat(tmp, 64)
return formatAmount
}
//处理金额 元 转分
func FormatAmountYuanToFen(amount string) uint64 {
//会有精度问题 改进
//formatAmount := gconv.Uint64(gconv.Float64(amount) * 100)
d := decimal.New(1, 2) //分转元乘以100
d1 := decimal.New(1, 0) //乘完之后,保留2为小数,需要这么一个中间参数
//df := decimal.NewFromFloat(price).Mul(d).DivRound(d1,2).String()
//df := decimal.NewFromFloat(price).Mul(d).IntPart()
//如下是满足,当乘以100后,仍然有小数位,取四舍五入法后,再取整数部分
dff := decimal.NewFromFloat(gconv.Float64(amount)).Mul(d).DivRound(d1, 0).IntPart()
return gconv.Uint64(dff)
}
// 获取指定时间月的开始时间
func GetFirstDateOfMonth(d time.Time) time.Time {
d = d.AddDate(0, 0, -d.Day()+1)
return GetDayZeroTime(d)
}
//获取传入的时间所在月份的结束时间
func GetLastDateOfMonth(d time.Time) time.Time {
lastTime := GetFirstDateOfMonth(d).AddDate(0, 1, -1)
return time.Date(lastTime.Year(), lastTime.Month(), lastTime.Day(), 23, 59, 59, 0, d.Location())
}
//获取某一天的0点时间
func GetDayZeroTime(d time.Time) time.Time {
return time.Date(d.Year(), d.Month(), d.Day(), 0, 0, 0, 0, d.Location())
}
//获取某一天的结束时间
func GetDayEndTime(d time.Time) time.Time {
return time.Date(d.Year(), d.Month(), d.Day(), 23, 59, 59, 0, d.Location())
}
// 获取指定日期前一天的开始时间
func GetYesterdayZeroTime(d time.Time) time.Time {
return time.Date(d.Year(), d.Month(), d.Day()-1, 0, 0, 0, 0, d.Location())
}
// 获取指定日期前一天的结束时间
func GetYesterdayEndTime(d time.Time) time.Time {
return time.Date(d.Year(), d.Month(), d.Day()-1, 23, 59, 59, 0, d.Location())
}
// 获取指定日期当年的开始结束时间
func GetCurrentYearTime(d time.Time) (time.Time, time.Time) {
currentLocation := time.Now().Location()
start := time.Date(d.Year(), 1, 1, 0, 0, 0, 0, currentLocation)
lastTime := start.AddDate(0, 12, -1)
end := time.Date(lastTime.Year(), lastTime.Month(), lastTime.Day(), 23, 59, 59, 0, currentLocation)
return start, end
}
// 获取指定时间的当周的开始结束时间
func GetWeekTime(d time.Time) (time.Time, time.Time) {
offset := int(time.Monday - d.Weekday())
if offset > 0 {
offset = -6
}
weekStart := time.Date(d.Year(), d.Month(), d.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, offset)
weekEndDay := weekStart.AddDate(0, 0, 6)
weekEnd := time.Date(weekEndDay.Year(), weekEndDay.Month(), weekEndDay.Day(), 23, 59, 59, 0, time.Local)
return weekStart, weekEnd
}
// 过滤编辑器传到后台的html
func EditorContentFilter(content string) (string, error) {
allowTags := []string{"h1", "p", "span", "em", "strong", "blockquote", "a", "table", "tbody", "tr", "td", "figure", "img"}
result, err := htmltags.Strip(content, allowTags, false)
if err != nil {
return "", err
}
return result.ToString(), nil
}
// 四舍五入
func Round(x float64) int {
return gconv.Int(math.Floor(x + 0/5))
}