func (c *Carbon) AddMonthsNoOverflow(m int) *Carbon {
	addedDate := NewCarbon(c.AddDate(0, m, 0))
	if c.Day() != addedDate.Day() {
		return addedDate.PreviousMonthLastDay()
	}
	return addedDate
}
AddMonthsNoOverflow adds a month to the current time, not overflowing in case the
destination month has less days than the current one.
Positive value travels forward while negative value travels into the past.
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)
}