字符串相关工具

master
sre 2 years ago
parent 06729e6f6f
commit 0b96bc2e3b

@ -0,0 +1,82 @@
package date
import (
"errors"
"fmt"
"time"
)
// Format 根据特定格式格式化日期
func (td *DateTime) Format(date time.Time, format string) (string, error) {
if _, ok := formatMap[format]; !ok {
return "", errors.New("unsupported format")
}
return date.Format(formatMap[format]), nil
}
// Parse 将日期字符串转换为Time
func (td *DateTime) Parse(dateStr, format string) (time.Time, error) {
if _, ok := formatMap[format]; !ok {
return time.Time{}, errors.New("unsupported format")
}
return time.Parse(formatMap[format], dateStr)
}
// Offset 时间偏移
func (td *DateTime) Offset(date time.Time, format string) (time.Time, error) {
pd, err := time.ParseDuration(format)
if err != nil {
return date, err
}
return date.Add(pd), nil
}
// OffsetDay 时间日期偏移
func (td *DateTime) OffsetDay(date time.Time, day int) (time.Time, error) {
return td.Offset(date, fmt.Sprintf("%dh", day*24))
}
// OffsetHour 按小时偏移
func (td *DateTime) OffsetHour(date time.Time, hour int) (time.Time, error) {
return td.Offset(date, fmt.Sprintf("%dh", hour))
}
// OffsetMinute 按分钟偏移
func (td *DateTime) OffsetMinute(date time.Time, minute int) (time.Time, error) {
return td.Offset(date, fmt.Sprintf("%dm", minute))
}
// OffsetSecond 按秒偏移
func (td *DateTime) OffsetSecond(date time.Time, second int) (time.Time, error) {
return td.Offset(date, fmt.Sprintf("%ds", second))
}
// OffsetMillisecond 按毫秒偏移
func (td *DateTime) OffsetMillisecond(date time.Time, ms int) (time.Time, error) {
return td.Offset(date, fmt.Sprintf("%dms", ms))
}
// SubDays 日期差
func (td *DateTime) SubDays(date1, date2 time.Time) int {
return int(date1.Sub(date2).Hours() / 24)
}
// SubHours 小时差
func (td *DateTime) SubHours(date1, date2 time.Time) int {
return int(date1.Sub(date2).Hours())
}
// SubMinutes 分钟差
func (td *DateTime) SubMinutes(date1, date2 time.Time) int {
return int(date1.Sub(date2).Minutes())
}
// SubSeconds 秒差
func (td *DateTime) SubSeconds(date1, date2 time.Time) int {
return int(date1.Sub(date2).Seconds())
}
// SubMilliseconds 毫秒差
func (td *DateTime) SubMilliseconds(date1, date2 time.Time) int {
return int(date1.Sub(date2).Milliseconds())
}

@ -0,0 +1,48 @@
package date
import (
"fmt"
"testing"
"time"
)
// Format 根据特定格式格式化日期
func TestFormat(t *testing.T) {
tm, err := dateTime.Format(time.Now(), "yyyy-MM-dd")
if err != nil {
t.Errorf("format failed, %s", err.Error())
return
}
fmt.Println(tm)
}
// Parse 将日期字符串转换为Time
func TestParse(t *testing.T) {
tm, err := dateTime.Parse("2006-01-02", "yyyy-MM-dd")
if err != nil {
t.Errorf("parse failed, %s", err.Error())
return
}
fmt.Println(tm)
}
// Offset 时间偏移
func TestOffset(t *testing.T) {
tm, err := dateTime.Offset(time.Now(), "-24h")
if err != nil {
t.Errorf("offset day failed, %s", err.Error())
return
}
fmt.Println(tm)
}
// SubDays 日期差
func TestSubDays(t *testing.T) {
tm, _ := dateTime.Offset(time.Now(), "-24h")
n := dateTime.SubDays(time.Now(), tm)
if n != 0 {
t.Error("value must be 0")
return
}
fmt.Println(n)
}

