diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result
index 08ed5fc6439..bbe3aee1fb0 100644
--- a/mysql-test/r/date_formats.result
+++ b/mysql-test/r/date_formats.result
@@ -449,6 +449,8 @@ create table t1 select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%
 str_to_date("10:11:12.0012", "%H:%i:%S.%f") as f2,
 str_to_date("2003-01-02", "%Y-%m-%d") as f3,
 str_to_date("02", "%d") as f4, str_to_date("02 10", "%d %H") as f5;
+Warnings:
+Warning	1265	Data truncated for column 'f4' at row 1
 describe t1;
 Field	Type	Null	Key	Default	Extra
 f1	datetime	YES		NULL	
@@ -458,7 +460,7 @@ f4	date	YES		NULL
 f5	time	YES		NULL	
 select * from t1;
 f1	f2	f3	f4	f5
-2003-01-02 10:11:12	10:11:12	2003-01-02	0000-00-02	58:00:00
+2003-01-02 10:11:12	10:11:12	2003-01-02	0000-00-00	58:00:00
 drop table t1;
 create table t1 select "02 10" as a, "%d %H" as b;
 select str_to_date(a,b) from t1;
diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result
index d0cf11d0511..08a33734910 100644
--- a/mysql-test/r/strict.result
+++ b/mysql-test/r/strict.result
@@ -5,7 +5,9 @@ select @@sql_mode;
 REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
 DROP TABLE IF EXISTS t1;
 CREATE TABLE t1 (col1 date);
-INSERT INTO t1 VALUES('2004-01-01'),('0000-10-31'),('2004-02-29');
+INSERT INTO t1 VALUES('2004-01-01'),('2004-02-29');
+INSERT INTO t1 VALUES('0000-10-31');
+ERROR 22007: Incorrect date value: '0000-10-31' for column 'col1' at row 1
 INSERT INTO t1 VALUES('2004-0-31');
 ERROR 22007: Incorrect date value: '2004-0-31' for column 'col1' at row 1
 INSERT INTO t1 VALUES('2004-01-02'),('2004-0-31');
@@ -54,7 +56,6 @@ Warning	1265	Data truncated for column 'col1' at row 3
 select * from t1;
 col1
 2004-01-01
-0000-10-31
 2004-02-29
 2004-01-02
 2004-01-03
@@ -121,7 +122,9 @@ col1
 drop table t1;
 set @@sql_mode='ansi,traditional';
 CREATE TABLE t1 (col1 datetime);
-INSERT INTO t1 VALUES('2004-10-31 15:30:00'),('0000-10-31 15:30:00'),('2004-02-29 15:30:00');
+INSERT INTO t1 VALUES('2004-10-31 15:30:00'),('2004-02-29 15:30:00');
+INSERT INTO t1 VALUES('0000-10-31 15:30:00');
+ERROR 22007: Incorrect datetime value: '0000-10-31 15:30:00' for column 'col1' at row 1
 INSERT INTO t1 VALUES('2004-0-31 15:30:00');
 ERROR 22007: Incorrect datetime value: '2004-0-31 15:30:00' for column 'col1' at row 1
 INSERT INTO t1 VALUES('2004-10-0 15:30:00');
@@ -141,7 +144,6 @@ ERROR 22007: Incorrect datetime value: '59' for column 'col1' at row 1
 select * from t1;
 col1
 2004-10-31 15:30:00
-0000-10-31 15:30:00
 2004-02-29 15:30:00
 drop table t1;
 CREATE TABLE t1 (col1 timestamp);
@@ -204,6 +206,7 @@ INSERT INTO t1 (col1) VALUES (STR_TO_DATE('15.10.2004','%d.%m.%Y'));
 INSERT INTO t1 (col2) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i'));
 INSERT INTO t1 (col3) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i'));
 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i'));
