mirror of
https://gitee.com/johng/gf
synced 2026-06-07 10:22:11 +08:00
改进gfpool文件指针池,增加对文件mv/rm后的指针池重建;改进gtime,增加对时间字符串更多的默认时间格式支持,新增gtime.ParseTimeFromContent方法
This commit is contained in:
@ -65,6 +65,11 @@ func (p *Pool) Put(value interface{}) {
|
||||
p.list.PushBack(item)
|
||||
}
|
||||
|
||||
// 清空对象池
|
||||
func (p *Pool) Clear() {
|
||||
p.list.RemoveAll()
|
||||
}
|
||||
|
||||
// 从池中获得一个临时对象
|
||||
func (p *Pool) Get() (interface{}, error) {
|
||||
for !p.closed.Val() {
|
||||
@ -93,11 +98,6 @@ func (p *Pool) Close() {
|
||||
p.closed.Set(true)
|
||||
}
|
||||
|
||||
// 池是否已关闭
|
||||
func (p *Pool) IsClosed() bool {
|
||||
return p.closed.Val()
|
||||
}
|
||||
|
||||
// 超时检测循环
|
||||
func (p *Pool) expireCheckingLoop() {
|
||||
for !p.closed.Val() {
|
||||
|
||||
@ -19,6 +19,7 @@ import (
|
||||
|
||||
// 文件指针池
|
||||
type Pool struct {
|
||||
id *gtype.Int // 指针池ID,用以识别指针池是否重建
|
||||
pool *gpool.Pool // 底层对象池
|
||||
inited *gtype.Bool // 是否初始化(在执行第一次File方法后初始化)
|
||||
watcher *fsnotify.Watcher // 文件监控对象
|
||||
@ -31,6 +32,7 @@ type File struct {
|
||||
os.File // 底层文件指针
|
||||
mu sync.RWMutex // 互斥锁
|
||||
pool *Pool // 所属池
|
||||
poolid int // 所属池ID,如果池ID不同表示池已经重建,那么该文件指针也应当销毁,不能重新丢到原有的池中
|
||||
flag int // 打开标志
|
||||
perm os.FileMode // 打开权限
|
||||
path string // 绝对路径
|
||||
@ -63,6 +65,7 @@ func New(path string, flag int, perm os.FileMode, expire...int) *Pool {
|
||||
fpExpire = expire[0]
|
||||
}
|
||||
p := &Pool {
|
||||
id : gtype.NewInt(),
|
||||
expire : fpExpire,
|
||||
inited : gtype.NewBool(),
|
||||
closeChan : make(chan struct{}),
|
||||
@ -84,11 +87,12 @@ func newFilePool(p *Pool, path string, flag int, perm os.FileMode, expire int) *
|
||||
return nil, err
|
||||
}
|
||||
return &File{
|
||||
File : *file,
|
||||
pool : p,
|
||||
flag : flag,
|
||||
perm : perm,
|
||||
path : path,
|
||||
File : *file,
|
||||
pool : p,
|
||||
poolid : p.id.Val(),
|
||||
flag : flag,
|
||||
perm : perm,
|
||||
path : path,
|
||||
}, nil
|
||||
})
|
||||
pool.SetExpireFunc(func(i interface{}) {
|
||||
@ -136,18 +140,22 @@ func (p *Pool) File() (*File, error) {
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
// 关闭事件
|
||||
case <- p.closeChan:
|
||||
return
|
||||
// 关闭事件
|
||||
case <- p.closeChan:
|
||||
return
|
||||
|
||||
// 监听事件
|
||||
case ev := <- p.watcher.Events:
|
||||
// 如果文件被删除或者重命名,重建指针池
|
||||
if ev.Op & fsnotify.Remove == fsnotify.Remove || ev.Op & fsnotify.Rename == fsnotify.Rename {
|
||||
p.pool.Close()
|
||||
p.pool = newFilePool(p, f.Name(), f.flag, f.perm, f.pool.expire)
|
||||
p.watcher.Remove(ev.Name)
|
||||
}
|
||||
case ev := <- p.watcher.Events:
|
||||
// 如果文件被删除或者重命名,立即重建指针池
|
||||
if ev.Op & fsnotify.Remove == fsnotify.Remove || ev.Op & fsnotify.Rename == fsnotify.Rename {
|
||||
// 原有的指针都不要了
|
||||
p.id.Add(1)
|
||||
// Clear相当于重建指针池
|
||||
p.pool.Clear()
|
||||
// 为保证原子操作,但又不想加锁,
|
||||
// 这里再执行一次原子Add,将在两次Add中间可能分配出去的文件指针丢弃掉
|
||||
p.id.Add(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
@ -165,6 +173,8 @@ func (p *Pool) Close() error {
|
||||
|
||||
// 获得底层文件指针(返回error是标准库io.ReadWriteCloser接口实现)
|
||||
func (f *File) Close() error {
|
||||
f.pool.pool.Put(f)
|
||||
if f.poolid == f.pool.id.Val() {
|
||||
f.pool.pool.Put(f)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -29,8 +29,8 @@ type Watcher struct {
|
||||
|
||||
// 监听事件对象
|
||||
type Event struct {
|
||||
Path string // 文件绝对路径
|
||||
Op Op // 触发监听的文件操作
|
||||
Path string // 文件绝对路径
|
||||
Op Op // 触发监听的文件操作
|
||||
Watcher *Watcher // 时间对应的监听对象
|
||||
}
|
||||
|
||||
@ -201,7 +201,7 @@ func (w *Watcher) startEventLoop() {
|
||||
// 如果是文件删除事件,判断该文件是否存在,如果存在,那么将此事件认为“假删除”,
|
||||
// 并重新添加监控(底层fsnotify会自动删除掉监控,这里重新添加回去)
|
||||
w.watcher.Add(event.Path)
|
||||
// 修改时间操作为重命名(相当于重命名为自身名称,最终名称没变)
|
||||
// 修改事件操作为重命名(相当于重命名为自身名称,最终名称没变)
|
||||
event.Op = RENAME
|
||||
} else {
|
||||
// 如果是真实删除,那么递归删除监控信息
|
||||
|
||||
@ -8,11 +8,12 @@
|
||||
package gtime
|
||||
|
||||
import (
|
||||
"time"
|
||||
"regexp"
|
||||
"strings"
|
||||
"strconv"
|
||||
"errors"
|
||||
"gitee.com/johng/gf/g/util/gregex"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -28,12 +29,45 @@ const (
|
||||
// "2018/10/31 - 16:38:46"
|
||||
// "2018-02-09",
|
||||
// 日期连接符号支持'-'或者'/'
|
||||
TIME_REAGEX_PATTERN = `(\d{2,4}[-/]\d{2}[-/]\d{2})[\sT-]*(\d{0,2}:{0,1}\d{0,2}:{0,1}\d{0,2}){0,1}\.{0,1}(\d{0,9})([\sZ]{0,1})([\+-]{0,1})([:\d]*)`
|
||||
TIME_REAGEX_PATTERN1 = `(\d{2,4}[-/]\d{2}[-/]\d{2})[:\sT-]*(\d{0,2}:{0,1}\d{0,2}:{0,1}\d{0,2}){0,1}\.{0,1}(\d{0,9})([\sZ]*)([\+-]{0,1})([:\d]*)`
|
||||
// 01-Nov-2018 11:50:28
|
||||
// 01/Nov/2018 11:50:28
|
||||
// 01/Nov/2018:11:50:28
|
||||
// 01/Nov/18 11:50:28
|
||||
TIME_REAGEX_PATTERN2 = `(\d{1,2}[-/][A-Za-z]{3,}[-/]\d{2,4})[:\sT-]*(\d{0,2}:{0,1}\d{0,2}:{0,1}\d{0,2}){0,1}\.{0,1}(\d{0,9})([\sZ]*)([\+-]{0,1})([:\d]*)`
|
||||
)
|
||||
|
||||
var (
|
||||
// 使用正则判断会比直接使用ParseInLocation挨个轮训判断要快很多
|
||||
timeRegex, _ = regexp.Compile(TIME_REAGEX_PATTERN)
|
||||
timeRegex1, _ = regexp.Compile(TIME_REAGEX_PATTERN1)
|
||||
timeRegex2, _ = regexp.Compile(TIME_REAGEX_PATTERN2)
|
||||
// 月份英文与阿拉伯数字对应关系
|
||||
monthMap = map[string]int {
|
||||
"jan" : 1,
|
||||
"feb" : 2,
|
||||
"mar" : 3,
|
||||
"apr" : 4,
|
||||
"may" : 5,
|
||||
"jun" : 6,
|
||||
"jul" : 7,
|
||||
"aug" : 8,
|
||||
"sep" : 9,
|
||||
"sept" : 9,
|
||||
"oct" : 10,
|
||||
"nov" : 11,
|
||||
"dec" : 12,
|
||||
"january" : 1,
|
||||
"february" : 2,
|
||||
"march" : 3,
|
||||
"april" : 4,
|
||||
"june" : 6,
|
||||
"july" : 7,
|
||||
"august" : 8,
|
||||
"september" : 9,
|
||||
"october" : 10,
|
||||
"november" : 11,
|
||||
"december" : 12,
|
||||
}
|
||||
)
|
||||
|
||||
// 类似与js中的SetTimeout,一段时间后执行回调函数
|
||||
@ -96,13 +130,19 @@ func Datetime() string {
|
||||
return time.Now().Format("2006-01-02 15:04:05")
|
||||
}
|
||||
|
||||
// 字符串转换为时间对象
|
||||
func StrToTime(str string) (time.Time, error) {
|
||||
var result time.Time
|
||||
var local = time.Local
|
||||
if match := timeRegex.FindStringSubmatch(str); len(match) > 0 {
|
||||
var year, month, day, hour, min, sec, nsec int
|
||||
var array []string
|
||||
// 字符串转换为时间对象,第二个参数指定格式的format(如: Y-m-d H:i:s),当指定第二个参数时同StrToTimeFormat方法
|
||||
func StrToTime(str string, format...string) (*Time, error) {
|
||||
if len(format) > 0 {
|
||||
return StrToTimeFormat(str, format[0])
|
||||
}
|
||||
var year, month, day, hour, min, sec, nsec int
|
||||
var array, match []string
|
||||
var local = time.Local
|
||||
match = timeRegex1.FindStringSubmatch(str)
|
||||
if len(match) > 0 {
|
||||
for k, v := range match {
|
||||
match[k] = strings.TrimSpace(v)
|
||||
}
|
||||
// 日期(支持'-'或'/'连接符号)
|
||||
array = strings.Split(match[1], "-")
|
||||
if len(array) < 3 {
|
||||
@ -117,32 +157,63 @@ func StrToTime(str string) (time.Time, error) {
|
||||
month, _ = strconv.Atoi(array[1])
|
||||
day, _ = strconv.Atoi(array[2])
|
||||
}
|
||||
// 时间
|
||||
if len(match[2]) > 0 {
|
||||
array = strings.Split(match[2], ":")
|
||||
hour, _ = strconv.Atoi(array[0])
|
||||
if len(array) >= 2 {
|
||||
min, _ = strconv.Atoi(array[1])
|
||||
} else {
|
||||
match = timeRegex2.FindStringSubmatch(str)
|
||||
if len(match) > 0 {
|
||||
for k, v := range match {
|
||||
match[k] = strings.TrimSpace(v)
|
||||
}
|
||||
// 日期(支持'-'或'/'连接符号)
|
||||
array = strings.Split(match[1], "-")
|
||||
if len(array) < 3 {
|
||||
array = strings.Split(match[1], "/")
|
||||
}
|
||||
if len(array) >= 3 {
|
||||
sec, _ = strconv.Atoi(array[2])
|
||||
day, _ = strconv.Atoi(array[0])
|
||||
if v, ok := monthMap[strings.ToLower(array[1])]; ok {
|
||||
month = v
|
||||
} else {
|
||||
return nil, errors.New("invalid month:" + array[1])
|
||||
}
|
||||
// 年是否为缩写,如果是,那么需要补上前缀
|
||||
year, _ = strconv.Atoi(array[2])
|
||||
if year < 100 {
|
||||
year = int(time.Now().Year()/100)*100 + year
|
||||
}
|
||||
}
|
||||
}
|
||||
// 纳秒,检查并执行位补齐
|
||||
if len(match[3]) > 0 {
|
||||
nsec, _ = strconv.Atoi(match[3])
|
||||
for i := 0; i < 9 - len(match[3]); i++ {
|
||||
nsec *= 10
|
||||
}
|
||||
}
|
||||
if len(match) == 0 {
|
||||
return nil, errors.New("unsupported time format")
|
||||
}
|
||||
|
||||
// 时间
|
||||
if len(match[2]) > 0 {
|
||||
array = strings.Split(match[2], ":")
|
||||
hour, _ = strconv.Atoi(array[0])
|
||||
if len(array) >= 2 {
|
||||
min, _ = strconv.Atoi(array[1])
|
||||
}
|
||||
// 如果字符串中有时区信息(具体时间信息),那么执行时区转换,将时区转成UTC
|
||||
if match[4] != "" && match[6] == "" {
|
||||
match[6] = "000000"
|
||||
if len(array) >= 3 {
|
||||
sec, _ = strconv.Atoi(array[2])
|
||||
}
|
||||
// 如果offset有值优先处理offset,否则处理后面的时区名称
|
||||
if match[6] != "" {
|
||||
zone := strings.Replace(match[6], ":", "", -1)
|
||||
zone = strings.TrimLeft(zone, "+-")
|
||||
}
|
||||
// 纳秒,检查并执行位补齐
|
||||
if len(match[3]) > 0 {
|
||||
nsec, _ = strconv.Atoi(match[3])
|
||||
for i := 0; i < 9 - len(match[3]); i++ {
|
||||
nsec *= 10
|
||||
}
|
||||
}
|
||||
// 如果字符串中有时区信息(具体时间信息),那么执行时区转换,将时区转成UTC
|
||||
if match[4] != "" && match[6] == "" {
|
||||
match[6] = "000000"
|
||||
}
|
||||
// 如果offset有值优先处理offset,否则处理后面的时区名称
|
||||
if match[6] != "" {
|
||||
zone := strings.Replace(match[6], ":", "", -1)
|
||||
zone = strings.TrimLeft(zone, "+-")
|
||||
if len(zone) <= 6 {
|
||||
zone += strings.Repeat("0", 6 - len(zone))
|
||||
h, _ := strconv.Atoi(zone[0 : 2])
|
||||
m, _ := strconv.Atoi(zone[2 : 4])
|
||||
@ -158,65 +229,81 @@ func StrToTime(str string) (time.Time, error) {
|
||||
operation = "-"
|
||||
}
|
||||
switch operation {
|
||||
case "+":
|
||||
if h > 0 {
|
||||
hour -= h
|
||||
}
|
||||
if m > 0 {
|
||||
min -= m
|
||||
}
|
||||
if s > 0 {
|
||||
sec -= s
|
||||
}
|
||||
case "-":
|
||||
if h > 0 {
|
||||
hour += h
|
||||
}
|
||||
if m > 0 {
|
||||
min += m
|
||||
}
|
||||
if s > 0 {
|
||||
sec += s
|
||||
}
|
||||
case "+":
|
||||
if h > 0 {
|
||||
hour -= h
|
||||
}
|
||||
if m > 0 {
|
||||
min -= m
|
||||
}
|
||||
if s > 0 {
|
||||
sec -= s
|
||||
}
|
||||
case "-":
|
||||
if h > 0 {
|
||||
hour += h
|
||||
}
|
||||
if m > 0 {
|
||||
min += m
|
||||
}
|
||||
if s > 0 {
|
||||
sec += s
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 生成UTC时间对象
|
||||
result = time.Date(year, time.Month(month), day, hour, min, sec, nsec, local)
|
||||
return result, nil
|
||||
}
|
||||
return result, errors.New("unsupported time format")
|
||||
// 统一生成UTC时间对象
|
||||
return NewFromTime(time.Date(year, time.Month(month), day, hour, min, sec, nsec, local)), nil
|
||||
}
|
||||
|
||||
// 时区转换
|
||||
func ConvertZone(strTime string, toZone string, fromZone...string) (time.Time, error) {
|
||||
func ConvertZone(strTime string, toZone string, fromZone...string) (*Time, error) {
|
||||
t, err := StrToTime(strTime)
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
return nil, err
|
||||
}
|
||||
if len(fromZone) > 0 {
|
||||
if l, err := time.LoadLocation(fromZone[0]); err != nil {
|
||||
return time.Time{}, err
|
||||
return nil, err
|
||||
} else {
|
||||
t = time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), l)
|
||||
t.Time = time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Time.Second(), t.Time.Nanosecond(), l)
|
||||
}
|
||||
}
|
||||
if l, err := time.LoadLocation(toZone); err != nil {
|
||||
return time.Time{}, err
|
||||
return nil, err
|
||||
} else {
|
||||
return t.In(l), nil
|
||||
return t.ToLocation(l), nil
|
||||
}
|
||||
}
|
||||
|
||||
// 字符串转换为时间对象,指定字符串时间格式,format格式形如:Y-m-d H:i:s
|
||||
func StrToTimeFormat(str string, format string) (time.Time, error) {
|
||||
func StrToTimeFormat(str string, format string) (*Time, error) {
|
||||
return StrToTimeLayout(str, formatToStdLayout(format))
|
||||
}
|
||||
|
||||
// 字符串转换为时间对象,通过标准库layout格式进行解析,layout格式形如:2006-01-02 15:04:05
|
||||
func StrToTimeLayout(str string, layout string) (time.Time, error) {
|
||||
func StrToTimeLayout(str string, layout string) (*Time, error) {
|
||||
if t, err := time.ParseInLocation(layout, str, time.Local); err == nil {
|
||||
return t, nil
|
||||
return NewFromTime(t), nil
|
||||
} else {
|
||||
return time.Time{}, err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// 从文本内容中解析时间,并返回解析成功的时间对象。注意当文本中存在多个时间时,会解析第一个。
|
||||
// format参数可以指定需要解析的时间格式。
|
||||
func ParseTimeFromContent(content string, format...string) *Time {
|
||||
if len(format) > 0 {
|
||||
if match, err := gregex.MatchString(formatToRegexPattern(format[0]), content); err == nil && len(match) > 0 {
|
||||
return NewFromStrFormat(match[0], format[0])
|
||||
}
|
||||
} else {
|
||||
if match := timeRegex1.FindStringSubmatch(content); len(match) >= 1 {
|
||||
return NewFromStr(match[0])
|
||||
} else if match := timeRegex2.FindStringSubmatch(content); len(match) >= 1 {
|
||||
return NewFromStr(match[0])
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -7,8 +7,9 @@
|
||||
package gtime
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"bytes"
|
||||
"gitee.com/johng/gf/g/util/gregex"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -68,6 +69,7 @@ func formatToStdLayout(format string) string {
|
||||
|
||||
default:
|
||||
if f, ok := formats[format[i]]; ok {
|
||||
// 有几个转换的符号需要特殊处理
|
||||
switch format[i] {
|
||||
case 'j':
|
||||
b.WriteString("02")
|
||||
@ -92,6 +94,14 @@ func formatToStdLayout(format string) string {
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// 将format格式转换为正则表达式规则
|
||||
func formatToRegexPattern(format string) string {
|
||||
s := gregex.Quote(formatToStdLayout(format))
|
||||
s, _ = gregex.ReplaceString(`[0-9]`, `[0-9]`, s)
|
||||
s, _ = gregex.ReplaceString(`[A-Za-z]`, `[A-Za-z]`, s)
|
||||
return s
|
||||
}
|
||||
|
||||
// 格式化,使用自定义日期格式
|
||||
func (t *Time) Format(format string) string {
|
||||
s := ""
|
||||
@ -109,6 +119,7 @@ func (t *Time) Format(format string) string {
|
||||
default:
|
||||
if f, ok := formats[format[i]]; ok {
|
||||
r := t.Time.Format(f)
|
||||
// 有几个转换的符号需要特殊处理
|
||||
switch format[i] {
|
||||
case 'j':
|
||||
s += strings.Replace(r, "=j=0", "", -1)
|
||||
|
||||
@ -39,9 +39,7 @@ func NewFromTime (t time.Time) *Time {
|
||||
// 从字符串转换为时间对象,复杂的时间字符串需要给定格式
|
||||
func NewFromStr (str string) *Time {
|
||||
if t, err := StrToTime(str); err == nil {
|
||||
return &Time{
|
||||
t,
|
||||
}
|
||||
return t
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -49,9 +47,7 @@ func NewFromStr (str string) *Time {
|
||||
// 从字符串转换为时间对象,指定字符串时间格式,format格式形如:Y-m-d H:i:s
|
||||
func NewFromStrFormat (str string, format string) *Time {
|
||||
if t, err := StrToTimeFormat(str, format); err == nil {
|
||||
return &Time{
|
||||
t,
|
||||
}
|
||||
return t
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -59,9 +55,7 @@ func NewFromStrFormat (str string, format string) *Time {
|
||||
// 从字符串转换为时间对象,通过标准库layout格式进行解析,layout格式形如:2006-01-02 15:04:05
|
||||
func NewFromStrLayout (str string, layout string) *Time {
|
||||
if t, err := StrToTimeLayout(str, layout); err == nil {
|
||||
return &Time{
|
||||
t,
|
||||
}
|
||||
return t
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -18,13 +18,13 @@ func Time(i interface{}, format...string) time.Time {
|
||||
// 优先使用用户输入日期格式进行转换
|
||||
if len(format) > 0 {
|
||||
t, _ := gtime.StrToTimeFormat(s, format[0])
|
||||
return t
|
||||
return t.Time
|
||||
}
|
||||
if gstr.IsNumeric(s) {
|
||||
return gtime.NewFromTimeStamp(Int64(s)).Time
|
||||
} else {
|
||||
t, _ := gtime.StrToTime(s)
|
||||
return t
|
||||
return t.Time
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -12,7 +12,9 @@ func main() {
|
||||
789
|
||||
`
|
||||
gfile.PutContents(path, content)
|
||||
fmt.Println(gfile.Size(path))
|
||||
fmt.Println(gfile.GetBinContentsTilCharByPath(path, '\n', 0))
|
||||
fmt.Println(gfile.GetBinContentsTilCharByPath(path, '\n', 3))
|
||||
fmt.Println(gfile.GetBinContentsTilCharByPath(path, '\n', 8))
|
||||
fmt.Println(gfile.GetBinContentsTilCharByPath(path, '\n', 12))
|
||||
}
|
||||
|
||||
27
geg/os/gtime/gtime_parsertime.go
Normal file
27
geg/os/gtime/gtime_parsertime.go
Normal file
@ -0,0 +1,27 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gitee.com/johng/gf/g/os/gtime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
content := `
|
||||
|
||||
2018-11-01 14:30:39 -- 67 -- assignDoctor:request -- {"问诊ID":"1017467","操作类型":2,"操作ID":52339491,"医生ID":52339491,"是否主动接单":"是"}
|
||||
2018-11-01 14:35:55 -- 73 -- throwIntoPool:request -- {"问诊Id":1017474,"当前Id":null,"当前角色":null}
|
||||
`
|
||||
if t := gtime.ParseTimeFromContent(content); t != nil {
|
||||
fmt.Println(t.String())
|
||||
fmt.Println(t.UTC())
|
||||
fmt.Println(gtime.Now().UTC())
|
||||
} else {
|
||||
panic("cannot parse time from content")
|
||||
}
|
||||
|
||||
//if t := gtime.ParseTimeFromContent(content, "d/M/Y:H:i:s +0800"); t != nil {
|
||||
// fmt.Println(t.String())
|
||||
//} else {
|
||||
// panic("cannot parse time from content")
|
||||
//}
|
||||
}
|
||||
@ -7,7 +7,7 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
timeRegex, err := regexp.Compile(gtime.TIME_REAGEX_PATTERN)
|
||||
timeRegex, err := regexp.Compile(gtime.TIME_REAGEX_PATTERN1)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
32
geg/os/gtime/gtime_regex2.go
Normal file
32
geg/os/gtime/gtime_regex2.go
Normal file
@ -0,0 +1,32 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"fmt"
|
||||
"gitee.com/johng/gf/g/os/gtime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
timeRegex, err := regexp.Compile(gtime.TIME_REAGEX_PATTERN2)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
array := []string{
|
||||
"01-Nov-2018 11:50:28 +0805 LMT",
|
||||
"01-Nov-2018T15:04:05Z07:00",
|
||||
"01-Nov-2018T01:19:15+08:00",
|
||||
"01-Nov-2018 11:50:28 +0805 LMT",
|
||||
"01/Nov/18 11:50:28",
|
||||
"01/Nov/2018 11:50:28",
|
||||
"01/Nov/2018:11:50:28",
|
||||
"01/Nov/2018",
|
||||
}
|
||||
for _, s := range array {
|
||||
fmt.Println(s)
|
||||
match := timeRegex.FindStringSubmatch(s)
|
||||
for k, v := range match {
|
||||
fmt.Println(k, v)
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
}
|
||||
@ -21,6 +21,15 @@ func main() {
|
||||
"18/02/09 12:16",
|
||||
"18/02/09 12",
|
||||
"18/02/09 +0805 LMT",
|
||||
"01/Nov/2018:13:28:13 +0800",
|
||||
"01-Nov-2018 11:50:28 +0805 LMT",
|
||||
"01-Nov-2018T15:04:05Z07:00",
|
||||
"01-Nov-2018T01:19:15+08:00",
|
||||
"01-Nov-2018 11:50:28 +0805 LMT",
|
||||
"01/Nov/18 11:50:28",
|
||||
"01/Nov/2018 11:50:28",
|
||||
"01/Nov/2018:11:50:28",
|
||||
"01/Nov/2018",
|
||||
}
|
||||
cstLocal, _ := time.LoadLocation("Asia/Shanghai")
|
||||
for _, s := range array {
|
||||
|
||||
@ -2,19 +2,11 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gitee.com/johng/gf/g/os/gfpool"
|
||||
"os"
|
||||
"time"
|
||||
"gitee.com/johng/gf/g/util/gregex"
|
||||
)
|
||||
|
||||
func main() {
|
||||
for {
|
||||
time.Sleep(time.Second)
|
||||
if f, err := gfpool.Open("/home/john/temp/log.log", os.O_RDONLY, 0666, 60000000*1000); err == nil {
|
||||
s, _ := f.Stat()
|
||||
fmt.Println(f.Name(), s.Name())
|
||||
} else {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
s := `[0-9][0-9]/Jan/[0-9][0-9][0-9][0-9]:[0-9][0-9]:[0-9][0-9]:[0-9][0-9] \+[0-9][0-9][0-9][0-9]`
|
||||
s,_ = gregex.ReplaceString(`[A-Za-z]`, `[A-Za-z]`, s)
|
||||
fmt.Println(s)
|
||||
}
|
||||
Reference in New Issue
Block a user