Skip to content

Commit

Permalink
global: initial v2 commit
Browse files Browse the repository at this point in the history
Rewrite/refactor to support improved holiday and working hours calcs.

Improve holiday observation logic; start/end/exception years.

Add ability to reuse and rename holidays.

Resolves #34
Resolves #37
  • Loading branch information
rickar committed May 3, 2020
1 parent 7864a4b commit 8640818
Show file tree
Hide file tree
Showing 108 changed files with 7,812 additions and 4,335 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,12 @@ jobs:

- name: Download Deps
run: go mod download
working-directory: ./v2

- name: Build
run: go build ./...
working-directory: ./v2

- name: Test
run: go test -v ./...
working-directory: ./v2
17 changes: 17 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
vendor/

.vscode/
82 changes: 62 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,72 @@
# cal: Go (golang) calendar library for dealing with holidays and work days
# cal/v2: Go (golang) calendar library for dealing with holidays and work days

This library augments the Go time package to provide easy handling of holidays
and work days (business days).

Holiday instances can be exact days, floating days such as the 3rd Monday of
the month, yearly offsets such as the 100th day of the year, or the result of
custom function executions for complex rules.

The Calendar type provides functions for calculating workdays and dealing
with holidays that are observed on alternate days when they fall on weekends.

Holiday instances are calculated from either builtin or user-created functions
to support exact days, floating days such as the 3rd Monday of the month,
yearly offsets such as the 100th day of the year, or more complex rules such as
offsets from Easter. Holidays may provide separate actual and observed dates
for cases where holidays are celebrated on an alternate day if they fall on a
specific day of the week (usually weekends).

The Calendar type provides the basic functionality for creating a yearly
calendar with holidays.

BusinessCalendar adds additional functionality for calculating workdays and
hours worked.

# Differences from v1
For v2, much of the functionality of this library was rewritten to address
shortcomings of the v1 releases. This version provides the following benefits
over v1:
* Holidays
* Observation rules are tied to individual holidays rather than a per-calendar
setting
* Name, description, and observance type fields added
* Starting, ending, and exception year options
* Holiday definitions are separated into subpackages by ISO code (no longer
necessary to bundle all holidays in the final binary)
* Calendar
* Separation of business specific functionality into BusinessCalendar
* Name and description fields added
* Support for time.Location matching to ease use of multiple Calendars
* BusinessCalendar
* Full support for working hours including dynamically determining work
start and end times per day and the number of work hours between dates
* Support for "overnight" working hours where a workday starts at night and
ends in the morning

# Example
Here is a simple usage example of a cron job that runs once per day:
```go
package main

import (
"time"

"github.com/rickar/cal"
"github.com/rickar/cal/v2"
"github.com/rickar/cal/v2/us"
)

func main() {
c := cal.NewCalendar()
c := cal.NewBusinessCalendar()
c.Name = "Bigco, Inc."
c.Description = "Default company calendar"

// add holidays for the business
// add holidays that the business observes
c.AddHoliday(
cal.USIndependence,
cal.USThanksgiving,
cal.USChristmas,
us.NewYear,
us.MemorialDay,
us.IndependenceDay,
us.LaborDay,
us.ThanksgivingDay,
us.ChristmasDay,
)

// optionally change the default of a Mon - Fri work week
// change the default of a Mon - Fri, 9am-5pm work week
c.SetWorkday(time.Saturday, true)

// optionally change the holiday calculation behavior
// (the default is US-style where weekend holidays are
// observed on the closest weekday)
c.Observed = cal.ObservedExact
c.SetWorkHours(8*time.Hour, 18*time.Hour+30*time.Minute)

t := time.Now()

Expand All @@ -59,5 +89,17 @@ func main() {
// last business day of the month
// execute auto billing transfers
}

// determine the number of working hours left in the current month
nextMonth := cal.DayStart(cal.MonthStart(t.AddDate(0, 1, 0)))
hoursLeft := c.WorkHoursInRange(t, nextMonth)

// check if there are any tasks for this month that are in danger of missing their deadline
pendingTasks := []struct{ pendingHours time.Duration }{{pendingHours: 32}} // assumed to be fetched from a DB or API
for _, task := range pendingTasks {
if hoursLeft < task.pendingHours {
// send alert to management
}
}
}
```
Loading

0 comments on commit 8640818

Please sign in to comment.