package now

import (
	
	
	
)

// BeginningOfMinute beginning of minute
func ( *Now) () time.Time {
	return .Truncate(time.Minute)
}

// BeginningOfHour beginning of hour
func ( *Now) () time.Time {
	, ,  := .Date()
	return time.Date(, , , .Time.Hour(), 0, 0, 0, .Time.Location())
}

// BeginningOfDay beginning of day
func ( *Now) () time.Time {
	, ,  := .Date()
	return time.Date(, , , 0, 0, 0, 0, .Time.Location())
}

// BeginningOfWeek beginning of week
func ( *Now) () time.Time {
	 := .BeginningOfDay()
	 := int(.Weekday())

	if .WeekStartDay != time.Sunday {
		 := int(.WeekStartDay)

		if  <  {
			 =  + 7 - 
		} else {
			 =  - 
		}
	}
	return .AddDate(0, 0, -)
}

// BeginningOfMonth beginning of month
func ( *Now) () time.Time {
	, ,  := .Date()
	return time.Date(, , 1, 0, 0, 0, 0, .Location())
}

// BeginningOfQuarter beginning of quarter
func ( *Now) () time.Time {
	 := .BeginningOfMonth()
	 := (int(.Month()) - 1) % 3
	return .AddDate(0, -, 0)
}

// BeginningOfHalf beginning of half year
func ( *Now) () time.Time {
	 := .BeginningOfMonth()
	 := (int(.Month()) - 1) % 6
	return .AddDate(0, -, 0)
}

// BeginningOfYear BeginningOfYear beginning of year
func ( *Now) () time.Time {
	, ,  := .Date()
	return time.Date(, time.January, 1, 0, 0, 0, 0, .Location())
}

// EndOfMinute end of minute
func ( *Now) () time.Time {
	return .BeginningOfMinute().Add(time.Minute - time.Nanosecond)
}

// EndOfHour end of hour
func ( *Now) () time.Time {
	return .BeginningOfHour().Add(time.Hour - time.Nanosecond)
}

// EndOfDay end of day
func ( *Now) () time.Time {
	, ,  := .Date()
	return time.Date(, , , 23, 59, 59, int(time.Second-time.Nanosecond), .Location())
}

// EndOfWeek end of week
func ( *Now) () time.Time {
	return .BeginningOfWeek().AddDate(0, 0, 7).Add(-time.Nanosecond)
}

// EndOfMonth end of month
func ( *Now) () time.Time {
	return .BeginningOfMonth().AddDate(0, 1, 0).Add(-time.Nanosecond)
}

// EndOfQuarter end of quarter
func ( *Now) () time.Time {
	return .BeginningOfQuarter().AddDate(0, 3, 0).Add(-time.Nanosecond)
}

// EndOfHalf end of half year
func ( *Now) () time.Time {
	return .BeginningOfHalf().AddDate(0, 6, 0).Add(-time.Nanosecond)
}

// EndOfYear end of year
func ( *Now) () time.Time {
	return .BeginningOfYear().AddDate(1, 0, 0).Add(-time.Nanosecond)
}

// Monday monday
/*
func (now *Now) Monday() time.Time {
	t := now.BeginningOfDay()
	weekday := int(t.Weekday())
	if weekday == 0 {
		weekday = 7
	}
	return t.AddDate(0, 0, -weekday+1)
}
*/

func ( *Now) ( ...string) time.Time {
	var  time.Time
	var  error
	if len() > 0 {
		,  = .Parse(...)
		if  != nil {
			panic()
		}
	} else {
		 = .BeginningOfDay()
	}
	 := int(.Weekday())
	if  == 0 {
		 = 7
	}
	return .AddDate(0, 0, -+1)
}

func ( *Now) ( ...string) time.Time {
	var  time.Time
	var  error
	if len() > 0 {
		,  = .Parse(...)
		if  != nil {
			panic()
		}
	} else {
		 = .BeginningOfDay()
	}
	 := int(.Weekday())
	if  == 0 {
		 = 7
	}
	return .AddDate(0, 0, (7 - ))
}

// EndOfSunday end of sunday
func ( *Now) () time.Time {
	return New(.Sunday()).EndOfDay()
}

// Quarter returns the yearly quarter
func ( *Now) () uint {
	return (uint(.Month())-1)/3 + 1
}

func ( *Now) ( string,  *time.Location) ( time.Time,  error) {
	for ,  := range .TimeFormats {
		,  = time.ParseInLocation(, , )

		if  == nil {
			return
		}
	}
	 = errors.New("Can't parse string as time: " + )
	return
}

var hasTimeRegexp = regexp.MustCompile(`(\s+|^\s*|T)\d{1,2}((:\d{1,2})*|((:\d{1,2}){2}\.(\d{3}|\d{6}|\d{9})))(\s*$|[Z+-])`) // match 15:04:05, 15:04:05.000, 15:04:05.000000 15, 2017-01-01 15:04, 2021-07-20T00:59:10Z, 2021-07-20T00:59:10+08:00, 2021-07-20T00:00:10-07:00 etc
var onlyTimeRegexp = regexp.MustCompile(`^\s*\d{1,2}((:\d{1,2})*|((:\d{1,2}){2}\.(\d{3}|\d{6}|\d{9})))\s*$`)            // match 15:04:05, 15, 15:04:05.000, 15:04:05.000000, etc

// Parse parse string to time
func ( *Now) ( ...string) ( time.Time,  error) {
	var (
		  bool
		       []int
		 = .Location()
		   = true
		     = formatTimeToList(.Time)
	)

	for ,  := range  {
		 := hasTimeRegexp.MatchString() // match 15:04:05, 15
		 =  &&  && onlyTimeRegexp.MatchString()
		if ,  = .parseWithFormat(, );  == nil {
			 := .Location()
			 = formatTimeToList()

			for ,  := range  {
				// Don't reset hour, minute, second if current time str including time
				if  &&  <= 3 {
					continue
				}

				// If value is zero, replace it with current time
				if  == 0 {
					if  {
						[] = []
					}
				} else {
					 = true
				}

				// if current time only includes time, should change day, month to current time
				if  {
					if  == 4 ||  == 5 {
						[] = []
						continue
					}
				}
			}

			 = time.Date([6], time.Month([5]), [4], [3], [2], [1], [0], )
			 = formatTimeToList()
		}
	}
	return
}

// MustParse must parse string to time or it will panic
func ( *Now) ( ...string) ( time.Time) {
	,  := .Parse(...)
	if  != nil {
		panic()
	}
	return 
}

// Between check time between the begin, end time or not
func ( *Now) (,  string) bool {
	 := .MustParse()
	 := .MustParse()
	return .After() && .Before()
}