@@ -178,7 +178,7 @@ class Validator implements ValidatorContract
178178 protected $ dependentRules = [
179179 'RequiredWith ' , 'RequiredWithAll ' , 'RequiredWithout ' , 'RequiredWithoutAll ' ,
180180 'RequiredIf ' , 'RequiredUnless ' , 'Confirmed ' , 'Same ' , 'Different ' , 'Unique ' ,
181- 'Before ' , 'After ' ,
181+ 'Before ' , 'After ' , ' BeforeOrEqual ' , ' AfterOrEqual ' ,
182182 ];
183183
184184 /**
@@ -1853,34 +1853,22 @@ protected function validateBefore($attribute, $value, $parameters)
18531853 {
18541854 $ this ->requireParameterCount (1 , $ parameters , 'before ' );
18551855
1856- if (! is_string ($ value ) && ! is_numeric ($ value ) && ! $ value instanceof DateTimeInterface) {
1857- return false ;
1858- }
1859-
1860- if ($ format = $ this ->getDateFormat ($ attribute )) {
1861- return $ this ->validateBeforeWithFormat ($ format , $ value , $ parameters );
1862- }
1863-
1864- if (! $ date = $ this ->getDateTimestamp ($ parameters [0 ])) {
1865- $ date = $ this ->getDateTimestamp ($ this ->getValue ($ parameters [0 ]));
1866- }
1867-
1868- return $ this ->getDateTimestamp ($ value ) < $ date ;
1856+ return $ this ->compareDates ($ attribute , $ value , $ parameters , '< ' );
18691857 }
18701858
18711859 /**
1872- * Validate the date is before a given date with a given format .
1860+ * Validate the date is before or equal a given date .
18731861 *
1874- * @param string $format
1862+ * @param string $attribute
18751863 * @param mixed $value
18761864 * @param array $parameters
18771865 * @return bool
18781866 */
1879- protected function validateBeforeWithFormat ( $ format , $ value , $ parameters )
1867+ protected function validateBeforeOrEqual ( $ attribute , $ value , $ parameters )
18801868 {
1881- $ param = $ this ->getValue ( $ parameters [ 0 ]) ?: $ parameters[ 0 ] ;
1869+ $ this ->requireParameterCount ( 1 , $ parameters, ' before_or_equal ' ) ;
18821870
1883- return $ this ->checkDateTimeOrder ( $ format , $ value , $ param );
1871+ return $ this ->compareDates ( $ attribute , $ value , $ parameters , ' <= ' );
18841872 }
18851873
18861874 /**
@@ -1895,51 +1883,68 @@ protected function validateAfter($attribute, $value, $parameters)
18951883 {
18961884 $ this ->requireParameterCount (1 , $ parameters , 'after ' );
18971885
1886+ return $ this ->compareDates ($ attribute , $ value , $ parameters , '> ' );
1887+ }
1888+
1889+ /**
1890+ * Validate the date is equal or after a given date.
1891+ *
1892+ * @param string $attribute
1893+ * @param mixed $value
1894+ * @param array $parameters
1895+ * @return bool
1896+ */
1897+ protected function validateAfterOrEqual ($ attribute , $ value , $ parameters )
1898+ {
1899+ $ this ->requireParameterCount (1 , $ parameters , 'after_or_equal ' );
1900+
1901+ return $ this ->compareDates ($ attribute , $ value , $ parameters , '>= ' );
1902+ }
1903+
1904+ /**
1905+ * Compare a given date against another using an operator.
1906+ *
1907+ * @param string $attribute
1908+ * @param mixed $value
1909+ * @param array $parameters
1910+ * @param string $operator
1911+ * @return bool
1912+ */
1913+ protected function compareDates ($ attribute , $ value , $ parameters , $ operator )
1914+ {
18981915 if (! is_string ($ value ) && ! is_numeric ($ value ) && ! $ value instanceof DateTimeInterface) {
18991916 return false ;
19001917 }
19011918
19021919 if ($ format = $ this ->getDateFormat ($ attribute )) {
1903- return $ this ->validateAfterWithFormat ($ format , $ value , $ parameters );
1920+ $ param = $ this ->getValue ($ parameters [0 ]) ?: $ parameters [0 ];
1921+
1922+ return $ this ->checkDateTimeOrder ($ format , $ value , $ param , $ operator );
19041923 }
19051924
19061925 if (! $ date = $ this ->getDateTimestamp ($ parameters [0 ])) {
19071926 $ date = $ this ->getDateTimestamp ($ this ->getValue ($ parameters [0 ]));
19081927 }
19091928
1910- return $ this ->getDateTimestamp ($ value ) > $ date ;
1911- }
1912-
1913- /**
1914- * Validate the date is after a given date with a given format.
1915- *
1916- * @param string $format
1917- * @param mixed $value
1918- * @param array $parameters
1919- * @return bool
1920- */
1921- protected function validateAfterWithFormat ($ format , $ value , $ parameters )
1922- {
1923- $ param = $ this ->getValue ($ parameters [0 ]) ?: $ parameters [0 ];
1924-
1925- return $ this ->checkDateTimeOrder ($ format , $ param , $ value );
1929+ return $ this ->compare ($ this ->getDateTimestamp ($ value ), $ date , $ operator );
19261930 }
19271931
19281932 /**
19291933 * Given two date/time strings, check that one is after the other.
19301934 *
19311935 * @param string $format
1932- * @param string $before
1933- * @param string $after
1936+ * @param string $first
1937+ * @param string $second
1938+ * @param string $operator
19341939 * @return bool
19351940 */
1936- protected function checkDateTimeOrder ($ format , $ before , $ after )
1941+ protected function checkDateTimeOrder ($ format , $ first , $ second , $ operator )
19371942 {
1938- $ before = $ this ->getDateTimeWithOptionalFormat ($ format , $ before );
1943+ $ first = $ this ->getDateTimeWithOptionalFormat ($ format , $ first );
19391944
1940- $ after = $ this ->getDateTimeWithOptionalFormat ($ format , $ after );
1945+ $ second = $ this ->getDateTimeWithOptionalFormat ($ format , $ second );
19411946
1942- return ($ before && $ after ) && ($ after > $ before );
1947+ return ($ first && $ second ) && ($ this -> compare ( $ first , $ second , $ operator ) );
19431948 }
19441949
19451950 /**
@@ -3340,6 +3345,34 @@ protected function requireParameterCount($count, $parameters, $rule)
33403345 }
33413346 }
33423347
3348+ /**
3349+ * Determine if a comparison passes between the given values.
3350+ *
3351+ * @param mixed $first
3352+ * @param mixed $second
3353+ * @param string $operator
3354+ * @return bool
3355+ */
3356+ protected function compare ($ first , $ second , $ operator )
3357+ {
3358+ switch ($ operator ) {
3359+ case '< ' :
3360+ return $ first < $ second ;
3361+ break ;
3362+ case '> ' :
3363+ return $ first > $ second ;
3364+ break ;
3365+ case '<= ' :
3366+ return $ first <= $ second ;
3367+ break ;
3368+ case '>= ' :
3369+ return $ first >= $ second ;
3370+ break ;
3371+ default :
3372+ throw new \InvalidArgumentException ();
3373+ }
3374+ }
3375+
33433376 /**
33443377 * Handle dynamic calls to class methods.
33453378 *
0 commit comments