@ -7,6 +7,23 @@ import (
"time"
)
// 格式化支持的类型
var formatMap = map[string]string{
"yyyy/MM/dd HH:mm:ss": "2006/01/02 15:04:05",
"yyyy.MM.dd HH:mm:ss": "2006.01.02 15:04:05",
"yyyy年MM月dd日 HH时mm分ss秒": "2006年01月02 15时04分05秒",
"yyyy-MM-dd": "2006-01-02",
"yyyy/MM/dd": "2006/01/02",
"yyyy.MM.dd": "2006.01.02",
"HH:mm:ss": "15:04:05",
"HH时mm分ss秒": "15时04分05秒",
"yyyy-MM-dd HH:mm": "2006-01-02 15:04",
"yyyy-MM-dd HH:mm:ss.SSS": "2006-01-02 15:04:05.999",
"yyyyMMddHHmmss": "20060102150405",
"yyyyMMddHHmmssSSS": "20060102150405999",
"yyyyMMdd": "20060102",
}
var weekStartDay = common.Sunday
type DateTime struct {

@ -0,0 +1,3 @@
package date
var dateTime DateTime

@ -18,7 +18,7 @@ func (dateTime *DateTime) Now() *DateTime {
}
// Format format time
func (dateTime *DateTime) Format(s ...string) string {
func (dateTime *DateTime) Format1(s ...string) string {
if dateTime.t.IsZero() {
dateTime.t = time.Now()
}
@ -217,7 +217,7 @@ func (dateTime *DateTime) EndOfYear() *DateTime {
}
// Parse parse string to time
func (dateTime *DateTime) Parse(strFormat ...string) (*DateTime, error) {
func (dateTime *DateTime) Parse2(strFormat ...string) (*DateTime, error) {
var err error
if dateTime.t.IsZero() {
dateTime.t = time.Now()
@ -272,7 +272,7 @@ func (dateTime *DateTime) Parse(strFormat ...string) (*DateTime, error) {
// MustParse must parse string to time or it will panic
func (dateTime *DateTime) MustParse(strs ...string) (d *DateTime) {
d, err := dateTime.Parse(strs...)
d, err := dateTime.Parse2(strs...)
if err != nil {
panic(err)
}

@ -1,8 +1,11 @@
package operaSystem
import (
"bufio"
"encoding/base64"
"os"
"path/filepath"
"strings"
"time"
)
@ -76,3 +79,40 @@ func (fl *OperaSystem) IsDir(filePath string) bool {
}
return false
}
// Exist 判断文件是否存在
func (tf *OperaSystem) FileExist(path string) bool {
_, err := os.Lstat(path)
return !os.IsNotExist(err)
}
// RemoveSuffix 删除文件后缀
func (tf *OperaSystem) RemoveSuffix(path string) string {
suffix := filepath.Ext(path)
if suffix != "" {
return strings.Replace(path, suffix, "", -1)
}
return ""
}
// RemovePrefix 删除文件前缀
func (tf *OperaSystem) RemovePrefix(path string) string {
prefix := filepath.Ext(path)
if prefix != "" {
return prefix[1:]
}
return ""
}
// FileAppendString 将String写入文件追加模式
func (tf *OperaSystem) FileAppendString(content string, path string) (*os.File, error) {
file, err := os.OpenFile(path, os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
return nil, err
}
defer file.Close()
write := bufio.NewWriter(file)
write.WriteString(content)
write.Flush()
return file, nil
}

@ -39,3 +39,29 @@ func TestOperaSystem_IsDir(t *testing.T) {
isDir := operaSystem.IsDir(filePath)
fmt.Println(isDir)
}
// Exist 判断文件是否存在
func TestOperaSystem_FileExist(t *testing.T) {
filePath := "./file.go"
isExist := operaSystem.FileExist(filePath)
fmt.Println(isExist)
}
func TestOperaSystem_RemovePrefix(t *testing.T) {
filePath := "./file.go"
filePath = operaSystem.RemovePrefix(filePath)
fmt.Println(filePath)
}
func TestOperaSystem_RemoveSuffix(t *testing.T) {
filePath := "./file.go"
filePath = operaSystem.RemoveSuffix(filePath)
fmt.Println(filePath)
}
func TestOperaSystem_FileAppendString(t *testing.T) {
filePath := "./file_test.go"
operaSystem.FileAppendString("//将String写入文件 追加模式\n", filePath)
fmt.Println(filePath)
}
//将String写入文件 追加模式
//将String写入文件 追加模式

@ -0,0 +1,104 @@
package operaSystem
import (
"archive/zip"
"io"
"os"
"path"
"path/filepath"
"strings"
)
// Zip 压缩文件
func (fl *OperaSystem) Zip(dest string, paths ...string) error {
zfile, err := os.Create(dest)
if err != nil {
return err
}
defer zfile.Close()
zipWriter := zip.NewWriter(zfile)
defer zipWriter.Close()
for _, src := range paths {
// remove the trailing path sepeartor if it is a directory
src := strings.TrimSuffix(src, string(os.PathSeparator))
err = filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
// create local file header
header, err := zip.FileInfoHeader(info)
if err != nil {
return err
}
// set compression method to deflate
header.Method = zip.Deflate
// set relative path of file in zip archive
header.Name, err = filepath.Rel(filepath.Dir(src), path)
if err != nil {
return err
}
if info.IsDir() {
header.Name += string(os.PathSeparator)
}
// create writer for writing header
headerWriter, err := zipWriter.CreateHeader(header)
if err != nil {
return err
}
if info.IsDir() {
return nil
}
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()
_, err = io.Copy(headerWriter, f)
return err
})
if err != nil {
return err
}
}
return nil
}
// Unzip 解压文件
func (fl *OperaSystem) Unzip(src string, dest string) error {
reader, err := zip.OpenReader(src)
if err != nil {
return err
}
defer reader.Close()
for _, file := range reader.File {
filePath := path.Join(dest, file.Name)
if file.FileInfo().IsDir() {
os.MkdirAll(filePath, os.ModePerm)
} else {
if err = os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil {
return err
}
inFile, err := file.Open()
if err != nil {
return err
}
defer inFile.Close()
outFile, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode())
if err != nil {
return err
}
defer outFile.Close()
_, err = io.Copy(outFile, inFile)
if err != nil {
return err
}
}
}
return nil
}

@ -0,0 +1,16 @@
package operaSystem
import "testing"
func TestOperaSystem_Zip(t *testing.T) {
err := operaSystem.Zip("test.zip", "zip.go")
if err != nil {
t.Error(err)
}
}
func TestOperaSystem_Unzip(t *testing.T) {
err := operaSystem.Unzip("test.zip", "test")
if err != nil {
t.Error(err)
}
}

@ -9,6 +9,13 @@ go get git.sre.ink/go/gtool
***
https://github.com/xbmlz/gct
golang common tools
https://github.com/duke-git/lancet
lancet柳叶刀是一个全面、高效、可复用的go语言工具函数库。 lancet受到了java apache common包和lodash.js的启发。

@ -0,0 +1,42 @@
package str
// IsBlank 是否空(空白)字符串.
func (ts *Str) IsBlank(str string) bool {
// Check length
if len(str) > 0 {
// Iterate string
for i := range str {
// Check about char different from whitespace
// 227为全角空格
if str[i] > 32 && str[i] != 227 {
return false
}
}
}
return true
}
// IsNotBlank 是否非空(非空白)字符串.
func (ts *Str) IsNotBlank(str string) bool {
return !ts.IsBlank(str)
}
// IsEmpty 是否空字符串.
func (ts *Str) IsEmpty(str string) bool {
return len(str) == 0
}
// IsNotEmpty 是否非空字符串.
func (ts *Str) IsNotEmpty(str string) bool {
return !ts.IsEmpty(str)
}
// IsBlankOrEmpty 是否空白或空字符串.
func (ts *Str) IsBlankOrEmpty(str string) bool {
return ts.IsBlank(str) || ts.IsEmpty(str)
}
// IsNotBlankOrEmpty 是否非空白或非空字符串.
func (ts *Str) IsNotBlankOrEmpty(str string) bool {
return !ts.IsBlankOrEmpty(str)
}

@ -0,0 +1,51 @@
package str
import "testing"
func TestIsBlank(t *testing.T) {
var tests = []struct {
param string
expected bool
}{
{"", true},
{" \t\n\r\v\f\x00 ", true},
{"0", false},
{"hello", false},
}
for _, test := range tests {
actual := StrTool.IsBlank(test.param)
if actual != test.expected {
t.Errorf("%s must be %t", test.param, test.expected)
}
}
}
func FuzzStrIsBlank(f *testing.F) {
f.Fuzz(func(t *testing.T, str string) {
StrTool.IsBlank(str)
})
}
func FuzzStrIsNotBlank(f *testing.F) {
f.Fuzz(func(t *testing.T, str string) {
StrTool.IsNotBlank(str)
})
}
func FuzzStr_IsEmpty(f *testing.F) {
f.Fuzz(func(t *testing.T, str string) {
StrTool.IsEmpty(str)
})
}
func FuzzStr_IsNotEmpty(f *testing.F) {
f.Fuzz(func(t *testing.T, str string) {
StrTool.IsNotEmpty(str)
})
}
func FuzzIsBlankOrEmpty(f *testing.F) {
f.Fuzz(func(t *testing.T, str string) {
StrTool.IsBlankOrEmpty(str)
})
}
func FuzzIsNotBlankOrEmpty(f *testing.F) {
f.Fuzz(func(t *testing.T, str string) {
StrTool.IsNotBlankOrEmpty(str)
})
}
Loading…
Cancel
Save