Git Product home page Git Product logo

swifty-holidays's Introduction

SwiftyHolidays

GitHub release Tests Codacy Badge codecov Docs

A holiday calculator written in Swift.

Installation

Add the following dependency to your Package.swift:

.package(url: "https://github.com/sersoft-gmbh/swifty-holidays.git", from: "2.0.0"),

Or add it via Xcode (as of Xcode 11).

Usage

SwiftyHolidays is built upon calculators. A calculator is responsible for calculating holidays in a given year for a certain calendar. Currently, SwiftyHolidays has a calculator for the gregorian calendar.

All calculations in SwiftyHolidays are thread-safe and are only performed once. This means even if you ask a given calculator for a certain date from two threads in parallel, it will only be calculated once and the second thread will wait for the first to finish its calculation. Certain dates (like e.g. new years eve) don't even need to be calculated but are fixed day-month-combinations. Dates, that do have to be calculated, are cached, so that the next time a certain date is requested, it does not have to be calculated but is returned immediately instead. Even though calculators are usually structs, they have reference semantics and are thread-safe when it comes to their context (which e.g. contains their cache). This means that you can use the calculator object in multiple places and still get the same performance by having dates calculated only once.

The context of a calculator can also be serialized and merged. This means that you could e.g. create a calculator, use it to calculate a few dates and then serialize its context to disk. Later on, you deserialize the context and pass it to a new calculator which will then profit from the previously calculated and now already cached dates. This even works across years. Meaning you can build up a cache spanning multiple years. If your cache grows too large, you can always clear the context (or simply create a new calculator that uses a new context).

Here are a few examples:

let calculator = GregorianCalculator()
// A few calculations:
let easterSunday20 = calculator.easterSunday(forYear: 2020)
// -> 2020-04-12
let firstAdvent19 = calculator.firstSundayOfAdvent(forYear: 2019)
// -> 2019-12-01
let firstAdvent20 = calculator.firstSundayOfAdvent(forYear: 2020)
// -> 2020-11-29


// Serialize context
let data = try JSONEncoder().encode(calculator.context)
let ctxPath = URL(fileURLWithPath: "/path/to/gregorian.ctx")
try data.write(to: ctxPath, options: .atomic)

// [...]

// Deserialize context
let data = try Data(contentsOf: ctxPath)
let deserializedCtx = try JSONDecoder().decode(GregorianCalculator.Context.self, from: data)
let newCalculator = GregorianCalculator()
newCalculator.initialize(with: deserializedCtx)
// -> `newCalculator` will now have cached values for the dates calculated above. So the following calls will use the cached values instead of recalculating them.
let cachedEasterSunday20 = calculator.easterSunday(forYear: 2020)
// -> 2020-04-12
let cachedFirstAdvent19 = calculator.firstSundayOfAdvent(forYear: 2019)
// -> 2019-12-01
let cachedFirstAdvent20 = calculator.firstSundayOfAdvent(forYear: 2020)
// -> 2020-11-29

Note that all calculations return a TimelessDate - a date without a time component to it. This isn't a general purpose timeless date. It simply removes the time zone problem from the calculations. This is also the reason why the calendar: Foundation.Calendar of a calculator always has its timezone set to UTC (0 seconds from GMT). Once you use the results of calculations, you should use Foundation.Date and Foundation.DateComponents again. This is fairly easy since you can always ask a TimelessDate for its components (which will return the matching DateComponents) or ask a calculator to return a Date for a given TimelessDate (which will use the calculators calendar to create a Date from the TimelessDate).

Documentation

The API is documented using header doc. If you prefer to view the documentation as a webpage, there is an online version available for you.

Contributing

If you find a bug / like to see a new feature there are a few ways of helping out:

  • If you can fix the bug / implement the feature yourself please do and open a PR.
  • If you know how to code (which you probably do), please add a (failing) test and open a PR. We'll try to get your test green ASAP.
  • If you can do neither, then open an issue. While this might be the easiest way, it will likely take the longest for the bug to be fixed / feature to be implemented.

License

See LICENSE file.

swifty-holidays's People

Contributors

dependabot[bot] avatar ffried avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.