func IsFrameInTimespan(frame Frame, start time.Time, end time.Time) bool {
	return IsTimeInTimespan(frame.StartedAt, start, end) || IsTimeInTimespan(frame.EndedAt, start, end)
}
IsFrameInTimespan checks if a frame's start OR end time are in the given timespan
package chronolib
import (
	"github.com/SaidinWoT/timespan"
	"github.com/jinzhu/now"
	jww "github.com/spf13/jwalterweatherman"
	"time"
)
func ExtendTimeFormats() {
	now.TimeFormats = append(now.TimeFormats, "02/01/2006 15:04")  
}
func GetTimeElapsedForDuration(delta time.Duration) (int, int, int) {
	hours := int(delta.Hours())
	minutes := int(delta.Minutes()) - (hours * 60)
	seconds := int(delta.Seconds()) - (hours * 60 * 60) - (minutes * 60)
	return hours, minutes, seconds
}
func GetTimeElapsed(dateStart, dateEnd time.Time) (int, int, int) {
	delta := dateEnd.Sub(dateStart)
	return GetTimeElapsedForDuration(delta)
}
func IsTimespanNegative(start time.Time, end time.Time) bool {
	return end.Sub(start) < 0
}
func NormalizeDate(precise time.Time) time.Time {
	return time.Date(precise.Year(), precise.Month(), precise.Day(), 0, 0, 0, 0, precise.Location())
}
func SanitizeUserInput(date string, format string) (time.Time) {
	parsed, err := time.Parse(format, date)
	if err != nil {
		jww.ERROR.Printf("couldn't parse specified date (%s), using default instead [err: %s]", date, err)
		return time.Now()
	}
	return parsed
}
func GetTimespanForToday() (time.Time, time.Time) {
	return now.BeginningOfDay(), now.EndOfDay()
}
func GetTimespanForWeek(date string) (time.Time, time.Time) {
	parsed := SanitizeUserInput(date, "2006-01-02")
	return now.With(parsed).BeginningOfWeek(), now.With(parsed).EndOfWeek()
}
func GetTimespanForMonth(month string) (time.Time, time.Time) {
	parsed := SanitizeUserInput(month, "2006-01")
	return now.With(parsed).BeginningOfMonth(), now.With(parsed).EndOfMonth()
}
func GetTimespanForDay(day string) (time.Time, time.Time) {
	parsed := SanitizeUserInput(day, "2006-01-02")
	return now.With(parsed).BeginningOfDay(), now.With(parsed).EndOfDay()
}
func GetTimespanForYear(year string) (time.Time, time.Time) {
	parsed := SanitizeUserInput(year, "2006")
	return now.With(parsed).BeginningOfYear(), now.With(parsed).EndOfYear()
}
func IsTimeInTimespan(point time.Time, start time.Time, end time.Time) bool {
	duration := end.Sub(start)
	ts := timespan.New(start, duration)
	return ts.ContainsTime(point)
}
func HasSameDate(t1 *time.Time, t2 *time.Time) bool {
	if t1.Day() == t2.Day() && t1.Year() == t2.Year() && t1.Month() == t2.Month() {
		return true
	}
	return false
}
func FilterFrames(frames *[]Frame, filterOptions FrameFilterOptions) []Frame {
	var filteredFrames = []Frame{}
	var validFrame bool
	var useTags = len(filterOptions.Tags) != 0
	var useProjects = len(filterOptions.Projects) != 0
	var noTimespanCheck = filterOptions.TimespanFilter == TimespanFilterOptions{}
	var start = filterOptions.TimespanFilter.Start
	var end = filterOptions.TimespanFilter.End
	jww.DEBUG.Printf("FilterFrames start: %s", filterOptions.TimespanFilter.Start)
	jww.DEBUG.Printf("FilterFrames end: %s", filterOptions.TimespanFilter.End)
	for _, frame := range *frames {
		if IsFrameInTimespan(frame, start, end) || noTimespanCheck {
			validFrame = true
			if !IsWholeFrameInTimespan(frame, start, end) {
				frame = SubFrameForTimespan(frame, start, end)
			}
			if useTags {
				for _, tag := range filterOptions.Tags {
					if !StringInSlice(tag, frame.Tags) {
						validFrame = false
						break
					}
				}
			}
			if useProjects {
				if !StringInSlice(frame.Project, filterOptions.Projects) {
					validFrame = false
				}
			}
			if validFrame {
				filteredFrames = append(filteredFrames, frame)
			}
		}
	}
	return filteredFrames
}
func OrganizeFrameByTime(frames *[]Frame) map[time.Time][]Frame {
	frameMap := make(map[time.Time][]Frame)
	for _, frame := range *frames {
		date := NormalizeDate(frame.StartedAt)
		frameMap[date] = append(frameMap[date], frame)
	}
	return frameMap
}
func SubFrameForTimespan(frame Frame, start time.Time, end time.Time) Frame {
	newFrame := frame
	if !IsTimeInTimespan(frame.StartedAt, start, end) {
		newFrame.StartedAt = start
	}
	if !IsTimeInTimespan(frame.EndedAt, start, end) {
		newFrame.EndedAt = end
	}
	return newFrame
}
func IsWholeFrameInTimespan(frame Frame, start time.Time, end time.Time) bool {
	if !IsTimeInTimespan(frame.StartedAt, start, end) {
		return false
	}
	if !IsTimeInTimespan(frame.EndedAt, start, end) {
		return false
	}
	return true
}