github.com/qioalice/ekago/v3@v3.3.2-0.20221202205325-5c262d586ee4/ekatime/date_private.go (about)

     1  // Copyright © 2020. All rights reserved.
     2  // Author: Ilya Stroy.
     3  // Contacts: iyuryevich@pm.me, https://github.com/qioalice
     4  // License: https://opensource.org/licenses/MIT
     5  
     6  package ekatime
     7  
     8  import (
     9  	"fmt"
    10  	"strconv"
    11  	"time"
    12  
    13  	"github.com/modern-go/reflect2"
    14  )
    15  
    16  //noinspection GoSnakeCaseUsage
    17  const (
    18  	_DATE_OFFSET_DAY     uint8 = 0
    19  	_DATE_OFFSET_MONTH   uint8 = _DATE_OFFSET_DAY + 5
    20  	_DATE_OFFSET_YEAR    uint8 = _DATE_OFFSET_MONTH + 4
    21  	_DATE_OFFSET_WEEKDAY uint8 = _DATE_OFFSET_YEAR + 12
    22  	_DATE_OFFSET_UNUSED  uint8 = _DATE_OFFSET_WEEKDAY + 3
    23  
    24  	_DATE_MASK_DAY     Day     = 0x1F
    25  	_DATE_MASK_MONTH   Month   = 0x0F
    26  	_DATE_MASK_YEAR    Year    = 0x0FFF
    27  	_DATE_MASK_WEEKDAY Weekday = 0x07
    28  
    29  	_DATE_MASK_DATE Date = (Date(1) << _DATE_OFFSET_UNUSED) - 1
    30  )
    31  
    32  //goland:noinspection GoSnakeCaseUsage
    33  const (
    34  	_DATE_INVALID Date = 0
    35  )
    36  
    37  //noinspection GoSnakeCaseUsage
    38  const (
    39  	// Min and max values to use _YEAR_AS_NUM_STR instead of strconv.Itoa()
    40  	_YEAR_AS_NUM_STR_MIN      = _YEAR_MIN
    41  	_YEAR_AS_NUM_STR_MAX Year = 2100
    42  
    43  	_YEAR_MIN Year = 1900
    44  	_YEAR_MAX Year = 4095
    45  )
    46  
    47  //noinspection GoSnakeCaseUsage
    48  var (
    49  	_YEAR_AS_NUM_STR [_YEAR_AS_NUM_STR_MAX - _YEAR_AS_NUM_STR_MIN + 1][]byte
    50  	_DAY_AS_NUM_STR  [31][]byte
    51  )
    52  
    53  // normalizeDate shifts Date, 'y', 'm', and 'd' represents which if they are not
    54  // in their valid ranges. Returns the fixed values (if they has been).
    55  func normalizeDate(y Year, m Month, d Day) (Year, Month, Day) {
    56  	if !IsValidDate(y, m, d) {
    57  		t := time.Date(int(y), time.Month(m), int(d), 0, 0, 0, 0, time.UTC)
    58  		ty, tm, td := t.Date()
    59  		if y > _YEAR_MAX {
    60  			y = _YEAR_MAX
    61  		}
    62  		y, m, d = Year(ty), Month(tm), Day(td)
    63  	}
    64  	return y, m, d
    65  }
    66  
    67  // ensureWeekdayExist returns the current Date w/o modifications if it already
    68  // has a weekday or adds it and to and returns a copy.
    69  func (dd Date) ensureWeekdayExist() Date {
    70  	return dd | dd.Weekday().asPartOfDate()
    71  }
    72  
    73  // initDateNumStr initializes _YEAR_AS_NUM_STR and _DAY_AS_NUM_STR
    74  // that are used at the Date.String(), Date.AppendTo()
    75  // and other methods to get a string (or []byte) representation of Date.
    76  func initDateNumStr() {
    77  	for y := _YEAR_AS_NUM_STR_MIN; y <= _YEAR_AS_NUM_STR_MAX; y++ {
    78  		_YEAR_AS_NUM_STR[y-_YEAR_AS_NUM_STR_MIN] =
    79  			reflect2.UnsafeCastString(strconv.Itoa(int(y)))
    80  	}
    81  	for d := Day(1); d <= 31; d++ {
    82  		_DAY_AS_NUM_STR[d-1] =
    83  			reflect2.UnsafeCastString(fmt.Sprintf("%02d", d))
    84  	}
    85  }