github.com/GoWebProd/gip@v0.0.0-20230623090727-b60d41d5d320/fasttime/fasttime.go (about)

     1  package fasttime
     2  
     3  import (
     4  	"strconv"
     5  	"strings"
     6  	"syscall"
     7  	"time"
     8  )
     9  
    10  const (
    11  	laepoch = 946684800 + 86400*(31+29)
    12  
    13  	daysPer400y = 365*400 + 97
    14  	daysPer100y = 365*100 + 24
    15  	daysPer4y   = 365*4 + 1
    16  )
    17  
    18  var daysInMonth = [...]int64{31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 29}
    19  
    20  /* Originally released by the musl project (http://www.musl-libc.org/) under the
    21   * MIT license. Taken from the file /src/time/__secs_to_tm.c */
    22  func ParseDateTime(timestamp int64) (year int64, month int64, day int64, hour int64, minute int64, seconds int64) {
    23  	secs := timestamp - laepoch
    24  	days := secs / 86400
    25  
    26  	remsecs := secs % 86400
    27  	if remsecs < 0 {
    28  		remsecs += 86400
    29  		days--
    30  	}
    31  
    32  	wday := (3 + days) % 7
    33  	if wday < 0 {
    34  		wday += 7
    35  	}
    36  
    37  	qcCycles := days / daysPer400y
    38  	remdays := days % daysPer400y
    39  	if remdays < 0 {
    40  		remdays += daysPer400y
    41  		qcCycles--
    42  	}
    43  
    44  	cCycles := remdays / daysPer100y
    45  	if cCycles == 4 {
    46  		cCycles--
    47  	}
    48  	remdays -= cCycles * daysPer100y
    49  
    50  	qCycles := remdays / daysPer4y
    51  	if qCycles == 25 {
    52  		qCycles--
    53  	}
    54  	remdays -= qCycles * daysPer4y
    55  
    56  	remyears := remdays / 365
    57  	if remyears == 4 {
    58  		remyears--
    59  	}
    60  	remdays -= remyears * 365
    61  
    62  	var leap int64
    63  	if remyears == 0 && (qCycles > 0 || cCycles == 0) {
    64  		leap = 1
    65  	}
    66  
    67  	yday := remdays + 31 + 28 + leap
    68  	if yday >= 365+leap {
    69  		yday -= 365 + leap
    70  	}
    71  
    72  	years := remyears + 4*qCycles + 100*cCycles + 400*qcCycles
    73  
    74  	var months int64
    75  	for months = 0; daysInMonth[months] <= remdays; months++ {
    76  		remdays -= daysInMonth[months]
    77  	}
    78  
    79  	tmYear := years + 2000
    80  	tmMon := months + 2
    81  	if tmMon >= 12 {
    82  		tmMon -= 12
    83  		tmYear++
    84  	}
    85  	tmMday := remdays + 1
    86  
    87  	tmHour := remsecs / 3600
    88  	tmMin := remsecs / 60 % 60
    89  	tmSec := remsecs % 60
    90  
    91  	return tmYear, tmMon, tmMday, tmHour, tmMin, tmSec
    92  }
    93  
    94  func ParseDate(timestamp int64) (year int64, month int64, day int64) {
    95  	year, month, day, _, _, _ = ParseDateTime(timestamp)
    96  	return
    97  }
    98  
    99  func FormatTimestampToDate(timestamp int64) string {
   100  	return FormatDate(ParseDate(timestamp))
   101  }
   102  
   103  func FormatTimestampToDateTime(timestamp int64) string {
   104  	return FormatDateTime(ParseDateTime(timestamp))
   105  }
   106  
   107  func FormatDate(year int64, month int64, day int64) string {
   108  	month += 1
   109  
   110  	sb := strings.Builder{}
   111  	sb.WriteString(strconv.Itoa(int(year)))
   112  	if month < 10 {
   113  		sb.WriteString("0")
   114  	}
   115  	sb.WriteString(strconv.Itoa(int(month)))
   116  	if day < 10 {
   117  		sb.WriteString("0")
   118  	}
   119  	sb.WriteString(strconv.Itoa(int(day)))
   120  
   121  	return sb.String()
   122  }
   123  
   124  func FormatDateTime(year int64, month int64, day int64, hour int64, minute int64, second int64) string {
   125  	month++
   126  
   127  	sb := strings.Builder{}
   128  
   129  	sb.WriteString(strconv.Itoa(int(year)))
   130  
   131  	if month < 10 {
   132  		sb.WriteString("0")
   133  	}
   134  
   135  	sb.WriteString(strconv.Itoa(int(month)))
   136  
   137  	if day < 10 {
   138  		sb.WriteString("0")
   139  	}
   140  
   141  	sb.WriteString(strconv.Itoa(int(day)))
   142  
   143  	if hour < 10 {
   144  		sb.WriteString("0")
   145  	}
   146  
   147  	sb.WriteString(strconv.Itoa(int(hour)))
   148  
   149  	if minute < 10 {
   150  		sb.WriteString("0")
   151  	}
   152  
   153  	sb.WriteString(strconv.Itoa(int(minute)))
   154  
   155  	if second < 10 {
   156  		sb.WriteString("0")
   157  	}
   158  
   159  	sb.WriteString(strconv.Itoa(int(second)))
   160  
   161  	return sb.String()
   162  }
   163  
   164  func Now() int64 {
   165  	var tv syscall.Timeval
   166  	err := syscall.Gettimeofday(&tv)
   167  	if err != nil {
   168  		return time.Now().Unix()
   169  	}
   170  	return int64(tv.Sec)
   171  }
   172  
   173  func NowNano() int64 {
   174  	var tv syscall.Timeval
   175  	err := syscall.Gettimeofday(&tv)
   176  	if err != nil {
   177  		return time.Now().UnixNano()
   178  	}
   179  	return int64(tv.Nano())
   180  }
   181  
   182  func Round(timestamp int64, period int64) int64 {
   183  	delta := timestamp % period
   184  	result := timestamp - delta
   185  	// if delta >= (period >> 1) {
   186  	// 	result += period
   187  	// }
   188  
   189  	return result
   190  }