github.com/qioalice/ekago/v3@v3.3.2-0.20221202205325-5c262d586ee4/ekatime/event.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  )
    11  
    12  type (
    13  	// EventID is an alias to Golang unit type
    14  	// that is used to represents an Event's ID.
    15  	EventID uint16
    16  
    17  	// Event represents some unusual days - events.
    18  	// Like holidays, personal vacation days or work day off, etc.
    19  	//
    20  	// Contains:
    21  	// - Day (use Day() method, values: 1-31),
    22  	// - Month (use Month() method, values: 1-12),
    23  	// - Year (use Year() method, values: 0-4095),
    24  	// - Working? (use IsWorkday() or IsDayOff() method),
    25  	// - Event type's ID (use ID() method, values: 0-65535).
    26  	//
    27  	// Supports up to 127 types you can bind an Event to. Hope it's enough.
    28  	// Takes just 8 byte. At all! Thanks to bitwise operations.
    29  	Event uint64
    30  )
    31  
    32  func (e Event) IsValid() bool {
    33  	return e != _EVENT_INVALID && e.Date().IsValid()
    34  }
    35  
    36  //
    37  func (e Event) Year() Year {
    38  	return e.Date().Year()
    39  }
    40  
    41  //
    42  func (e Event) Month() Month {
    43  	return e.Date().Month()
    44  }
    45  
    46  //
    47  func (e Event) Day() Day {
    48  	return e.Date().Day()
    49  }
    50  
    51  //
    52  func (e Event) Weekday() Weekday {
    53  	return e.Date().Weekday()
    54  }
    55  
    56  //
    57  func (e Event) Date() Date {
    58  	return Date(e>>_EVENT_OFFSET_DATE) & _DATE_MASK_DATE
    59  }
    60  
    61  //
    62  func (e Event) IsWorkday() bool {
    63  	return !e.IsDayOff()
    64  }
    65  
    66  //
    67  func (e Event) IsDayOff() bool {
    68  	return uint8((e>>_EVENT_OFFSET_IS_WORKDAY)&_EVENT_MASK_IS_WORKDAY) > 0
    69  }
    70  
    71  //
    72  func (e Event) ID() EventID {
    73  	return EventID(e >> _EVENT_OFFSET_ID & _EVENT_MASK_ID)
    74  }
    75  
    76  //
    77  func (e Event) Split() (id EventID, dd Date, isDayOff bool) {
    78  	return e.ID(), e.Date(), e.IsDayOff()
    79  }
    80  
    81  //
    82  func NewEvent(d Date, id EventID, isDayOff bool) Event {
    83  
    84  	isDayOffBit := Event(0)
    85  	if isDayOff {
    86  		isDayOffBit = Event(1) << _EVENT_OFFSET_IS_WORKDAY
    87  	}
    88  
    89  	d = d.ensureWeekdayExist()
    90  
    91  	return Event(d&_DATE_MASK_DATE)<<_EVENT_OFFSET_DATE | isDayOffBit |
    92  		(Event(id)&_EVENT_MASK_ID)<<_EVENT_OFFSET_ID
    93  }
    94  
    95  // String returns the current Event's string representation in the following format:
    96  // "YYYY/MM/DD [<isWorkDay>] ID: <id>", where:
    97  //     <id> is Event's ID as is in the range [1..127],
    98  //     <isWorkDay> is either "Workday" or "Dayoff"
    99  func (e Event) String() string {
   100  	s := "Workday"
   101  	if e.IsDayOff() {
   102  		s = "Dayoff"
   103  	}
   104  	return fmt.Sprintf("%04d/%02d/%02d [%s] ID: %d", e.Year(), e.Month(), e.Day(), s, e.ID())
   105  }