Problems adding time

MaradonaJr

New Member
I've run into a strange timewarp while doing some math with time, and it has left me stumped. Or, well, I've found the reason (or atleast a plausible one), but don't quite know what to do about it, or if there is indeed anything that can be done.The issue in plain words is, that when adding time in larger units than 1 week (it's multipliers excluded) it seems to be impossible to be exact. And by exact I mean, that when I add 1 years worth of seconds to NOW, I end up 1 year and some hours from NOW.I can understand that adding 1 (or more) months will do this, as a months length varies, but a year should be more or less the same, shouldn't it?Now I know you'll want to know how I do this, so here follows (pseudoish) code:\[code\]class My_DateInterval { public $length; // Interval length in seconds public function __construct($interval) { $this->length = 0; preg_match( '/P(((?<years>([0-9]{1,}))Y)|((?<months>([0-9]{1,}))M)|((?<weeks>([0-9]{1,}))W)|((?<days>([0-9]{1,}))D)){0,}(T((?<hours>([0-9]{1,2})){1}H){0,1}((?<minutes>([0-9]{1,2}){1})M){0,1}((?<seconds>([0-9]{1,2}){1})S){0,1}){0,1}/', $interval, $timeparts ); if (is_numeric($timeparts['years'])) $this->length += intval($timeparts['years']) * 31556926; // 1 year in seconds if (is_numeric($timeparts['months'])) $this->length += intval($timeparts['months']) * 2629743.83; // 1 month in seconds if (is_numeric($timeparts['weeks'])) $this->length += intval($timeparts['weeks']) * 604800; // 1 week in seconds if (is_numeric($timeparts['days'])) $this->length += intval($timeparts['days']) * 86400; // 1 day in seconds if (is_numeric($timeparts['hours'])) $this->length += intval($timeparts['hours']) * 3600; // 1 hour in seconds if (is_numeric($timeparts['minutes'])) $this->length += intval($timeparts['minutes']) * 60; // 1 minute in seconds if (is_numeric($timeparts['seconds'])) $this->length += intval($timeparts['seconds']); $this->length = round($this->length); }}class My_DateTime extends DateTime { public function __construct($time, $tz = null) { parent::__contruct($time, $tz); } public function add(My_DateInterval $i) { $this->modify($i->length . ' seconds'); }}$d = new My_DateTime();$i = new My_DateInterval('P1Y');$d->add($i);\[/code\]Doing some debug printouts of the interval length and before/after values show that it's all good, in the sense that "it works as expected and all checks out", but the issue stated above still stands: there is an anomaly in the exactness of it all which I'd very much would like to get right, if possible.In so many words: How to do exact mathematics with time units greater than 1 week. (I.e. 1 month / 1 year).PS. For those wondering why I'm using My_* classes is because PHP 5.3 just isn't widespread enough, but I'm trying to keep things in a way that migrating to built-in utility classes will be as smooth as possible.
 
Back
Top