master
sre 2 years ago
parent 127dc0d250
commit 12fe5fdece

@ -0,0 +1,13 @@
package common
type Weekday int
const (
Sunday Weekday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)

@ -0,0 +1,77 @@
package date
import (
"git.sre.ink/go/gtool/common"
"regexp"
"strings"
"time"
)
var weekStartDay = common.Sunday
type DateTime struct {
t time.Time
weekStartDay common.Weekday
}
const (
year = "2006"
month = "01"
day = "02"
hour = "15"
minute = "04"
second = "05"
complete = "2006-01-02 15:04:05"
stringToTimeOne = "2006-01-02 15:04:05"
stringToTimeTow = "2006-01-02"
)
func formatTimeToList(t time.Time) []int {
hour, min, sec := t.Clock()
year, month, day := t.Date()
return []int{t.Nanosecond(), sec, min, hour, day, int(month), year}
}
// time format string
func replace(s string) (string, bool) {
flag := false
if strings.Contains(s, "YYYY") {
s = strings.Replace(s, "YYYY", year, 1)
flag = true
}
if strings.Contains(s, "MM") {
s = strings.Replace(s, "MM", month, 1)
flag = true
}
if strings.Contains(s, "DD") {
s = strings.Replace(s, "DD", day, 1)
flag = true
}
if strings.Contains(s, "hh") {
s = strings.Replace(s, "hh", hour, 1)
flag = true
}
if strings.Contains(s, "mm") {
s = strings.Replace(s, "mm", minute, 1)
flag = true
}
if strings.Contains(s, "ss") {
s = strings.Replace(s, "ss", second, 1)
flag = true
}
return s, flag
}
var hasTimeRegexp = regexp.MustCompile(`(\s+|^\s*|T)\d{1,2}((:\d{1,2})*|((:\d{1,2}){2}\.(\d{3}|\d{6}|\d{9})))(\s*$|[Z+-])`) // match 15:04:05, 15:04:05.000, 15:04:05.000000 15, 2017-01-01 15:04, 2021-07-20T00:59:10Z, 2021-07-20T00:59:10+08:00, 2021-07-20T00:00:10-07:00 etc
var onlyTimeRegexp = regexp.MustCompile(`^\s*\d{1,2}((:\d{1,2})*|((:\d{1,2}){2}\.(\d{3}|\d{6}|\d{9})))\s*$`) // match 15:04:05, 15, 15:04:05.000, 15:04:05.000000, etc
// TimeFormats default time formats will be parsed as
var TimeFormats = []string{
"2006", "2006-1", "2006-1-2", "2006-1-2 15", "2006-1-2 15:4", "2006-1-2 15:4:5", "1-2",
"15:4:5", "15:4", "15",
"15:4:5 Jan 2, 2006 MST", "2006-01-02 15:04:05.999999999 -0700 MST", "2006-01-02T15:04:05Z0700", "2006-01-02T15:04:05Z07",
"2006.1.2", "2006.1.2 15:04:05", "2006.01.02", "2006.01.02 15:04:05", "2006.01.02 15:04:05.999999999",
"1/2/2006", "1/2/2006 15:4:5", "2006/01/02", "20060102", "2006/01/02 15:04:05",
time.ANSIC, time.UnixDate, time.RubyDate, time.RFC822, time.RFC822Z, time.RFC850,
time.RFC1123, time.RFC1123Z, time.RFC3339, time.RFC3339Nano,
time.Kitchen, time.Stamp, time.StampMilli, time.StampMicro, time.StampNano,
}