+ERROR 22007: Incorrect date value: '0000-10-31 15:30:00' for column 'col1' at row 1
 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i'));
 ERROR 22007: Incorrect date value: '2004-00-31 15:30:00' for column 'col1' at row 1
 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i'));
@@ -219,6 +222,7 @@ ERROR HY000: Incorrect datetime value: '15.13.2004 15.30' for function str_to_ti
 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y'));
 ERROR 22007: Incorrect date value: '0000-00-00' for column 'col1' at row 1
 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i'));
+ERROR 22007: Incorrect datetime value: '0000-10-31 15:30:00' for column 'col2' at row 1
 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i'));
 ERROR 22007: Incorrect datetime value: '2004-00-31 15:30:00' for column 'col2' at row 1
 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i'));
@@ -255,6 +259,7 @@ INSERT INTO t1 (col1) VALUES (CAST('2004-10-15' AS DATE));
 INSERT INTO t1 (col2) VALUES (CAST('2004-10-15 10:15' AS DATETIME));
 INSERT INTO t1 (col3) VALUES (CAST('2004-10-15 10:15' AS DATETIME));
 INSERT INTO t1 (col1) VALUES(CAST('0000-10-31' AS DATE));
+ERROR 22007: Truncated incorrect datetime value: '0000-10-31'
 INSERT INTO t1 (col1) VALUES(CAST('2004-10-0' AS DATE));
 ERROR 22007: Incorrect date value: '2004-10-00' for column 'col1' at row 1
 INSERT INTO t1 (col1) VALUES(CAST('2004-0-10' AS DATE));
@@ -262,6 +267,7 @@ ERROR 22007: Incorrect date value: '2004-00-10' for column 'col1' at row 1
 INSERT INTO t1 (col1) VALUES(CAST('0000-00-00' AS DATE));
 ERROR 22007: Truncated incorrect datetime value: '0000-00-00'
 INSERT INTO t1 (col2) VALUES(CAST('0000-10-31 15:30' AS DATETIME));
+ERROR 22007: Truncated incorrect datetime value: '0000-10-31 15:30'
 INSERT INTO t1 (col2) VALUES(CAST('2004-10-0 15:30' AS DATETIME));
 ERROR 22007: Incorrect datetime value: '2004-10-00 15:30:00' for column 'col2' at row 1
 INSERT INTO t1 (col2) VALUES(CAST('2004-0-10 15:30' AS DATETIME));
@@ -269,7 +275,7 @@ ERROR 22007: Incorrect datetime value: '2004-00-10 15:30:00' for column 'col2' a
 INSERT INTO t1 (col2) VALUES(CAST('0000-00-00' AS DATETIME));
 ERROR 22007: Truncated incorrect datetime value: '0000-00-00'
 INSERT INTO t1 (col3) VALUES(CAST('0000-10-31 15:30' AS DATETIME));
-ERROR 22007: Incorrect datetime value: '0000-10-31 15:30:00' for column 'col3' at row 1
+ERROR 22007: Truncated incorrect datetime value: '0000-10-31 15:30'
 INSERT INTO t1 (col3) VALUES(CAST('2004-10-0 15:30' AS DATETIME));
 ERROR 22007: Incorrect datetime value: '2004-10-00 15:30:00' for column 'col3' at row 1
 INSERT INTO t1 (col3) VALUES(CAST('2004-0-10 15:30' AS DATETIME));
@@ -282,6 +288,7 @@ INSERT INTO t1 (col1) VALUES (CONVERT('2004-10-15',DATE));
 INSERT INTO t1 (col2) VALUES (CONVERT('2004-10-15 10:15',DATETIME));
 INSERT INTO t1 (col3) VALUES (CONVERT('2004-10-15 10:15',DATETIME));
 INSERT INTO t1 (col1) VALUES(CONVERT('0000-10-31' , DATE));
