func (c *Carbon) IsSunday() bool {
	return c.Weekday() == time.Sunday
}
IsSunday checks if this day is a Sunday.
package carbon
import (
	"errors"
	"math"
	"strings"
	"time"
)
const (
	secondsPerMinute  = 60
	minutesPerHour    = 60
	hoursPerDay       = 24
	daysPerWeek       = 7
	monthsPerQuarter  = 3
	monthsPerYear     = 12
	yearsPerCenturies = 100
	yearsPerDecade    = 10
	weeksPerLongYear  = 53
	daysInLeapYear    = 366
	daysInNormalYear  = 365
	secondsInWeek     = 691200
)
const (
	DefaultFormat       = "2006-01-02 15:04:05"
	DateFormat          = "2006-01-02"
	FormattedDateFormat = "Jan 2, 2006"
	TimeFormat          = "15:04:05"
	HourMinuteFormat    = "15:04"
	HourFormat          = "15"
	DayDateTimeFormat   = "Mon, Aug 2, 2006 3:04 PM"
	CookieFormat        = "Monday, 02-Jan-2006 15:04:05 MST"
	RFC822Format        = "Mon, 02 Jan 06 15:04:05 -0700"
	RFC1036Format       = "Mon, 02 Jan 06 15:04:05 -0700"
	RFC2822Format       = "Mon, 02 Jan 2006 15:04:05 -0700"
	RFC3339Format       = "2006-01-02T15:04:05-07:00"
	RSSFormat           = "Mon, 02 Jan 2006 15:04:05 -0700"
)
type Carbon struct {
	time.Time
	weekStartsAt time.Weekday
	weekEndsAt   time.Weekday
	weekendDays  []time.Weekday
	stringFormat string
	Translator   *Translator
}
var (
	isTimeFrozen      bool
	currentFrozenTime time.Time
)
func NewCarbon(t time.Time) *Carbon {
	wds := []time.Weekday{
		time.Saturday,
		time.Sunday,
	}
	return &Carbon{
		Time:         t,
		weekStartsAt: time.Monday,
		weekEndsAt:   time.Sunday,
		weekendDays:  wds,
		stringFormat: DefaultFormat,
		Translator:   translator(),
	}
}
func Freeze(time time.Time) {
	currentFrozenTime = time
	isTimeFrozen = true
}
func UnFreeze() {
	isTimeFrozen = false
}
func IsTimeFrozen() bool {
	return isTimeFrozen
}
func After(d time.Duration) <-chan time.Time {
	if isTimeFrozen {
		currentFrozenTime = currentFrozenTime.Add(d)
		c := make(chan time.Time, 1)
		c <- currentFrozenTime
		return c
	}
	return time.After(d)
}
func Tick(d time.Duration) <-chan time.Time {
	if isTimeFrozen {
		c := make(chan time.Time, 1)
		go func() {
			for {
				currentFrozenTime = currentFrozenTime.Add(d)
				c <- currentFrozenTime
			}
		}()
		return c
	}
	return time.Tick(d)
}
func Sleep(d time.Duration) {
	if isTimeFrozen && d > 0 {
		currentFrozenTime = currentFrozenTime.Add(d)
		return
	}
	time.Sleep(d)
}
func create(y int, mon time.Month, d, h, m, s, ns int, l *time.Location) *Carbon {
	return NewCarbon(time.Date(y, mon, d, h, m, s, ns, l))
}
func Create(y int, mon time.Month, d, h, m, s, ns int, location string) (*Carbon, error) {
	l, err := time.LoadLocation(location)
	if err != nil {
		return nil, err
	}
	return create(y, mon, d, h, m, s, ns, l), nil
}
func CreateFromDate(y int, mon time.Month, d int, location string) (*Carbon, error) {
	h, m, s := Now().Clock()
	ns := Now().Nanosecond()
	return Create(y, mon, d, h, m, s, ns, location)
}
func CreateFromTime(h, m, s, ns int, location string) (*Carbon, error) {
	y, mon, d := Now().Date()
	return Create(y, mon, d, h, m, s, ns, location)
}
func CreateFromFormat(layout, value string, location string) (*Carbon, error) {
	l, err := time.LoadLocation(location)
	if err != nil {
		return nil, err
	}
	t, err := time.ParseInLocation(layout, value, l)
	if err != nil {
		return nil, err
	}
	return NewCarbon(t), nil
}
func CreateFromTimestamp(timestamp int64, location string) (*Carbon, error) {
	l, err := time.LoadLocation(location)
	if err != nil {
		return nil, err
	}
	t := NewCarbon(Now().In(l))
	t.SetTimestamp(timestamp)
	return t, nil
}
func CreateFromTimestampUTC(timestamp int64) (*Carbon, error) {
	return CreateFromTimestamp(timestamp, "UTC")
}
func CreateFromMonthAndYear(y int, mon time.Month, location string) (*Carbon, error) {
	_, _, d := Now().Date()
	h, m, s := Now().Clock()
	ns := Now().Nanosecond()
	return Create(y, mon, d, h, m, s, ns, location)
}
func Parse(layout, value, location string) (*Carbon, error) {
	l, err := time.LoadLocation(location)
	if err != nil {
		return nil, err
	}
	t, err := time.ParseInLocation(layout, value, l)
	if err != nil {
		return nil, err
	}
	return NewCarbon(t), nil
}
func Today(location string) (*Carbon, error) {
	l, err := time.LoadLocation(location)
	if err != nil {
		return nil, err
	}
	return NewCarbon(Now().In(l)), err
}
func Tomorrow(location string) (*Carbon, error) {
	c, err := Today(location)
	if err != nil {
		return nil, err
	}
	return c.AddDay(), nil
}
func Yesterday(location string) (*Carbon, error) {
	c, err := Today(location)
	if err != nil {
		return nil, err
	}
	return c.SubDay(), nil
}
const unixTimeInSeconds = 62135596801
const maxNSecs = 999999999
func MaxValue() *Carbon {
	return NewCarbon(time.Unix(math.MaxInt64-unixTimeInSeconds, maxNSecs))
}
func MinValue() *Carbon {
	return NewCarbon(time.Unix(math.MinInt64+unixTimeInSeconds, 0))
}
func Now() *Carbon {
	if isTimeFrozen {
		return NewCarbon(currentFrozenTime)
	}
	return NewCarbon(time.Now())
}
func NowInLocation(loc string) (*Carbon, error) {
	l, err := time.LoadLocation(loc)
	if err != nil {
		return nil, err
	}
	return nowIn(l), nil
}
func nowIn(loc *time.Location) *Carbon {
	return NewCarbon(Now().In(loc))
}
func (c *Carbon) Copy() *Carbon {
	return create(c.Year(), c.Month(), c.Day(), c.Hour(), c.Minute(), c.Second(), c.Nanosecond(), c.Location())
}
func (c *Carbon) WeekStartsAt() time.Weekday {
	return c.weekStartsAt
}
func (c *Carbon) WeekEndsAt() time.Weekday {
	return c.weekEndsAt
}
func (c *Carbon) WeekendDays() []time.Weekday {
	return c.weekendDays
}
func (c *Carbon) Quarter() int {
	month := c.Month()
	switch {
	case month < 4:
		return 1
	case month >= 4 && month < 7:
		return 2
	case month >= 7 && month < 10:
		return 3
	}
	return 4
}
func (c *Carbon) Age() int {
	return int(c.DiffInYears(Now(), true))
}
func (c *Carbon) DaysInMonth() int {
	return c.EndOfMonth().Day()
}
func (c *Carbon) DaysInYear() int {
	if c.IsLeapYear() {
		return daysInLeapYear
	}
	return daysInNormalYear
}
func (c *Carbon) WeekOfMonth() int {
	w := math.Ceil(float64(c.Day() / daysPerWeek))
	return int(w + 1)
}
func (c *Carbon) WeekOfYear() (int, int) {
	return c.ISOWeek()
}
func (c *Carbon) TimeZone() string {
	return c.Location().String()
}
func (c *Carbon) Timestamp() int64 {
	return c.Unix()
}
func (c *Carbon) String() string {
	return c.Format(c.stringFormat)
}
func (c *Carbon) AddYears(y int) *Carbon {
	return NewCarbon(c.AddDate(y, 0, 0))
}
func (c *Carbon) AddYear() *Carbon {
	return c.AddYears(1)
}
func (c *Carbon) AddQuarters(q int) *Carbon {
	return NewCarbon(c.AddDate(0, monthsPerQuarter*q, 0))
}
func (c *Carbon) AddQuarter() *Carbon {
	return c.AddQuarters(1)
}
func (c *Carbon) AddCenturies(cent int) *Carbon {
	return NewCarbon(c.AddDate(yearsPerCenturies*cent, 0, 0))
}
func (c *Carbon) AddCentury() *Carbon {
	return c.AddCenturies(1)
}
func (c *Carbon) AddMonths(m int) *Carbon {
	return NewCarbon(c.AddDate(0, m, 0))
}
func (c *Carbon) AddMonth() *Carbon {
	return c.AddMonths(1)
}
func (c *Carbon) AddSeconds(s int) *Carbon {
	d := time.Duration(s) * time.Second
	return NewCarbon(c.Add(d))
}
func (c *Carbon) AddSecond() *Carbon {
	return c.AddSeconds(1)
}
func (c *Carbon) AddDays(d int) *Carbon {
	return NewCarbon(c.AddDate(0, 0, d))
}
func (c *Carbon) AddDay() *Carbon {
	return c.AddDays(1)
}
func (c *Carbon) AddWeekdays(wd int) *Carbon {
	d := 1
	if wd < 0 {
		wd, d = -wd, -d
	}
	t := c.Copy()
	for wd > 0 {
		t = t.AddDays(d)
		if t.IsWeekday() {
			wd--
		}
	}
	return t
}
func (c *Carbon) AddWeekday() *Carbon {
	return c.AddWeekdays(1)
}
func (c *Carbon) AddWeeks(w int) *Carbon {
	return NewCarbon(c.AddDate(0, 0, daysPerWeek*w))
}
func (c *Carbon) AddWeek() *Carbon {
	return c.AddWeeks(1)
}
func (c *Carbon) AddHours(h int) *Carbon {
	d := time.Duration(h) * time.Hour
	return NewCarbon(c.Add(d))
}
func (c *Carbon) AddHour() *Carbon {
	return c.AddHours(1)
}
func (c *Carbon) AddMonthsNoOverflow(m int) *Carbon {
	addedDate := NewCarbon(c.AddDate(0, m, 0))
	if c.Day() != addedDate.Day() {
		return addedDate.PreviousMonthLastDay()
	}
	return addedDate
}
func (c *Carbon) PreviousMonthLastDay() *Carbon {
	return NewCarbon(c.AddDate(0, 0, -c.Day()))
}
func (c *Carbon) AddMonthNoOverflow() *Carbon {
	return c.AddMonthsNoOverflow(1)
}
func (c *Carbon) AddMinutes(m int) *Carbon {
	d := time.Duration(m) * time.Minute
	return NewCarbon(c.Add(d))
}
func (c *Carbon) AddMinute() *Carbon {
	return c.AddMinutes(1)
}
func (c *Carbon) SubYear() *Carbon {
	return c.SubYears(1)
}
func (c *Carbon) SubYears(y int) *Carbon {
	return c.AddYears(-1 * y)
}
func (c *Carbon) SubQuarter() *Carbon {
	return c.SubQuarters(1)
}
func (c *Carbon) SubQuarters(q int) *Carbon {
	return c.AddQuarters(-q)
}
func (c *Carbon) SubCentury() *Carbon {
	return c.SubCenturies(1)
}
func (c *Carbon) SubCenturies(cent int) *Carbon {
	return c.AddCenturies(-cent)
}
func (c *Carbon) SubMonth() *Carbon {
	return c.SubMonths(1)
}
func (c *Carbon) SubMonths(m int) *Carbon {
	return c.AddMonths(-m)
}
func (c *Carbon) SubMonthNoOverflow() *Carbon {
	return c.SubMonthsNoOverflow(1)
}
func (c *Carbon) SubMonthsNoOverflow(m int) *Carbon {
	return c.AddMonthsNoOverflow(-m)
}
func (c *Carbon) SubDay() *Carbon {
	return c.SubDays(1)
}
func (c *Carbon) SubDays(d int) *Carbon {
	return c.AddDays(-d)
}
func (c *Carbon) SubWeekday() *Carbon {
	return c.SubWeekdays(1)
}
func (c *Carbon) SubWeekdays(wd int) *Carbon {
	return c.AddWeekdays(-wd)
}
func (c *Carbon) SubWeek() *Carbon {
	return c.SubWeeks(1)
}
func (c *Carbon) SubWeeks(w int) *Carbon {
	return c.AddWeeks(-w)
}
func (c *Carbon) SubHour() *Carbon {
	return c.SubHours(1)
}
func (c *Carbon) SubHours(h int) *Carbon {
	return c.AddHours(-h)
}
func (c *Carbon) SubMinute() *Carbon {
	return c.SubMinutes(1)
}
func (c *Carbon) SubMinutes(m int) *Carbon {
	return c.AddMinutes(-m)
}
func (c *Carbon) SubSecond() *Carbon {
	return c.SubSeconds(1)
}
func (c *Carbon) SubSeconds(s int) *Carbon {
	return c.AddSeconds(-s)
}
func (c *Carbon) SetYear(y int) {
	c.Time = time.Date(y, c.Month(), c.Day(), c.Hour(), c.Minute(), c.Second(), c.Nanosecond(), c.Location())
}
func (c *Carbon) SetMonth(m time.Month) {
	c.Time = time.Date(c.Year(), m, c.Day(), c.Hour(), c.Minute(), c.Second(), c.Nanosecond(), c.Location())
}
func (c *Carbon) SetDay(d int) {
	c.Time = time.Date(c.Year(), c.Month(), d, c.Hour(), c.Minute(), c.Second(), c.Nanosecond(), c.Location())
}
func (c *Carbon) SetHour(h int) {
	c.Time = time.Date(c.Year(), c.Month(), c.Day(), h, c.Minute(), c.Second(), c.Nanosecond(), c.Location())
}
func (c *Carbon) SetMinute(m int) {
	c.Time = time.Date(c.Year(), c.Month(), c.Day(), c.Hour(), m, c.Second(), c.Nanosecond(), c.Location())
}
func (c *Carbon) SetSecond(s int) {
	c.Time = time.Date(c.Year(), c.Month(), c.Day(), c.Hour(), c.Minute(), s, c.Nanosecond(), c.Location())
}
func (c *Carbon) SetDate(y int, m time.Month, d int) {
	c.Time = time.Date(y, m, d, c.Hour(), c.Minute(), c.Second(), c.Nanosecond(), c.Location())
}
func (c *Carbon) SetDateTime(y int, mon time.Month, d, h, m, s int) {
	c.Time = time.Date(y, mon, d, h, m, s, c.Nanosecond(), c.Location())
}
func (c *Carbon) SetTimeFromTimeString(timeString string) error {
	layouts := []string{
		TimeFormat,
		HourMinuteFormat,
		HourFormat,
	}
	var t time.Time
	var err error
	for i, layout := range layouts {
		t, err = time.Parse(layout, timeString)
		if err == nil {
			h, m, s := t.Clock()
			switch i {
			case 1:
				s = c.Second()
			case 2:
				m, s = c.Minute(), c.Second()
			}
			c.SetHour(h)
			c.SetMinute(m)
			c.SetSecond(s)
			return nil
		}
	}
	return errors.New("only supports hh:mm:ss, hh:mm and hh formats")
}
func (c *Carbon) SetWeekEndsAt(wd time.Weekday) {
	c.weekEndsAt = wd
}
func (c *Carbon) SetWeekStartsAt(wd time.Weekday) {
	c.weekStartsAt = wd
}
func (c *Carbon) SetWeekendDays(wds []time.Weekday) {
	c.weekendDays = wds
}
func (c *Carbon) SetTimestamp(sec int64) {
	c.Time = time.Unix(sec, 0).In(c.Location())
}
func (c *Carbon) SetTimeZone(name string) error {
	loc, err := time.LoadLocation(name)
	if err != nil {
		return err
	}
	c.Time = time.Date(c.Year(), c.Month(), c.Day(), c.Hour(), c.Minute(), c.Second(), c.Nanosecond(), loc)
	return nil
}
func (c *Carbon) ResetStringFormat() {
	c.stringFormat = DefaultFormat
}
func (c *Carbon) SetStringFormat(format string) {
	c.stringFormat = format
}
func (c *Carbon) DateString() string {
	return c.Format(DateFormat)
}
func (c *Carbon) FormattedDateString() string {
	return c.Format(FormattedDateFormat)
}
func (c *Carbon) TimeString() string {
	return c.Format(TimeFormat)
}
func (c *Carbon) DateTimeString() string {
	return c.Format(DefaultFormat)
}
func (c *Carbon) DayDateTimeString() string {
	return c.Format(DayDateTimeFormat)
}
func (c *Carbon) AtomString() string {
	return c.Format(RFC3339Format)
}
func (c *Carbon) CookieString() string {
	return c.Format(CookieFormat)
}
func (c *Carbon) ISO8601String() string {
	return c.Format(RFC3339Format)
}
func (c *Carbon) RFC822String() string {
	return c.Format(RFC822Format)
}
func (c *Carbon) RFC850String() string {
	return c.Format(time.RFC850)
}
func (c *Carbon) RFC1036String() string {
	return c.Format(RFC1036Format)
}
func (c *Carbon) RFC1123String() string {
	return c.Format(time.RFC1123Z)
}
func (c *Carbon) RFC2822String() string {
	return c.Format(RFC2822Format)
}
func (c *Carbon) RFC3339String() string {
	return c.Format(RFC3339Format)
}
func (c *Carbon) RSSString() string {
	return c.Format(RSSFormat)
}
func (c *Carbon) W3CString() string {
	return c.Format(RFC3339Format)
}
func (c *Carbon) IsWeekday() bool {
	return !c.IsWeekend()
}
func (c *Carbon) IsWeekend() bool {
	d := c.Weekday()
	for _, wd := range c.WeekendDays() {
		if d == wd {
			return true
		}
	}
	return false
}
func (c *Carbon) IsYesterday() bool {
	n := Now().SubDay()
	return c.IsSameDay(n)
}
func (c *Carbon) IsToday() bool {
	return c.IsSameDay(Now())
}
func (c *Carbon) IsTomorrow() bool {
	n := Now().AddDay()
	return c.IsSameDay(n)
}
func (c *Carbon) IsFuture() bool {
	return c.After(Now().Time)
}
func (c *Carbon) IsPast() bool {
	return c.Before(Now().Time)
}
func (c *Carbon) IsLeapYear() bool {
	y := c.Year()
	if (y%4 == 0 && y%100 != 0) || y%400 == 0 {
		return true
	}
	return false
}
func (c *Carbon) IsLongYear() bool {
	carb := create(c.Year(), time.December, 31, 0, 0, 0, 0, c.Location())
	_, w := carb.WeekOfYear()
	return w == weeksPerLongYear
}
func (c *Carbon) IsSameAs(format string, carb *Carbon) bool {
	if carb == nil {
		return c.Format(DefaultFormat) == Now().Format(DefaultFormat)
	}
	return c.Format(DefaultFormat) == carb.Format(DefaultFormat)
}
func (c *Carbon) IsCurrentYear() bool {
	return c.Year() == Now().Year()
}
func (c *Carbon) IsSameYear(carb *Carbon) bool {
	if carb == nil {
		return c.Year() == nowIn(c.Location()).Year()
	}
	return c.Year() == carb.Year()
}
func (c *Carbon) IsCurrentMonth() bool {
	return c.Month() == Now().Month()
}
func (c *Carbon) IsSameMonth(carb *Carbon, sameYear bool) bool {
	m := nowIn(c.Location()).Month()
	if carb != nil {
		m = carb.Month()
	}
	if sameYear {
		return c.IsSameYear(carb) && c.Month() == m
	}
	return c.Month() == m
}
func (c *Carbon) IsSameDay(carb *Carbon) bool {
	n := nowIn(c.Location())
	if carb != nil {
		n = carb
	}
	return c.Year() == n.Year() && c.Month() == n.Month() && c.Day() == n.Day()
}