@ -0,0 +1,280 @@
package date
import (
"git.sre.ink/go/gtool/common"
"time"
)
// Time return time structure
func (dateTime *DateTime) Time() time.Time {
return dateTime.t
}
// Now get standard time
// If time Now is empty, the single-sign time is obtained, otherwise the set time
func (dateTime *DateTime) Now() *DateTime {
dateTime.t = time.Now()
return dateTime
}
// Format format time
func (dateTime *DateTime) Format(s ...string) string {
if dateTime.t.IsZero() {
dateTime.t = time.Now()
}
if len(s) > 0 {
replace, b := replace(s[0])
if !b {
return dateTime.t.Format(complete)
} else {
return dateTime.t.Format(replace)
}
}
return dateTime.t.Format(complete)
}
// SetTime set time
func (dateTime *DateTime) SetTime(t ...time.Time) *DateTime {
dateTime.t = time.Now()
if len(t) > 0 {
dateTime.t = t[0]
}
return dateTime
}
// OperationDay Add and subtract time by day
// Add when num is positive, subtract when negative
// This method is mostly used for user or customer validity period operation,
// which is convenient for time operation.
func (dateTime *DateTime) OperationDay(num int) *DateTime {
if dateTime.t.IsZero() {
dateTime.t = time.Now()
}
dateTime.t = dateTime.t.AddDate(0, 0, num)
return dateTime
}
// OperationMoon Add and subtract time by Moon
// Add when num is positive, subtract when negative
// This method is mostly used for user or customer validity period operation,
// which is convenient for time operation.
func (dateTime *DateTime) OperationMoon(num int) *DateTime {
if dateTime.t.IsZero() {
dateTime.t = time.Now()
}
dateTime.t = dateTime.t.AddDate(0, num, 0)
return dateTime
}
// OperationYears Add and subtract time by Years
// Add when num is positive, subtract when negative
// This method is mostly used for user or customer validity period operation,
// which is convenient for time operation.
func (dateTime *DateTime) OperationYears(num int) *DateTime {
if dateTime.t.IsZero() {
dateTime.t = time.Now()
}
dateTime.t = dateTime.t.AddDate(num, 0, 0)
return dateTime
}
// StartOfHour start of hour
func (dateTime *DateTime) StartOfHour() *DateTime {
if dateTime.t.IsZero() {
dateTime.t = time.Now()
}
y, m, d := dateTime.t.Date()
dateTime.t = time.Date(y, m, d, dateTime.t.Hour(), 0, 0, 0, dateTime.t.Location())
return dateTime
}
// StartTimeOfDay start time of day
// This method can get the start time of the day, which is year:month:day 00:00:00
func (dateTime *DateTime) StartTimeOfDay() *DateTime {
if dateTime.t.IsZero() {
dateTime.t = time.Now()
}
y, m, d := dateTime.t.Date()
dateTime.t = time.Date(y, m, d, 0, 0, 0, 0, dateTime.t.Location())
return dateTime
}
// StartOfMinute beginning of minute
func (dateTime *DateTime) StartOfMinute() *DateTime {
if dateTime.t.IsZero() {
dateTime.t = time.Now()
}
dateTime.t = dateTime.t.Truncate(time.Minute)
return dateTime
}
// StartOfWeek Weekly start time
func (dateTime *DateTime) StartOfWeek() *DateTime {
if dateTime.t.IsZero() {
dateTime.t = time.Now()
dateTime.weekStartDay = weekStartDay
}
t := dateTime.StartTimeOfDay()
weekday := int(t.Time().Weekday())
if dateTime.weekStartDay != common.Sunday {
weekStartDayInt := int(dateTime.weekStartDay)
if weekday < weekStartDayInt {
weekday = weekday + 7 - weekStartDayInt
} else {
weekday = weekday - weekStartDayInt
}
}
dateTime.t = t.t.AddDate(0, 0, -weekday)
return dateTime
}
// StartOfMonth beginning of month
// This method user gets the start time of each month
func (dateTime *DateTime) StartOfMonth() *DateTime {
if dateTime.t.IsZero() {
dateTime.t = time.Now()
}
y, m, _ := dateTime.t.Date()
dateTime.t = time.Date(y, m, 1, 0, 0, 0, 0, dateTime.t.Location())
return dateTime
}
// SetWeekStartDay Set the start time of the week, the default is Sunday. China generally uses a week to start on Monday
// Use this method to quickly set up The value range is 0-6, please use the enumeration preset by the system
func (dateTime *DateTime) SetWeekStartDay(weekday common.Weekday) *DateTime {
if dateTime.t.IsZero() {
dateTime.t = time.Now()
}
if weekday < 0 || weekday > 6 {
weekday = common.Sunday
}
dateTime.weekStartDay = weekday
return dateTime
}
// StartOfQuarter Start time of current quarter
func (dateTime *DateTime) StartOfQuarter() *DateTime {
month := dateTime.StartOfMonth()
offset := (int(month.t.Month()) - 1) % 3
dateTime.t = month.t.AddDate(0, -offset, 0)
return dateTime
}
// StartOfYear Start time of current year
func (dateTime *DateTime) StartOfYear() *DateTime {
if dateTime.t.IsZero() {
dateTime.t = time.Now()
}
y, _, _ := dateTime.t.Date()
dateTime.t = time.Date(y, time.January, 1, 0, 0, 0, 0, dateTime.t.Location())
return dateTime
}
// EndOfMinute end of minute
func (dateTime *DateTime) EndOfMinute() *DateTime {
dateTime.t = dateTime.StartOfMinute().t.Add(time.Minute - time.Nanosecond)
return dateTime
}
// EndOfHour end of hour
func (dateTime *DateTime) EndOfHour() *DateTime {
dateTime.t = dateTime.StartOfHour().t.Add(time.Hour - time.Nanosecond)
return dateTime
}
// EndOfDay end of day
func (dateTime *DateTime) EndOfDay() *DateTime {
if dateTime.t.IsZero() {
dateTime.t = time.Now()
}
y, m, d := dateTime.t.Date()
dateTime.t = time.Date(y, m, d, 23, 59, 59, int(time.Second-time.Nanosecond), dateTime.t.Location())
return dateTime
}
// EndOfWeek end of week
func (dateTime *DateTime) EndOfWeek() *DateTime {
dateTime.t = dateTime.StartOfWeek().t.AddDate(0, 0, 7).Add(-time.Nanosecond)
return dateTime
}
// EndOfMonth end of month
func (dateTime *DateTime) EndOfMonth() *DateTime {
dateTime.t = dateTime.StartOfMonth().t.AddDate(0, 1, 0).Add(-time.Nanosecond)
return dateTime
}
// EndOfQuarter end of quarter
func (dateTime *DateTime) EndOfQuarter() *DateTime {
dateTime.t = dateTime.StartOfQuarter().t.AddDate(0, 3, 0).Add(-time.Nanosecond)
return dateTime
}
// EndOfYear end of year
func (dateTime *DateTime) EndOfYear() *DateTime {
dateTime.t = dateTime.StartOfYear().t.AddDate(1, 0, 0).Add(-time.Nanosecond)
return dateTime
}
// Parse parse string to time
func (dateTime *DateTime) Parse(strFormat ...string) (*DateTime, error) {
var err error
if dateTime.t.IsZero() {
dateTime.t = time.Now()
}
var (
setCurrentTime bool
parseTime []int
currentLocation = dateTime.t.Location()
onlyTimeInStr = true
currentTime = formatTimeToList(dateTime.t)
)
for _, str := range strFormat {
hasTimeInStr := hasTimeRegexp.MatchString(str) // match 15:04:05, 15
onlyTimeInStr = hasTimeInStr && onlyTimeInStr && onlyTimeRegexp.MatchString(str)
if t, err := dateTime.parseWithFormat(str, currentLocation); err == nil {
location := t.Location()
parseTime = formatTimeToList(t)
for i, v := range parseTime {
// Don't reset hour, minute, second if current time str including time
if hasTimeInStr && i <= 3 {
continue
}
// If value is zero, replace it with current time
if v == 0 {
if setCurrentTime {
parseTime[i] = currentTime[i]
}
} else {
setCurrentTime = true
}
// if current time only includes time, should change day, month to current time
if onlyTimeInStr {
if i == 4 || i == 5 {
parseTime[i] = currentTime[i]
continue
}
}
}
t = time.Date(parseTime[6], time.Month(parseTime[5]), parseTime[4], parseTime[3],
parseTime[2], parseTime[1], parseTime[0], location)
currentTime = formatTimeToList(t)
dateTime.t = t
}
}
return dateTime, err
}
// MustParse must parse string to time or it will panic
func (dateTime *DateTime) MustParse(strs ...string) (d *DateTime) {
d, err := dateTime.Parse(strs...)
if err != nil {
panic(err)
}
return d
}

