This commit is contained in:
2025-07-07 20:11:59 +08:00
parent ab0fdbc447
commit 06e3aa2eb3
2009 changed files with 193082 additions and 0 deletions

0
utility/.gitkeep Normal file
View File

View File

@ -0,0 +1,128 @@
// Package timeutil
// @Author 铁憨憨[cory] 2025/6/11 20:08:00
package timeutil
import (
"github.com/paulmach/orb"
"github.com/paulmach/orb/geo"
"github.com/paulmach/orb/planar"
"github.com/tiger1103/gfast/v3/api/v1/common/shp"
"math"
)
// 将 Polygon 结构体转换为 [][]float64 格式
func ConvertPolygonToFloatArray(polygon shp.Polygon) [][]float64 {
// 创建结果切片,长度与 Polygon 中的 Positions 相同
result := make([][]float64, len(polygon.Positions))
// 遍历每个 Point 并转换为 []float64
for i, point := range polygon.Positions {
// 每个点转换为 [经度, 纬度, 高度, 宽度]
result[i] = []float64{
point.Lng,
point.Lat,
point.Alt,
point.Width,
}
}
return result
}
// 判断点是否在多边形内
func FanWei(mian [][]float64, dian []float64) bool {
if len(mian) < 3 || len(dian) != 2 {
return false
}
var ring orb.Ring
for _, vertex := range mian {
ring = append(ring, orb.Point{vertex[0], vertex[1]})
}
// 闭合环
if !ring[0].Equal(ring[len(ring)-1]) {
ring = append(ring, ring[0])
}
polygon := orb.Polygon{ring}
point := orb.Point{dian[0], dian[1]}
return planar.PolygonContains(polygon, point)
}
// 点到线段最近点(投影点)
func closestPointOnSegment(p, a, b orb.Point) orb.Point {
ax, ay := a[0], a[1]
bx, by := b[0], b[1]
px, py := p[0], p[1]
abx := bx - ax
aby := by - ay
apx := px - ax
apy := py - ay
t := (apx*abx + apy*aby) / (abx*abx + aby*aby)
if t < 0 {
t = 0
} else if t > 1 {
t = 1
}
return orb.Point{ax + t*abx, ay + t*aby}
}
// 点到多边形的最近距离(米)
func PointToPolygonDistance(mian [][]float64, dian []float64) float64 {
point := orb.Point{dian[0], dian[1]}
ring := make(orb.Ring, len(mian))
for i, pt := range mian {
ring[i] = orb.Point{pt[0], pt[1]}
}
// 闭合多边形
if !ring[0].Equal(ring[len(ring)-1]) {
ring = append(ring, ring[0])
}
polygon := orb.Polygon{ring}
if planar.PolygonContains(polygon, point) {
return 0
}
minDist := math.MaxFloat64
for i := 0; i < len(ring)-1; i++ {
proj := closestPointOnSegment(point, ring[i], ring[i+1])
dist := geo.Distance(point, proj) // 单位:米
if dist < minDist {
minDist = dist
}
}
return minDist
}
// 计算两个经纬度点之间的球面距离(单位:米)
func PointToPointDistance(p1 []float64, p2 []float64) float64 {
point1 := orb.Point{p1[0], p1[1]}
point2 := orb.Point{p2[0], p2[1]}
return geo.Distance(point1, point2)
}
//func main() {
// polygonVertices := [][]float64{
// {106.518314, 29.627223},
// {106.519419, 29.627223},
// {106.518238, 29.626399},
// {106.519491, 29.626435},
// }
//
// targetPoint := []float64{117.51, 40.74}
//
// inPolygon := FanWei(polygonVertices, targetPoint)
// fmt.Printf("点是否在多边形内:%v\n", inPolygon)
//
// distance := pointToPolygonDistance(polygonVertices, targetPoint)
// fmt.Printf("点到多边形的最短距离(单位米):%.2f m\n", distance)
//}

View File