+ERROR 22007: Truncated incorrect datetime value: '0000-10-31'
 INSERT INTO t1 (col1) VALUES(CONVERT('2004-10-0' , DATE));
 ERROR 22007: Incorrect date value: '2004-10-00' for column 'col1' at row 1
 INSERT INTO t1 (col1) VALUES(CONVERT('2004-0-10' , DATE));
@@ -289,6 +296,7 @@ ERROR 22007: Incorrect date value: '2004-00-10' for column 'col1' at row 1
 INSERT INTO t1 (col1) VALUES(CONVERT('0000-00-00',DATE));
 ERROR 22007: Truncated incorrect datetime value: '0000-00-00'
 INSERT INTO t1 (col2) VALUES(CONVERT('0000-10-31 15:30',DATETIME));
+ERROR 22007: Truncated incorrect datetime value: '0000-10-31 15:30'
 INSERT INTO t1 (col2) VALUES(CONVERT('2004-10-0 15:30',DATETIME));
 ERROR 22007: Incorrect datetime value: '2004-10-00 15:30:00' for column 'col2' at row 1
 INSERT INTO t1 (col2) VALUES(CONVERT('2004-0-10 15:30',DATETIME));
@@ -296,7 +304,7 @@ ERROR 22007: Incorrect datetime value: '2004-00-10 15:30:00' for column 'col2' a
 INSERT INTO t1 (col2) VALUES(CONVERT('0000-00-00',DATETIME));
 ERROR 22007: Truncated incorrect datetime value: '0000-00-00'
 INSERT INTO t1 (col3) VALUES(CONVERT('0000-10-31 15:30',DATETIME));
-ERROR 22007: Incorrect datetime value: '0000-10-31 15:30:00' for column 'col3' at row 1
+ERROR 22007: Truncated incorrect datetime value: '0000-10-31 15:30'
 INSERT INTO t1 (col3) VALUES(CONVERT('2004-10-0 15:30',DATETIME));
 ERROR 22007: Incorrect datetime value: '2004-10-00 15:30:00' for column 'col3' at row 1
 INSERT INTO t1 (col3) VALUES(CONVERT('2004-0-10 15:30',DATETIME));
diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result
index 85f899be5d8..2addb9c93eb 100644
--- a/mysql-test/r/type_datetime.result
+++ b/mysql-test/r/type_datetime.result
@@ -26,6 +26,8 @@ Table	Op	Msg_type	Msg_text
 test.t1	check	status	OK
 delete from t1;
 insert into t1 values("000101"),("691231"),("700101"),("991231"),("00000101"),("00010101"),("99991231"),("00101000000"),("691231000000"),("700101000000"),("991231235959"),("10000101000000"),("99991231235959"),("20030100000000"),("20030000000000");
+Warnings:
+Warning	1264	Out of range value adjusted for column 't' at row 5
 insert into t1 values ("2003-003-03");
 insert into t1 values ("20030102T131415"),("2001-01-01T01:01:01"), ("2001-1-1T1:01:01");
 select * from t1;
@@ -34,7 +36,7 @@ t
 2069-12-31 00:00:00
 1970-01-01 00:00:00
 1999-12-31 00:00:00
-0000-01-01 00:00:00
+0000-00-00 00:00:00
 0001-01-01 00:00:00
 9999-12-31 00:00:00
 2000-10-10 00:00:00
diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test
index ce269b42ee9..6f22b81172d 100644
--- a/mysql-test/t/strict.test
+++ b/mysql-test/t/strict.test
@@ -13,7 +13,9 @@ DROP TABLE IF EXISTS t1;
 # Test INSERT with DATE
 
 CREATE TABLE t1 (col1 date);
-INSERT INTO t1 VALUES('2004-01-01'),('0000-10-31'),('2004-02-29');
+INSERT INTO t1 VALUES('2004-01-01'),('2004-02-29');
+--error 1292
+INSERT INTO t1 VALUES('0000-10-31');
 
 # All test cases expected to fail should return 
 #      SQLSTATE 22007 <invalid date value>
