date.go raw

   1  // Copyright 2016 Qiang Xue. All rights reserved.
   2  // Use of this source code is governed by a MIT-style
   3  // license that can be found in the LICENSE file.
   4  
   5  package validation
   6  
   7  import (
   8  	"time"
   9  )
  10  
  11  var (
  12  	// ErrDateInvalid is the error that returns in case of an invalid date.
  13  	ErrDateInvalid = NewError("validation_date_invalid", "must be a valid date")
  14  	// ErrDateOutOfRange is the error that returns in case of an invalid date.
  15  	ErrDateOutOfRange = NewError("validation_date_out_of_range", "the date is out of range")
  16  )
  17  
  18  // DateRule is a validation rule that validates date/time string values.
  19  type DateRule struct {
  20  	layout        string
  21  	min, max      time.Time
  22  	err, rangeErr Error
  23  }
  24  
  25  // Date returns a validation rule that checks if a string value is in a format that can be parsed into a date.
  26  // The format of the date should be specified as the layout parameter which accepts the same value as that for time.Parse.
  27  // For example,
  28  //    validation.Date(time.ANSIC)
  29  //    validation.Date("02 Jan 06 15:04 MST")
  30  //    validation.Date("2006-01-02")
  31  //
  32  // By calling Min() and/or Max(), you can let the Date rule to check if a parsed date value is within
  33  // the specified date range.
  34  //
  35  // An empty value is considered valid. Use the Required rule to make sure a value is not empty.
  36  func Date(layout string) DateRule {
  37  	return DateRule{
  38  		layout:   layout,
  39  		err:      ErrDateInvalid,
  40  		rangeErr: ErrDateOutOfRange,
  41  	}
  42  }
  43  
  44  // Error sets the error message that is used when the value being validated is not a valid date.
  45  func (r DateRule) Error(message string) DateRule {
  46  	r.err = r.err.SetMessage(message)
  47  	return r
  48  }
  49  
  50  // ErrorObject sets the error struct that is used when the value being validated is not a valid date..
  51  func (r DateRule) ErrorObject(err Error) DateRule {
  52  	r.err = err
  53  	return r
  54  }
  55  
  56  // RangeError sets the error message that is used when the value being validated is out of the specified Min/Max date range.
  57  func (r DateRule) RangeError(message string) DateRule {
  58  	r.rangeErr = r.rangeErr.SetMessage(message)
  59  	return r
  60  }
  61  
  62  // RangeErrorObject sets the error struct that is used when the value being validated is out of the specified Min/Max date range.
  63  func (r DateRule) RangeErrorObject(err Error) DateRule {
  64  	r.rangeErr = err
  65  	return r
  66  }
  67  
  68  // Min sets the minimum date range. A zero value means skipping the minimum range validation.
  69  func (r DateRule) Min(min time.Time) DateRule {
  70  	r.min = min
  71  	return r
  72  }
  73  
  74  // Max sets the maximum date range. A zero value means skipping the maximum range validation.
  75  func (r DateRule) Max(max time.Time) DateRule {
  76  	r.max = max
  77  	return r
  78  }
  79  
  80  // Validate checks if the given value is a valid date.
  81  func (r DateRule) Validate(value interface{}) error {
  82  	value, isNil := Indirect(value)
  83  	if isNil || IsEmpty(value) {
  84  		return nil
  85  	}
  86  
  87  	str, err := EnsureString(value)
  88  	if err != nil {
  89  		return err
  90  	}
  91  
  92  	date, err := time.Parse(r.layout, str)
  93  	if err != nil {
  94  		return r.err
  95  	}
  96  
  97  	if !r.min.IsZero() && r.min.After(date) || !r.max.IsZero() && date.After(r.max) {
  98  		return r.rangeErr
  99  	}
 100  
 101  	return nil
 102  }
 103