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)
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
package date
|
||||
|
||||
var dateTime DateTime
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
Loading…
Reference in new issue