PHP Developers Network

A community of PHP developers offering assistance, advice, discussion, and friendship.
 
Loading
It is currently Mon Oct 15, 2018 9:04 am

All times are UTC - 5 hours




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: Date and time validation
PostPosted: Thu Oct 21, 2010 11:36 am 
Offline
Forum Contributor

Joined: Sat Jan 03, 2009 4:27 pm
Posts: 148
Here's a class to allow a little more flexibility than the native function checkdate().

Syntax: [ Download ] [ Hide ]

    class DateValidator {

      private $_date = array();
      private $_lost;

      public function __construct($date = null, $lost = false) {

        $this->_lost = $lost;

        switch (true) {

          case (strpos($date, '/')):
            $date = explode('/', $date);
            break;
          case (strpos($date, '-')):
            $date = explode('-', $date);
            break;
          case (strpos($date, '.')):
            $date = explode('.', $date);
            break;

        }

        if (!isset($date[2][1]) || isset($date[0][2])) {
          $this->_date = $date;
        }

        else {
          $this->_date = array_reverse($date);
        }

      }

      public function isValidDay() {

        if (!isset($this->_date[2]) || !ctype_digit($this->_date[2]) || $this->_date[2] < 1 || $this->_date[2] > 31) {
          return false;
        }

        return true;

      }

      public function isValidMonth() {

        if (!isset($this->_date[1]) || !ctype_digit($this->_date[1]) || $this->_date[1] < 1 || $this->_date[1] > 12) {
          return false;
        }

        return true;

      }

      public function isValidYear() {

        if (!isset($this->_date[0]) || !ctype_digit($this->_date[0]) || $this->_date[0] == 0) {
          return false;
        }

        if ($this->_date[0] == 0) {
          return false;
        }

        return true;

      }

      public function isValidDate() {

        if (!$this->isValidDay() || !$this->isValidMonth() || !$this->isValidYear()) {
          return false;
        }

        if (isset($this->_date[3])) {
          return false;
        }

        if ($this->_date[2] == 31 && in_array($this->_date[1], array(4, 6, 9, 11))) {
          return false;
        }

        if ($this->_date[2] == 30 && $this->_date[1] == 2) {
          return false;
        }

        if ($this->_date[2] == 29 && $this->_date[1] == 2) {

          if (!is_int($this->_date[0] / 4)) {
            return false;
          }

          if (!is_int($this->_date[0] / 400) && is_int($this->_date[0] / 100)) {
            return false;
          }

        }

        if ($this->_lost && $this->_date[0] == 1752 && $this->_date[1] == 9 && $this->_date[2] > 2 && $this->_date[2] < 14) {
          return false;
        }

        return true;

      }

      public function returnDate() {

        if (!$this->isValidDate()) {
          return '';
        }

        if (!isset($this->_date[2][1])) {
          $this->_date[2] = '0' . $this->_date[2];
        }

        if (!isset($this->_date[1][1])) {
          $this->_date[1] = '0' . $this->_date[1];
        }

        return implode('-', $this->_date);

      }

    }

 


Acceptable date formats:

Code:
01/12/2000
1/12/2000
2000/01/31
2000/1/31
1-1-2000
01-01-2000
2000-01-31
2000-1-31
01.12.2000
1.12.2000
2000.01.31
2000.1.31
1 1 2000
01 01 2000
2000 01 31
2000 1 31


Example:

Syntax: [ Download ] [ Hide ]

// Input

$validDate = new DateValidator('30/02/2001');

var_dump($validDate->isValidDay());
var_dump($validDate->isValidMonth());
var_dump($validDate->isValidYear());
var_dump($validDate->isValidDate());