@ -0,0 +1,18 @@
package date
import (
"errors"
"time"
)
func (dateTime *DateTime) parseWithFormat(str string, location *time.Location) (t time.Time, err error) {
for _, format := range TimeFormats {
t, err = time.ParseInLocation(format, str, location)
if err == nil {
return
}
}
err = errors.New("Can't parse string as time: " + str)
return
}

@ -1 +0,0 @@
package datime

@ -1 +0,0 @@
package datime

@ -0,0 +1,4 @@
package id
type Id struct {
}

@ -0,0 +1,3 @@
package id
var id Id

File diff suppressed because it is too large Load Diff

@ -0,0 +1,4 @@
package regx
type Regx struct {
}

@ -0,0 +1,3 @@
package regx
var regx Regx

@ -0,0 +1,178 @@
package regx
import (
"encoding/json"
"errors"
"fmt"
"git.sre.ink/go/gtool/date"
"io/ioutil"
"regexp"
"strconv"
)
// Check Perform global verification
func (rr *Regx) IsIdCardCheck(id string) (bool, error) {
//digit check
flag, err := rr.IsValidIdCard(id)
if err != nil {
return flag, err
}
//Check the date
birth := id[6:14]
_, err = rr.CheckBirthdayCode(birth)
if err != nil {
return false, err
}
return true, nil
}
var area = make(map[string]string)
// initConfig locale configuration
func (rr *Regx) initConfig() {
c := "./area.json"
raw, err := ioutil.ReadFile(c)
err = json.Unmarshal(raw, &area)
if err != nil {
err = fmt.Errorf("Failed to parse basic configuration file%s\n", err.Error())
return
}
}
// GetProvinceByIdCard get province
func (rr *Regx) GetProvinceByIdCard(address string) string {
rr.initConfig()
address = address[:6]
provincialCode := address[:3] + "000"
cityCode := address[:4] + "00"
return area[provincialCode] + area[cityCode] + area[address]
}
// IsValidCard Verify that the ID is legal
func (rr *Regx) IsValidIdCard(id string) (bool, error) {
if len(id) != 15 && len(id) != 18 {
return false, errors.New("身份证长度不对")
}
return rr.CheckValidNo18(id)
}
// 18-digit ID verification code
func (rr *Regx) CheckValidNo18(id string) (bool, error) {
//string -> []byte
id18 := []byte(id)
nSum := 0
for i := 0; i < len(id18)-1; i++ {
n, _ := strconv.Atoi(string(id18[i]))
nSum += n * weight[i]
}
//mod gets 18-bit ID verification code
mod := nSum % 11
if validValue[mod] == id18[17] {
return true, nil
}
return false, errors.New("身份证不正确请进行核实")
}
// 校验身份证号格式
func (rr *Regx) IsIdCardFormat(identityCard string) bool {
switch len(identityCard) {
case 15:
// 15位身份证号码15位全是数字
result, _ := regexp.MatchString(`^(\d{15})$`, identityCard)
return result
case 18:
// 18位身份证前17位为数字第18位为校验位可能是数字或X
result, _ := regexp.MatchString(`^(\d{17})([0-9]|X|x)$`, identityCard)
return result
default:
//身份证位数应该为15位 与 18位
return false
}
return true
}
// GetAgeByIdCard Get age based on ID
func (rr *Regx) GetAgeByIdCard(id string) int {
d := new(date.DateTime)
now := d.Now().Time()
birth, _ := rr.GetBirthByIdCard(id)
startTime, err := d.Parse(birth)
if err != nil {
return 0
}
if startTime.Time().Before(now) {
diff := now.Unix() - startTime.Time().Unix()
Age := diff / (3600 * 365 * 24)
return int(Age)
}
return 0
}
// GetBirthByIdCard get birthday
func (rr *Regx) GetBirthByIdCard(id string) (string, error) {
birth := id[6:14]
_, err := rr.CheckBirthdayCode(birth)
if err != nil {
return "", err
}
return birth[:4] + "-" + birth[4:6] + "-" + birth[6:], nil
}
// GetYearByIdCard Year based on ID
func (rr *Regx) GetYearByIdCard(id string) string {
return id[6:14][:4]
}
// GetMonthByIdCard Get the month of your birthday based on your ID
func (rr *Regx) GetMonthByIdCard(id string) string {
return id[6:14][4:6]
}
// GetDayByIdCard Get birthday based on ID
func (rr *Regx) GetDayByIdCard(id string) string {
return id[6:14][6:]
}
// GetSex Get gender based on ID
// Description 0 Female 1 Male 3 unknown ID card gender identification error
func (rr *Regx) GetSex(id string) uint {
var unknown uint = 3
sexStr := id[16:17]
if sexStr == "" {
return unknown
}
i, err := strconv.Atoi(sexStr)
if err != nil {
return unknown
}
if i%2 != 0 {
return 1
}
return 0
}
// Convert15To18 15-digit ID card to 18-digit
// 15位身份证转为18位
var weight = [17]int{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}
var validValue = [11]byte{'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'}
func (rr *Regx) Convert15To18(id string) string {
nLen := len(id)
if nLen != 15 {
return "身份证不是15位"
}
id18 := make([]byte, 0)
id18 = append(id18, id[:6]...)
id18 = append(id18, '1', '9')
id18 = append(id18, id[6:]...)
sum := 0
for i, v := range id18 {
n, _ := strconv.Atoi(string(v))
sum += n * weight[i]
}
mod := sum % 11
id18 = append(id18, validValue[mod])
return string(id18)
}

