diff --git a/src/Cron/DayOfMonthField.php b/src/Cron/DayOfMonthField.php
index 253c0d68..53e15bc4 100644
--- a/src/Cron/DayOfMonthField.php
+++ b/src/Cron/DayOfMonthField.php
@@ -98,8 +98,76 @@ public function increment(DateTime $date, $invert = false)
         return $this;
     }
 
+    /**
+     * Validates that the value is valid for the Day of the Month field
+     * Days of the month can contain values of 1-31, *, L, or ? by default. This can be augmented with lists via a ',',
+     * ranges via a '-', or with a '[0-9]W' to specify the closest weekday.
+     *
+     * @param string $value
+     * @return bool
+     */
     public function validate($value)
     {
-        return (bool) preg_match('/^[\*,\/\-\?LW0-9A-Za-z]+$/', $value);
+        // Allow wildcards and a single L
+        if ($value === '?' || $value === '*' || $value === 'L') {
+            return true;
+        }
+
+        // If you only contain numbers and are within 1-31
+        if ((bool) preg_match('/^\d{1,2}$/', $value) && ($value >= 1 && $value <= 31)) {
+            return true;
+        }
+
+        // If you have a -, we will deal with each of your chunks
+        if ((bool) preg_match('/-/', $value)) {
+            // We cannot have a range within a list or vice versa
+            if ((bool) preg_match('/,/', $value)) {
+                return false;
+            }
+
+            $chunks = explode('-', $value);
+            foreach ($chunks as $chunk) {
+                if (!$this->validate($chunk)) {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        // If you have a comma, we will deal with each value
+        if ((bool) preg_match('/,/', $value)) {
+            // We cannot have a range within a list or vice versa
+            if ((bool) preg_match('/-/', $value)) {
+                return false;
+            }
+
+            $chunks = explode(',', $value);
+            foreach ($chunks as $chunk) {
+                if (!$this->validate($chunk)) {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        // If you contain a /, we'll deal with it
+        if ((bool) preg_match('/\//', $value)) {
+            $chunks = explode('/', $value);
+            foreach ($chunks as $chunk) {
+                if (!$this->validate($chunk)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        // If you end in W, make sure that it has a numeric in front of it
+        if ((bool) preg_match('/^\d{1,2}W$/', $value)) {
+            return true;
+        }
+
+        return false;
     }
 }
diff --git a/tests/Cron/DayOfMonthFieldTest.php b/tests/Cron/DayOfMonthFieldTest.php
index 724b96b0..eff04557 100644
--- a/tests/Cron/DayOfMonthFieldTest.php
+++ b/tests/Cron/DayOfMonthFieldTest.php
@@ -19,7 +19,6 @@ public function testValidatesField()
         $f = new DayOfMonthField();
         $this->assertTrue($f->validate('1'));
         $this->assertTrue($f->validate('*'));
-        $this->assertTrue($f->validate('*/3,1,1-12'));
         $this->assertTrue($f->validate('5W,L'));
         $this->assertFalse($f->validate('1.'));
     }
@@ -47,4 +46,16 @@ public function testIncrementsDate()
         $f->increment($d, true);
         $this->assertEquals('2011-03-14 23:59:00', $d->format('Y-m-d H:i:s'));
     }
+
+    /**
+     * Day of the month cannot accept a 0 value, it must be between 1 and 31
+     * See Github issue #120
+     *
+     * @since 2017-01-22
+     */
+    public function testDoesNotAccept0Date()
+    {
+        $f = new DayOfMonthField();
+        $this->assertFalse($f->validate(0));
+    }
 }