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

     1  // Copyright © 2020-2021. 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  type (
     9  	// Weekday is a special type that has enough space to store weekday's number.
    10  	// Useless just by yourself but is a part of Date object.
    11  	// Valid values: [0..6]. Use predefined constants to make it clear.
    12  	Weekday int8
    13  )
    14  
    15  //noinspection GoSnakeCaseUsage,GoUnusedConst
    16  const (
    17  	WEEKDAY_WEDNESDAY Weekday = iota
    18  	WEEKDAY_THURSDAY
    19  	WEEKDAY_FRIDAY
    20  	WEEKDAY_SATURDAY
    21  	WEEKDAY_SUNDAY
    22  	WEEKDAY_MONDAY
    23  	WEEKDAY_TUESDAY
    24  )
    25  
    26  // WeekdayJan1 returns a Weekday of 1 January of requested Year.
    27  // Returns -1 if passed Year is not in the range [1..4095].
    28  //
    29  // Yes, although other functions and methods declares 1900 as lower bound of Year,
    30  // here you can use even lower than 1900.
    31  func WeekdayJan1(y Year) Weekday {
    32  
    33  	// Algorithm from:
    34  	// https://people.cs.nctu.edu.tw/~tsaiwn/sisc/runtime_error_200_div_by_0/www.merlyn.demon.co.uk/weekcalc.htm
    35  	// (if not available, then thank you, Mr Zeller)
    36  	// https://en.wikipedia.org/wiki/Christian_Zeller
    37  
    38  	if y <= 0 || y > _YEAR_MAX {
    39  		return -1
    40  	} else if y >= 1901 && y <= 2099 {
    41  		yf := float32(y)
    42  		return WeekdayFrom06(int8(int16(1.25*(yf-1)) % 7))
    43  	} else {
    44  		y--
    45  		yf := float32(y)
    46  		return WeekdayFrom06(int8(int16((1.25*yf)-(yf/100)+(yf/400)+1) % 7))
    47  	}
    48  }
    49  
    50  // Next returns the next day of week following the current one.
    51  func (w Weekday) Next() Weekday {
    52  	if w == WEEKDAY_TUESDAY {
    53  		return WEEKDAY_WEDNESDAY
    54  	}
    55  	return w + 1
    56  }
    57  
    58  // Prev returns the prev day of week before the current one.
    59  func (w Weekday) Prev() Weekday {
    60  	if w == WEEKDAY_WEDNESDAY {
    61  		return WEEKDAY_TUESDAY
    62  	}
    63  	return w - 1
    64  }
    65  
    66  // IsDayOff reports whether current day of week is Saturday or Sunday.
    67  func (w Weekday) IsDayOff() bool {
    68  	return w == WEEKDAY_SATURDAY || w == WEEKDAY_SUNDAY
    69  }
    70  
    71  // String returns the current Weekday's string representation as full day of week
    72  // name, capitalized.
    73  func (w Weekday) String() string {
    74  	if w < 0 || w > 6 {
    75  		//noinspection GoAssignmentToReceiver
    76  		w = -1
    77  	}
    78  	return _WeekdayStr[w+1]
    79  }
    80  
    81  // MarshalJSON returns the current Weekday's string representation and nil (always).
    82  // It will be the same as String() returns (but double quoted).
    83  func (w Weekday) MarshalJSON() ([]byte, error) {
    84  	return w.byteSliceEncode(), nil
    85  }
    86  
    87  // UnmarshalJSON tries to decode 'data' and treat it as encoded weekday.
    88  // If it's so, saves the weekday into the current Weekday's object.
    89  // If 'data' contains an invalid data, -1 will be stored into the current Weekday.
    90  // Always returns nil.
    91  func (w *Weekday) UnmarshalJSON(data []byte) error {
    92  	return w.byteSliceDecode(data)
    93  }
    94  
    95  // From06 parses passed i8, transforms it to the Weekday, saves to the current object,
    96  // and returns it.
    97  // Requires i8 be in the range [0..6], where 0 - Sunday, 6 - Saturday.
    98  // Does nothing if w == nil, but returns it.
    99  func (w *Weekday) From06(i8 int8) *Weekday {
   100  	if w != nil && i8 >= 0 && i8 <= 6 {
   101  		*w = WeekdayFrom06(i8)
   102  	}
   103  	return w
   104  }
   105  
   106  // WeekdayFrom06 parses passed i8, transforms it to the Weekday and returns.
   107  // Requires i8 be in the range [0..6], where 0 - Sunday, 6 - Saturday.
   108  // Returns -1 if i8 is not in the allowed range.
   109  func WeekdayFrom06(i8 int8) Weekday {
   110  	if i8 >= 0 && i8 <= 6 {
   111  		return Weekday(i8+4) % 7
   112  	} else {
   113  		return -1
   114  	}
   115  }
   116  
   117  // To06 returns a uint8 representation of the current Weekday,
   118  // where 0 - Sunday, 6 - Saturday.
   119  func (w Weekday) To06() int8 {
   120  	return int8(w+3) % 7
   121  }