@ -0,0 +1,41 @@
package regx
import (
"fmt"
"testing"
)
func TestRegx_IsIdCardFormat(t *testing.T) {
fmt.Println(regx.IsIdCardFormat("888388899880318888"))
}
func TestRegx_Convert15To18(t *testing.T) {
fmt.Println(regx.Convert15To18("111111111111111"))
//111111111111111
//111111191111111113
}
func TestRegx_GetSex(t *testing.T) {
fmt.Println(regx.GetSex("324054400330403410"))
//1
fmt.Println(regx.GetSex("324054400330403400"))
//0
fmt.Println(regx.GetYearByIdCard("324054400330403400"))
fmt.Println(regx.GetMonthByIdCard("324054400330403400"))
fmt.Println(regx.GetDayByIdCard("324054400330403400"))
}
func TestRegx_GetAge(t *testing.T) {
fmt.Println(regx.GetAgeByIdCard("324054202010233400"))
fmt.Println(regx.IsValidIdCard("324054202010233400"))
}
func TestRegx_GetProvinceByIdCard(t *testing.T) {
fmt.Println(regx.GetProvinceByIdCard("324054202010233400"))
fmt.Println(regx.GetProvinceByIdCard("422322202010233400"))
fmt.Println(regx.IsIdCardCheck("422322202010233400"))
}