$validDate = new DateValidator("1 1 2001');

echo $validDate->returnDate(); // Returns date in ISO 8601 format (YYYY-MM-DD)

// Output

bool(true) // 1 - 31 allowed (00 - 09 as well)
bool(true) // 1 - 12 allowed (00 - 09 as well)
bool(true) // 0001 - 9999 allowed (must be four digits to distinguish days from years)
bool(false) // 30 February is an invalid date

2001-01-01



Just for fun, if you pass as the second parameter a true value then any date between 03/09/1752 and 13/09/1752 inclusive will return false. This is because when the Julian calendar was switched to the Gregorian calendar in Great Britain, 11 days needed to be removed to establish accuracy. They went to sleep on Wednesday September 2nd and woke up the following day on Thursday September 14th.

And here's a class for time validation:

Syntax: [ Download ] [ Hide ]

    class TimeValidator {

      private $_time = array();

      public function __construct($time = null) {

        switch (true) {

          case (strpos($time, ':')):
            $this->_time = explode(':', $time);
            break;
          case (strpos($time, '-')):
            $this->_time = explode('-', $time);
            break;
          case (strpos($time, '.')):
            $this->_time = explode('.', $time);
            break;
          case (strpos($time, ' ')):
            $this->_time = explode(' ', $time);
            break;

        }

      }

      public function isValidSecond() {

        if (!isset($this->_time[2]) || !ctype_digit($this->_time[2]) || $this->_time[2] > 59) {
          return false;
        }

        return true;

      }

      public function isValidMinute() {

        if (!isset($this->_time[1]) || !ctype_digit($this->_time[1]) || $this->_time[1] > 59) {
          return false;
        }

        return true;

      }

      public function isValidHour() {

        if (!isset($this->_time[0]) || !ctype_digit($this->_time[0]) || $this->_time[0] > 24) {
          return false;
        }

        return true;

      }

      public function isValidTime() {

        if (!$this->isValidSecond() || !$this->isValidMinute() || !$this->isValidHour()) {
          return false;
        }

        if ($this->_time[0] == 24 && ($this->_time[1] != 0 || $this->_time[2] != 0)) {
          return false;
        }

        return true;

      }

      public function returnTime() {

        if (!$this->isValidTime()) {
          return '';
        }

        if (!isset($this->_time[0][1])) {
          $this->_time[0] = '0' . $this->_time[0];
        }

        if (!isset($this->_time[1][1])) {
          $this->_time[1] = '0' . $this->_time[1];
        }

        if (!isset($this->_time[2][1])) {
          $this->_time[2] = '0' . $this->_time[2];
        }

        return implode(':', $this->_time);

      }

    }

 


This works in pretty much the same way but with the methods isValidSecond(), isValidMinute(), isValidHour(), and isValidTime(). The time must be entered in the order hour, minute, second, and can be separated with either a colon, a dash-minus, a dot, or a space. An hour of 24 is allowed only if the minutes and seconds are both (0)0. The method returnTime() will return the time in the format HH:MM:SS.


Last edited by MichaelR on Fri Oct 22, 2010 4:40 am, edited 2 times in total.

Top
 Profile  
 
PostPosted: Fri Oct 22, 2010 1:13 am 
Offline
DevNet Master

Joined: Wed Feb 11, 2004 4:23 pm
Posts: 4872
Location: Palm beach, Florida
Lots of literals that aren't informative. '400' should be replaced with a descriptive constant Could use unit tests.


Top
 Profile  
 
PostPosted: Fri Oct 22, 2010 2:56 am 
Offline
DevNet Master
User avatar

Joined: Wed Jun 27, 2007 9:44 am
Posts: 4313
Location: Sofia, Bulgaria
How about using strtotime() to do all of this?

_________________
There are 10 types of people in this world, those who understand binary and those who don't


Top
 Profile  
 
PostPosted: Fri Oct 22, 2010 4:30 am 
Offline
Forum Contributor

Joined: Sat Jan 03, 2009 4:27 pm
Posts: 148
VladSun wrote:
How about using strtotime() to do all of this?


Syntax: [ Download ] [ Hide ]

// Input

echo date('Y-m-d', strtotime('13 December 1901'));

// Outputs

1970-01-01
 


josh wrote:
Lots of literals that aren't informative. '400' should be replaced with a descriptive constant Could use unit tests.


Sorry. I thought they were kind of obvious in context. I'll change them to variables if you think it's more suitable. And I'll add some tests.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC - 5 hours


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
Powered by phpBB® Forum Software © phpBB Group