代码拉取完成,页面将自动刷新
package strUtil
import (
"fmt"
"reflect"
"strconv"
"strings"
"time"
)
// GetNowStr 根据指定的时间格式字符串(layout),返回当前时间的格式化字符串。
// 参数:
// - layout: 时间格式字符串,例如 "2006-01-02 15:04:05"。
//
// 返回值:
// - string: 当前时间的格式化字符串。
func GetNowStr(layout string) string {
currentTime := time.Now()
return currentTime.Format(layout)
}
// GetNowDayStr 返回当前日期的8位字符串,格式为 "20060102"。
func GetNowDayStr() string {
currentTime := time.Now()
return currentTime.Format("20060102")
}
// GetNowTimeStr 返回当前时间的6位字符串,格式为 "150405"。
func GetNowTimeStr() string {
currentTime := time.Now()
return currentTime.Format("150405")
}
// ChunkStringsOptimized 将字符串切片按指定大小分块。
// 参数:
// - slice: 待分块的字符串切片。
// - chunkSize: 每块的大小。
//
// 返回值:
// - [][]string: 分块后的二维字符串切片。
//
// 说明:
// - 函数会预计算分组数量以提高性能。
// - 分块逻辑确保所有元素均被包含,且每块大小不超过 chunkSize。
func ChunkStringsOptimized(slice []string, chunkSize int) [][]string {
// 预计算分组数量
chunkCount := (len(slice) + chunkSize - 1) / chunkSize
chunks := make([][]string, 0, chunkCount)
for i := 0; i < len(slice); i += chunkSize {
end := min(i+chunkSize, len(slice))
chunks = append(chunks, slice[i:end])
}
return chunks
}
// StrSliceToStruct 将字符串切片映射到目标结构体的字段中。
//
// 参数:
// - data: 字符串切片,包含需要映射到结构体的数据。
// - target: 目标结构体的指针,其字段将通过反射被填充。
//
// 返回值:
// - error: 如果映射过程中发生错误(如索引越界或不支持的类型),返回错误信息。
//
// 说明:
// - 结构体字段必须使用 `field` 标签指定字符串切片中的索引位置(从0开始)。
// - 支持的类型包括:string、int、float64 和 bool。
// - 如果字段的索引超出字符串切片的范围,会返回错误。
// - 如果字段类型不支持,会返回错误。
//
// 示例:
//
// type Example struct {
// Name string `field:"0"`
// Age int `field:"1"`
// }
// var ex Example
// err := StrSliceToStruct([]string{"Alice", "30"}, &ex)
// if err != nil {
// log.Fatal(err)
// }
func StrSliceToStruct(data []string, target any) error {
v := reflect.ValueOf(target).Elem()
t := v.Type()
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
indexStr := field.Tag.Get("field")
index, err := strconv.Atoi(indexStr)
if err != nil {
return fmt.Errorf("字段 %s 的 field 标签 '%s' 不是有效的整数", field.Name, indexStr)
}
if index < 0 {
return fmt.Errorf("字段 %s 的索引不能为负数", field.Name)
}
if index >= len(data) {
return fmt.Errorf("字段 %s 的索引 %d 超出数据范围(数据长度: %d)", field.Name, index, len(data))
}
fieldValue := v.Field(i)
strValue := data[index]
switch fieldValue.Kind() {
case reflect.String:
fieldValue.SetString(strValue)
case reflect.Int:
intValue, err := strconv.Atoi(strValue)
if err != nil {
return fmt.Errorf("字段 %s: 无法将值 '%s' 转换为 int: %w", field.Name, strValue, err)
}
fieldValue.SetInt(int64(intValue))
case reflect.Float64:
f64, err := strconv.ParseFloat(strValue, 32)
if err != nil {
return fmt.Errorf("字段 %s: 无法将值 '%s' 转换为 float64: %w", field.Name, strValue, err)
}
fieldValue.SetFloat(f64)
case reflect.Bool:
boolValue, err := strconv.ParseBool(strValue)
if err != nil {
return fmt.Errorf("字段 %s: 无法将值 '%s' 转换为 bool: %w", field.Name, strValue, err)
}
fieldValue.SetBool(boolValue)
default:
return fmt.Errorf("不支持的类型: %s", fieldValue.Kind())
}
}
return nil
}
// parseMap 将字符串数组解析为键值对映射。
// 参数:
// - entries: 包含键值对字符串的数组,格式为"key:value"。
//
// 返回值:
// - map[string]string: 解析后的键值对映射。
func ParseMap(entries []string) map[string]string {
m := make(map[string]string)
for _, entry := range entries {
// 跳过空字符串
if strings.TrimSpace(entry) == "" {
continue
}
parts := strings.SplitN(entry, ":", 2)
if len(parts) == 2 {
key := strings.TrimSpace(parts[0])
value := strings.TrimSpace(parts[1])
if key != "" { // 确保键不为空
m[key] = value
}
}
}
return m
}
// IsNumeric 检查字符串是否只包含数字字符
// 参数 s 是要检查的字符串
// 返回 true 如果字符串非空且只包含数字字符,否则返回 false
func IsNumeric(s string) bool {
if s == "" {
return false
}
for _, r := range s {
if r < '0' || r > '9' {
return false
}
}
return true
}
// CaesarCipher 实现凯撒密码加密/解密
//
// 只对字母字符(A-Z, a-z)进行转换,非字母字符保持不变。大小写字母分开处理,保持原有大小写
//
// 参数:
//
// text: 要加密/解密的字符串
// shift: 移动步长(可以为负数),负数偏移(向左移动),超出字母表范围时自动循环(Z + 1 = A,A - 1 = Z)
//
// 返回:
//
// 加密/解密后的字符串
func CaesarCipher(text string, shift int) string {
// 将 shift 规范化到 [0, 25] 范围,简化计算
shift = ((shift % 26) + 26) % 26
runes := []rune(text)
for i, char := range runes {
if 'a' <= char && char <= 'z' {
// 处理小写字母:归零后加上偏移,取模恢复到字母范围
newPos := (int(char-'a') + shift) % 26
runes[i] = 'a' + rune(newPos)
} else if 'A' <= char && char <= 'Z' {
// 处理大写字母
newPos := (int(char-'A') + shift) % 26
runes[i] = 'A' + rune(newPos)
}
}
return string(runes)
}
// IsValidDate 检查日期字符串是否有效,支持6位(YYYYMM)或8位(YYYYMMDD)格式
// 如果是6位格式,会自动补全为8位格式(YYYYMM01)进行验证
func IsValidDate(dateStr string) bool {
if len(dateStr) == 6 {
dateStr = fmt.Sprintf("%s01", dateStr)
}
return isValidDate8(dateStr)
}
func isValidDate8(dateStr string) bool {
if _, err := time.Parse("20060102", dateStr); err != nil {
return false
}
return true
}
// IsValidDate6 检查6位日期字符串(格式为YYYYMM)是否有效
func IsValidDate6(dateStr string) bool {
return isValidDate8(dateStr + "01")
}
// SplitDateStr 将格式为YYMMDD或YYYYMMDD的日期字符串拆分为年、月、日三个整数值
// 参数dateStr: 需要解析的日期字符串
// 返回值: 年、月、日三个整数值,以及可能的错误信息
// 错误: 当日期格式无效或解析失败时返回错误
func SplitDateStr(dateStr string) (int, int, int, error) {
if !IsValidDate(dateStr) {
return 0, 0, 0, fmt.Errorf("错误:日期格式不正确,格式应为YYYYMMDD 或 YYMMDD")
}
if len(dateStr) < 6 {
return 0, 0, 0, fmt.Errorf("错误:日期字符串长度不足")
}
year, err := strconv.Atoi(dateStr[:4])
if err != nil {
return 0, 0, 0, fmt.Errorf("错误:无法解析年份 '%s': %v", dateStr[:4], err)
}
month, err := strconv.Atoi(dateStr[4:6])
if err != nil {
return 0, 0, 0, fmt.Errorf("错误:无法解析月份 '%s': %v", dateStr[4:6], err)
}
if len(dateStr) < 8 {
return year, month, 0, nil
}
day, err := strconv.Atoi(dateStr[6:8])
if err != nil {
return 0, 0, 0, fmt.Errorf("错误:无法解析日期 '%s': %v", dateStr[6:8], err)
}
return year, month, day, nil
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。