@ -0,0 +1,24 @@
package regx
import (
"net"
"regexp"
)
func (rr *Regx) IsIp(address string) bool {
ip := net.ParseIP(address)
if ip != nil {
return true
}
return false
}
func (rr *Regx) IsIpRegx(address string) bool {
ipReg := `^((0|[1-9]\d?|1\d\d|2[0-4]\d|25[0-5])\.){3}(0|[1-9]\d?|1\d\d|2[0-4]\d|25[0-5])$`
r, _ := regexp.Compile(ipReg)
match := r.MatchString(address)
if match {
return true
}
return false
}

@ -0,0 +1,16 @@
package regx
import (
"fmt"
"testing"
)
func TestRegx_IsIp(t *testing.T) {
fmt.Println(regx.IsIp("114.114.114.114"))
fmt.Println(regx.IsIp("114.114.114.314"))
fmt.Println(regx.IsIp("www.baidu.com"))
fmt.Println(regx.IsIpRegx("114.114.114.114"))
fmt.Println(regx.IsIpRegx("114.114.114.314"))
fmt.Println(regx.IsIpRegx("www.baidu.com"))
}

@ -0,0 +1,10 @@
package regx
import "regexp"
// 校验邮件地址有效性
func (rr *Regx) IsMail(mail string) bool {
pattern := `^[0-9a-z][_.0-9a-z-]{0,31}@([0-9a-z][0-9a-z-]{0,30}[0-9a-z]\.){1,4}[a-z]{2,4}$`
reg := regexp.MustCompile(pattern)
return reg.MatchString(mail)
}