@ -0,0 +1,415 @@
package timeutil
import (
"fmt"
"strconv"
"time"
)
func New() *TimeUtil {
return &TimeUtil{}
}
// TimeUtil 是时间操作工具类
type TimeUtil struct{}
// GetFormattedDate 获取格式化的日期字符串
func (tu *TimeUtil) GetFormattedDate(t time.Time) string {
return t.Format("2006-01-02")
}
// GetFormattedTime 获取格式化的时间字符串
func (tu *TimeUtil) GetFormattedTime(t time.Time) string {
return t.Format("15:04:05")
}
// GetFormattedDateTime 获取格式化的日期时间字符串
func (tu *TimeUtil) GetFormattedDateTime(t time.Time) string {
return t.Format("2006-01-02 15:04:05")
}
// GetWeekday 获取星期几
func (tu *TimeUtil) GetWeekday(t time.Time) string {
return t.Weekday().String()
}
// IsLeapYear 判断是否为闰年
func (tu *TimeUtil) IsLeapYear(year int) bool {
return year%4 == 0 && (year%100 != 0 || year%400 == 0)
}
// ParseDateFromString 将日期字符串解析为时间对象
func (tu *TimeUtil) ParseDateFromString(dateString string) (time.Time, error) {
layout := "2006-01-02"
t, err := time.Parse(layout, dateString)
if err != nil {
return time.Time{}, err
}
return t, nil
}
// ParseTimeFromString 将时间字符串解析为时间对象
func (tu *TimeUtil) ParseTimeFromString(timeString string) (time.Time, error) {
layout := "15:04:05"
t, err := time.Parse(layout, timeString)
if err != nil {
return time.Time{}, err
}
return t, nil
}
// ParseDateTimeFromString 将日期时间字符串解析为时间对象
func (tu *TimeUtil) ParseDateTimeFromString(dateTimeString string) (time.Time, error) {
layout := "2006-01-02 15:04:05"
t, err := time.Parse(layout, dateTimeString)
if err != nil {
return time.Time{}, err
}
return t, nil
}
// NowTime 获取当前时间 format 表示要转换的日期时间格式 1、YYYY-MM-DD hh:mm:ss 2、YYYY-MM-DD 3、hh:mm:ss
func (tu *TimeUtil) NowTime(format string) (timeDate time.Time) {
// 获取当前时间
currentTime := time.Now()
// 使用时间格式化函数,将时间转换为指定格式的字符串
formattedTime := currentTime.Format(rule(format))
// 输出格式化后的时间字符串
fmt.Println(formattedTime)
// 如果你需要将时间转换为 time.Time 类型,直接使用 currentTime 即可
// 这里的 currentTime 就是 time.Time 类型的对象
fmt.Println(currentTime)
return currentTime
}
// FormatTimeString 将时间字符串转换为指定格式的日期时间字符串
/**
inputTime 表示输入的时间字符串 字符格式为2006-01-02 15:04:05
format 表示要转换的日期时间格式 1、YYYY-MM-DD hh:mm:ss 2、YYYY-MM-DD 3、hh:mm:ss
*/
func (tu *TimeUtil) FormatTimeString(inputTime, format string) (string, error) {
format = rule(format)
layout := "2006-01-02 15:04:05"
t, err := time.Parse(layout, inputTime)
if err != nil {
return "", err
}
formattedTime := t.Format(format)
return formattedTime, nil
}
// FormatTimeStringZ 将时间字符串转换为指定格式的日期时间字符串
/**
inputTime 表示输入的时间字符串 字符格式为2023-07-29T15:30:00Z
format 表示要转换的日期时间格式 1、YYYY-MM-DD hh:mm:ss 2、YYYY-MM-DD 3、hh:mm:ss
*/
func (tu *TimeUtil) FormatTimeStringZ(inputTime, format string) (string, error) {
format = rule(format)
t, err := time.Parse(time.RFC3339, inputTime)
if err != nil {
return "", err
}
formattedTime := t.Format(format)
return formattedTime, nil
}
// CalculateAge 计算年龄 传递参数格式为20060406
func (tu *TimeUtil) CalculateAge(timeStr string) string {
if len(timeStr) > 0 {
// 定义时间字符串和时间格式
timeFormat := "2006-01-02"
// 将时间字符串解析为时间对象
birthDate, err := time.Parse(timeFormat, timeStr)
if err != nil {
fmt.Println("无法解析时间字符串:", err)
}
//当前时间
currentDate := time.Now()
// 计算年份差值
years := currentDate.Year() - birthDate.Year()
// 检查月份和日期,如果当前日期还没过生日,则年龄减一
if currentDate.Month() < birthDate.Month() ||
(currentDate.Month() == birthDate.Month() && currentDate.Day() < birthDate.Day()) {
years -= 1
}
return strconv.Itoa(years)
}
return ""
}
func StringDateComparison(comparisonTime, scopeA, scopeB string) (flag bool) {
// 将日期字符串解析为时间对象
startTime, err := time.Parse("2006-01-02", scopeA)
if err != nil {
fmt.Println("解析开始日期时出错:", err)
return
}
endTime, err := time.Parse("2006-01-02", scopeB)
if err != nil {
fmt.Println("解析结束日期时出错:", err)
return
}
// 要检查的日期
checkTime, err := time.Parse("2006-01-02", comparisonTime)
if err != nil {
fmt.Println("解析要检查的日期时出错:", err)
return
}
// 检查a是否在start和end之间
if checkTime.After(startTime) && checkTime.Before(endTime) || checkTime.Equal(startTime) || checkTime.Equal(endTime) {
return true
} else {
return false
}
}
// TimeWithin 判断一个时间字符串是否在on和off之间注意on和off规则为时分【09:00】 返回值1为在范围内 返回值2为不在范围内
/**
strTime 需要判断的时间
on 范围起始时间
off 范围结束时间
*/
func (tu *TimeUtil) TimeWithin(strTime string, on string, off string, clockStatus string) string {
format := "2006-01-02 15:04:05"
now := time.Now()
year, month, day := now.Date()
// 构建完整的日期时间字符串
onTimeStr := ""
if clockStatus == "1" {
onTimeStr = fmt.Sprintf("%d-%02d-%02d %s:00", year, month, day, on)
} else {
onTimeStr = fmt.Sprintf("%d-%02d-%02d %s:00", year, month, day, off)
}
// 解析时间字符串为时间对象
onTime, err := time.Parse(format, onTimeStr)
if err != nil {
// 错误处理
}
strDateTime, err := time.Parse(format, strTime)
if err != nil {
// 错误处理
}
// 判断strTime与onTime、offTime的关系
/**
定义了
var on = “09:00”
var off = “18:00”
判断strTime“2023-06-07 17:44:49”
on和off自动填补上年月日比如说on为09:00,自动补充为2023-06-07 09:00:00然后与2023-06-07 17:44:49比较
strTime小于等于on大于等于off返回1
strTime大于on返回2
strTime小于off为3
*/
if clockStatus == "1" { //上班
if strDateTime.Before(onTime) || strDateTime.Equal(onTime) {
return "1" //表示正常
} else {
if clockStatus == "1" {
return "2" //表述迟到
} else {
//表示offTime小于等于strDateTime
return "1" //表示正常
}
}
} else { //下班
if strDateTime.After(onTime) || strDateTime.Equal(onTime) {
return "1" //表示正常
} else {
if clockStatus == "2" {
return "3" //表述早退
} else {
//表示offTime小于等于strDateTime
return "1" //表示正常
}
}
}
}
// TimeCycle 将字符串20060102转成2006-01-02
func (tu *TimeUtil) TimeCycle(dateStr string) (str string, err error) {
date, err := time.Parse("20060102", dateStr)
if err != nil {
fmt.Println("解析时间失败:", err)
return
}
formattedDate := date.Format("2006-01-02")
return formattedDate, err
}
// rule 时间规则
func rule(format string) (str string) {
if format == "1" {
format = "2006-01-02 15:04:05"
} else if format == "2" {
format = "2006-01-02"
} else if format == "3" {
format = "15:04:05"
}
return format
}
// GetDaysDifference 根据字符串时间2023-08-09 减去当前时间 得到 差异天数
func GetDaysDifference(strDate string) int {
layout := "2006-01-02" // 指定日期字符串的格式
t, err := time.Parse(layout, strDate)
if err != nil {
fmt.Println("日期解析错误:", err)
return -1
}
now := time.Now()
duration := now.Sub(t)
days := int(duration.Hours() / 24)
return days
}
// RangeTime 根据时间段获取到时间段内的所有时间 2023-10-01 17:26:56 ~ 2023-10-07 17:26:56里的所有时间年-月-日)
func RangeTime(startDateStr, endDateStr string) (qp []string) {
if startDateStr == "" || endDateStr == "" {
return
}
// 解析起始日期和结束日期
startDate, err := time.Parse("2006-01", startDateStr)
if err != nil {
fmt.Printf("无法解析起始日期:%s\n", err)
return
}
endDate, err := time.Parse("2006-01", endDateStr)
if err != nil {
fmt.Printf("无法解析结束日期:%s\n", err)
return
}
// 生成日期范围并输出
currentDate := startDate
for !currentDate.After(endDate) {
format := currentDate.Format("2006-01")
qp = append(qp, format)
currentDate = currentDate.AddDate(0, 1, 0)
}
return qp
}
// TimeStr 根据时间字符串 09:00 转成 2023-10-17 09:00:00 然后 再减去10分钟 在转成 time.Duration
func TimeStr(timeString string) (dn time.Duration, err error) {
currentTime := time.Now()
newTimeString := fmt.Sprintf("%s %s", currentTime.Format("2006-01-02"), timeString)
parsedTime, err := time.Parse("2006-01-02 15:04", newTimeString)
if err != nil {
fmt.Println("时间解析错误:", err)
return
}
//duration := 10 * time.Minute
//newTime := parsedTime.Add(-duration)
thisTime := currentTime.Format("2006-01-02 15:04:05")
t, err := time.Parse("2006-01-02 15:04:05", thisTime)
// 计算持续时间
//dn = newTime.Sub(t)
dn = parsedTime.Sub(t)
return
}
func MillisecondTimestamp() int64 {
// 获取当前时间
currentTime := time.Now()
// 将时间转换为毫秒时间戳
milliseconds := currentTime.UnixNano() / int64(time.Millisecond)
return milliseconds
}
// TheBeginningAndTheEndOfTheMonth 获取当月的月初月末
func TheBeginningAndTheEndOfTheMonth() (string, string) {
currentTime := time.Now()
firstDay := time.Date(currentTime.Year(), currentTime.Month(), 1, 0, 0, 0, 0, currentTime.Location())
lastDay := firstDay.AddDate(0, 1, 0).Add(-time.Second)
statr := firstDay.Format("2006-01-02")
end := lastDay.Format("2006-01-02")
return statr, end
}
// TheBeginningAndTheEndOfTheMonthAssign 获取指定月的月初月末
func TheBeginningAndTheEndOfTheMonthAssign(selectedTime string) (string, string) {
// 将指定时间解析为 time.Time 对象
selectedTimeObj, err := time.Parse("2006-01", selectedTime)
if err != nil {
// 处理解析错误
fmt.Println(err)
return "", ""
}
// 获取当月的月初和月末
firstDay := time.Date(selectedTimeObj.Year(), selectedTimeObj.Month(), 1, 0, 0, 0, 0, selectedTimeObj.Location())
lastDay := firstDay.AddDate(0, 1, 0).Add(-time.Second)
// 格式化开始日期和结束日期为字符串
start := firstDay.Format("2006-01-02")
end := lastDay.Format("2006-01-02")
return start, end
}
// CalculateTheDifferenceBetweenTheTwoTimePoints 计算两个字符串时间相差多少分钟
func CalculateTheDifferenceBetweenTheTwoTimePoints(currentDateTime, targetTime string) float64 {
// 计算时间差(以分钟为单位)
diff := DateTimeSub(currentDateTime, targetTime).Minutes()
return diff
}
// CalculatesTheTimeDifferenceBetweenTwoStringsInHours 计算两个字符串时间相差多少小时
func CalculatesTheTimeDifferenceBetweenTwoStringsInHours(currentDateTime, targetTime string) float64 {
if currentDateTime == "00:00:00" || targetTime == "00:00:00" {
return 0
}
// 计算时间差(以小时为单位)
currentDateTime, _ = TimeToDateTimeFunc(currentDateTime)
targetTime, _ = TimeToDateTimeFunc(targetTime)
diff := DateTimeSub(currentDateTime, targetTime).Hours()
return diff
}
func DateTimeSub(currentDateTime, targetTime string) time.Duration {
// 解析当前日期时间字符串
t1, err := time.Parse("2006-01-02 15:04:05", currentDateTime)
if err != nil {
return 0
}
// 解析目标时间字符串
t2, err := time.Parse("2006-01-02 15:04:05", targetTime)
if err != nil {
return 0
}
diff := t2.Sub(t1)
return diff
}
// TimeToDateTimeFunc 时间转成年月日时分秒格式
func TimeToDateTimeFunc(timeStr string) (formattedTime string, err error) {
// 当前日期
currentDate := time.Now().Format("2006-01-02")
// 将时间字符串添加到当前日期的字符串中
fullTimeStr := currentDate + " " + timeStr
// 解析完整的时间字符串
parsedTime, err := time.Parse("2006-01-02 15:04:05", fullTimeStr)
if err != nil {
fmt.Println("解析时间时出错:", err)
return
}
// 将解析后的时间格式化为“2006-01-02 15:04:05”
formattedTime = parsedTime.Format("2006-01-02 15:04:05")
return
}

3
utility/dxfUtils.go Normal file
View File

@ -0,0 +1,3 @@
// Package utility
// @Author 铁憨憨[cory] 2025/6/11 20:07:00
package utility