@@ -97,7 +99,9 @@ set @@sql_mode='ansi,traditional';
 # Test INSERT with DATETIME
 
 CREATE TABLE t1 (col1 datetime);
-INSERT INTO t1 VALUES('2004-10-31 15:30:00'),('0000-10-31 15:30:00'),('2004-02-29 15:30:00');
+INSERT INTO t1 VALUES('2004-10-31 15:30:00'),('2004-02-29 15:30:00');
+--error 1292
+INSERT INTO t1 VALUES('0000-10-31 15:30:00');
 
 # All test cases expected to fail should return 
 #      SQLSTATE 22007 <invalid datetime value>
@@ -190,6 +194,7 @@ INSERT INTO t1 (col3) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i'));
 #       All test cases expected to fail should return 
 #       SQLSTATE 22007 <invalid date value>
 
+--error 1292
 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i'));
 
 --error 1292
@@ -211,6 +216,7 @@ INSERT INTO t1 (col1) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y'));
 #       All test cases expected to fail should return 
 #       SQLSTATE 22007 <invalid datetime value>
 
+--error 1292
 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i'));
 
 --error 1292
@@ -264,6 +270,8 @@ INSERT INTO t1 (col3) VALUES (CAST('2004-10-15 10:15' AS DATETIME));
 ## Test INSERT with CAST AS DATE into DATE
 #       All test cases expected to fail should return 
 #       SQLSTATE 22007 <invalid date value>
+
+--error 1292
 INSERT INTO t1 (col1) VALUES(CAST('0000-10-31' AS DATE));
 
 --error 1292
@@ -290,6 +298,8 @@ INSERT INTO t1 (col1) VALUES(CAST('0000-00-00' AS DATE));
 ## Test INSERT with CAST AS DATETIME into DATETIME
 #       All test cases expected to fail should return 
 #       SQLSTATE 22007 <invalid datetime value>
+
+--error 1292
 INSERT INTO t1 (col2) VALUES(CAST('0000-10-31 15:30' AS DATETIME));
 
 --error 1292
@@ -356,6 +366,8 @@ INSERT INTO t1 (col3) VALUES (CONVERT('2004-10-15 10:15',DATETIME));
 ## Test INSERT with CONVERT to DATE into DATE
 #       All test cases expected to fail should return 
 #       SQLSTATE 22007 <invalid date value>
+
+--error 1292
 INSERT INTO t1 (col1) VALUES(CONVERT('0000-10-31' , DATE));
 
 --error 1292
@@ -381,6 +393,8 @@ INSERT INTO t1 (col1) VALUES(CONVERT('0000-00-00',DATE));
 ## Test INSERT with CONVERT to DATETIME into DATETIME
 #       All test cases expected to fail should return 
 #       SQLSTATE 22007 <invalid datetime value>
+
+--error 1292
 INSERT INTO t1 (col2) VALUES(CONVERT('0000-10-31 15:30',DATETIME));
 
 --error 1292
diff --git a/sql-common/my_time.c b/sql-common/my_time.c
index c9d39260761..93bf23ed284 100644
--- a/sql-common/my_time.c
+++ b/sql-common/my_time.c
@@ -69,6 +69,7 @@ uint calc_days_in_year(uint year)
     Here we assume that year and month is ok !
     If month is 0 we allow any date. (This only happens if we allow zero
     date parts in str_to_datetime())
+    Disallow dates with zero year and non-zero month and/or day.
 
   RETURN
     0  ok
@@ -85,7 +86,8 @@ static my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date,
         (!(flags & TIME_INVALID_DATES) &&
          ltime->month && ltime->day > days_in_month[ltime->month-1] &&
          (ltime->month != 2 || calc_days_in_year(ltime->year) != 366 ||
-          ltime->day != 29)))
+          ltime->day != 29)) ||
+        (ltime->year == 0 && (ltime->month != 0 || ltime->day != 0)))
     {
       *was_cut= 2;
       return TRUE;