Mantis - Quercus
Viewing Issue Advanced Details
4346 minor always 01-14-11 08:29 05-04-16 05:33
m3ct0n  
nam  
normal  
closed 4.0.14  
fixed  
none    
none  
0004346: mktime do not change year...
$m_diff = 6;

$date_diff = mktime(0, 0, date('d'), date('m')-$m_diff, date('y'));

PHP standard:
2010-07-14

Quercus:
2011-07-14

The year do not change by the negative month value in Quercus.

Notes
(0006686)
matthiasblaesing   
04-22-16 12:00   
The issue can be traced into the DateModule.java (com.caucho.quercus.lib.date.DateModule), the implementation of mktime delegates to setMktime (around line 920). There the values for the date elements are set individually, but in no recogisable order.

The fix (see attached patch) is to set the values in order from most significant to least significat. This allows spills from smaller values to propagate to the higher value fields. The old behavior causes the spill to be overwritten by the set value.
(0006687)
matthiasblaesing   
04-22-16 12:07   
Ok - attaching files fails - so here the patch and reproducer:

------- test.php: ----------

<?php

$rollover = mktime(30, 0, 0, 4, 21, 2016);

print(strftime("mktime(30, 0, 0, 4, 21, 2016) => Should be: 2016-04-22 06:00:00 -- %Y-%m-%d %H:%M:%S", $rollover));
print("\n");

$rollover = mktime(-1, 0, 0, 4, 21, 2016);

print(strftime("mktime(-1, 0, 0, 4, 21, 2016) => Should be: 2016-04-20 23:00:00 -- %Y-%m-%d %H:%M:%S", $rollover));
print("\n");

------- Broken (current): ----------
matthias@athena:~/src/quercus$ java -jar /home/matthias/src/quercus/dist/quercus-with-dependencies.jar test.php
mktime(30, 0, 0, 4, 21, 2016) => Should be: 2016-04-22 06:00:00 -- 2016-04-21 06:00:00
mktime(-1, 0, 0, 4, 21, 2016) => Should be: 2016-04-20 23:00:00 -- 2016-04-21 23:00:00
matthias@athena:~/src/quercus$

------- Patch: ----------
diff --git a/modules/quercus/src/com/caucho/quercus/lib/date/DateModule.java b/modules/quercus/src/com/caucho/quercus/lib/date/DateModule.java
index 49c1ec4..41e58df 100644
--- a/modules/quercus/src/com/caucho/quercus/lib/date/DateModule.java
+++ b/modules/quercus/src/com/caucho/quercus/lib/date/DateModule.java
@@ -925,6 +925,35 @@
                                 Value dayV,
                                 Value yearV)
   {
+ if (! yearV.isDefault()) {
+ int year = yearV.toInt();
+
+ if (year >= 1000) {
+ date.setYear(year);
+ }
+ else if (year >= 70) {
+ date.setYear(year + 1900);
+ }
+ else if (year >= 0) {
+ date.setYear(year + 2000);
+ }
+ else if (year < 0) {
+ date.setYear(1969);
+ }
+ }
+
+ if (! monthV.isDefault()) {
+ int month = monthV.toInt();
+
+ date.setMonth(month - 1);
+ }
+
+ if (! dayV.isDefault()) {
+ int day = dayV.toInt();
+
+ date.setDayOfMonth(day);
+ }
+
     if (! hourV.isDefault()) {
       int hour = hourV.toInt();
 
@@ -941,35 +970,6 @@
       int second = secondV.toInt();
 
       date.setSecond(second);
- }
-
- if (! monthV.isDefault()) {
- int month = monthV.toInt();
-
- date.setMonth(month - 1);
- }
-
- if (! dayV.isDefault()) {
- int day = dayV.toInt();
-
- date.setDayOfMonth(day);
- }
-
- if (! yearV.isDefault()) {
- int year = yearV.toInt();
-
- if (year >= 1000) {
- date.setYear(year);
- }
- else if (year >= 70) {
- date.setYear(year + 1900);
- }
- else if (year >= 0) {
- date.setYear(year + 2000);
- }
- else if (year < 0) {
- date.setYear(1969);
- }
     }
   }
 

------- Result: ----------
matthias@athena:~/src/quercus$ java -jar /home/matthias/src/quercus/dist/quercus-with-dependencies.jar test.php
mktime(30, 0, 0, 4, 21, 2016) => Should be: 2016-04-22 06:00:00 -- 2016-04-22 06:00:00
mktime(-1, 0, 0, 4, 21, 2016) => Should be: 2016-04-20 23:00:00 -- 2016-04-20 23:00:00
matthias@athena:~/src/quercus$
(0006693)
nam   
05-04-16 05:33   
php/190p
php/190z