github.com/suiyunonghen/DxCommonLib@v0.5.3/delphi_time.go (about)

     1  package DxCommonLib
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"runtime"
     7  	"strconv"
     8  	"time"
     9  )
    10  
    11  type (
    12  	TDateTime float64
    13  )
    14  
    15  const (
    16  	MinsPerHour = 60
    17  	MinsPerDay  = 24 * MinsPerHour
    18  	SecsPerDay  = MinsPerDay * 60
    19  	MSecsPerDay = SecsPerDay * 1000
    20  )
    21  
    22  var (
    23  	delphiFirstTime        time.Time
    24  	IsAmd64                = runtime.GOARCH == "amd64"
    25  	ErrInvalidJsonDateTime = errors.New("invalidate json dateTime format")
    26  )
    27  
    28  func init() {
    29  	delphiFirstTime = time.Date(1899, 12, 30, 0, 0, 0, 0, time.Local)
    30  }
    31  
    32  /*ToTime
    33  从Delphi日期转为Go日期格式
    34  Delphi的日期规则为到1899-12-30号的天数+当前的毫秒数/一天的总共毫秒数集合
    35  */
    36  func (date TDateTime) ToTime() time.Time {
    37  	mDay := time.Duration(date)
    38  	ms := (date - TDateTime(mDay)) * TDateTime(MSecsPerDay)
    39  	return delphiFirstTime.Add(mDay*time.Hour*24 + time.Duration(ms)*time.Millisecond)
    40  }
    41  
    42  func (date *TDateTime) WrapTime2Self(t time.Time) {
    43  	days := t.Sub(delphiFirstTime) / (time.Hour * 24)
    44  	y, m, d := t.Date()
    45  	nowdate := time.Date(y, m, d, 0, 0, 0, 0, time.Local)
    46  	times := float64(t.Sub(nowdate)) / float64(time.Hour*24)
    47  	*date = TDateTime(float64(days) + times)
    48  }
    49  
    50  func Time2DelphiTime(t time.Time) TDateTime {
    51  	if t.IsZero() {
    52  		return 0
    53  	}
    54  	days := t.Sub(delphiFirstTime) / (time.Hour * 24)
    55  	y, m, d := t.Date()
    56  	nowdate := time.Date(y, m, d, 0, 0, 0, 0, time.Local)
    57  	times := float64(t.Sub(nowdate)) / float64(time.Hour*24)
    58  	return TDateTime(float64(days) + times)
    59  }
    60  
    61  //ParserJsonTime
    62  //Date(1402384458000)
    63  //Date(1224043200000+0800)
    64  func ParserJsonTime(jsontime string) (time.Time, error) {
    65  	bt := FastString2Byte(jsontime)
    66  	dtflaglen := 0
    67  	endlen := 0
    68  	if bytes.HasPrefix(bt, []byte{'D', 'a', 't', 'e', '('}) && bytes.HasSuffix(bt, []byte{')'}) {
    69  		dtflaglen = 5
    70  		endlen = 1
    71  	} else if bytes.HasPrefix(bt, []byte{'/', 'D', 'a', 't', 'e', '('}) && bytes.HasSuffix(bt, []byte{')', '/'}) {
    72  		dtflaglen = 6
    73  		endlen = 2
    74  	}
    75  	if dtflaglen > 0 {
    76  		bt = bt[dtflaglen : len(bt)-endlen]
    77  		var (
    78  			ms  int64
    79  			err error
    80  		)
    81  		endlen = 0
    82  		idx := bytes.IndexByte(bt, '+')
    83  		if idx < 0 {
    84  			idx = bytes.IndexByte(bt, '-')
    85  		} else {
    86  			endlen = 1
    87  		}
    88  		if idx < 0 {
    89  			str := FastByte2String(bt[:])
    90  			if ms, err = strconv.ParseInt(str, 10, 64); err != nil {
    91  				return time.Time{}, ErrInvalidJsonDateTime
    92  			}
    93  			if len(str) > 9 {
    94  				ms = ms / 1000
    95  			}
    96  		} else {
    97  			if endlen == 0 {
    98  				endlen = -1
    99  			}
   100  			str := FastByte2String(bt[:idx])
   101  			ms, err = strconv.ParseInt(str, 10, 64)
   102  			if err != nil {
   103  				return time.Time{}, err
   104  			}
   105  			bt = bt[idx+1:]
   106  			if len(bt) < 2 {
   107  				return time.Time{}, ErrInvalidJsonDateTime
   108  			}
   109  			bt = bt[:2]
   110  			ctz, err := strconv.Atoi(FastByte2String(bt))
   111  			if err != nil {
   112  				return time.Time{}, ErrInvalidJsonDateTime
   113  			}
   114  			if len(str) > 9 {
   115  				ms = ms / 1000
   116  			}
   117  			ms += int64(ctz * 60)
   118  		}
   119  		ntime := time.Now()
   120  		ns := ntime.Unix()
   121  		ntime = ntime.Add((time.Duration(ms-ns) * time.Second))
   122  		return ntime, nil
   123  	}
   124  	return time.Time{}, ErrInvalidJsonDateTime
   125  }