@ -0,0 +1,14 @@
package regx
import (
"fmt"
"testing"
)
func TestRegx_IsMail(t *testing.T) {
fmt.Println(regx.IsMail("www.baidu.com"))
fmt.Println(regx.IsMail("www@baiducom"))
fmt.Println(regx.IsMail("www@baidu.com"))
fmt.Println(regx.IsMail("www@baidu.com.cn"))
}

@ -0,0 +1,10 @@
package regx
import "regexp"
// 校验手机号有效性
func (rr *Regx) IsPhone(phone string) bool {
regular := "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$"
reg := regexp.MustCompile(regular)
return reg.MatchString(phone)
}

@ -0,0 +1,12 @@
package regx
import (
"fmt"
"testing"
)
func TestRegx_IsPhone(t *testing.T) {
fmt.Println(regx.IsPhone("18888888888"))
fmt.Println(regx.IsPhone("188888888888888"))
fmt.Println(regx.IsPhone("28888888888"))
}

@ -0,0 +1,51 @@
package regx
import (
"errors"
"strconv"
"time"
)
// Verify birthday
func (rr *Regx) CheckBirthdayCode(birthday string) (bool, error) {
year, _ := strconv.Atoi(birthday[:4])
month, _ := strconv.Atoi(birthday[4:6])
day, _ := strconv.Atoi(birthday[6:])
curYear, curMonth, curDay := time.Now().Date()
//Birth date greater than current date
if year < 1900 || year > curYear || month <= 0 || month > 12 || day <= 0 || day > 31 {
return false, errors.New("请检查生日部分的日期是否正确")
}
if year == curYear {
if month > int(curMonth) {
return false, errors.New("当前日期月份小于您身份证上的月份")
} else if month == int(curMonth) && day > curDay {
return false, errors.New("当前日期天数小于您身份证上的天数")
}
}
//出生日期在2月份
if 2 == month {
if rr.IsLeapYear(year) && day > 29 {
return false, errors.New("闰年2月只有29号")
} else if day > 28 {
return false, errors.New("非闰年2月只有28号")
}
} else if 4 == month || 6 == month || 9 == month || 11 == month {
if day > 30 {
return false, errors.New("小月只有30号")
}
}
return true, nil
}
// 判断是否为闰年
func (rr *Regx) IsLeapYear(year int) bool {
if year <= 0 {
return false
}
if (year%4 == 0 && year%100 != 0) || year%400 == 0 {
return true
}
return false
}

@ -0,0 +1,13 @@
package regx
import (
"fmt"
"testing"
)
func TestRegx_IsLeapYear(t *testing.T) {
fmt.Println(regx.IsLeapYear(2020))
fmt.Println(regx.CheckBirthdayCode("20200231"))
//false 闰年2月只有29号
}
Loading…
Cancel
Save