Ticket #425: jduration.patch
| File jduration.patch, 12.0 kB (added by flh, 11 months ago) |
|---|
-
testapp/modules/jelix_tests/tests/utils.jduration.html_cli.php
old new 1 <?php 2 /** 3 * @package testapp 4 * @subpackage jelix_tests module 5 * @author Florian Hatat 6 * @copyright 2008 Florian Hatat 7 * @link http://www.jelix.org 8 * @licence GNU Lesser General Public Licence see LICENCE file or http://www.gnu.org/licenses/lgpl.html 9 */ 10 11 class testjDuration extends UnitTestCase { 12 function testReportedBug(){ 13 // Get now date/time 14 $dtNow = new jDateTime(); 15 $dtNow->setFromString("2008-02-08 00:27:22", jDateTime::DB_DTFORMAT); 16 17 // Get expiration date 18 $expirationDate = "2008-02-12 00:00:00"; 19 20 // Create date time object from DB date 21 $dtExpirationDate = new jDateTime(); 22 $dtExpirationDate->setFromString($expirationDate, jDateTime::DB_DTFORMAT); 23 24 // Compute difference between these dates 25 try 26 { 27 $countdown = $dtNow->durationTo($dtExpirationDate); 28 $dtNow->add($countdown); 29 $this->assertEqual($dtNow, $dtExpirationDate); 30 } 31 catch (Exception $e) 32 { 33 $this->fail("Rejected duration construction"); 34 } 35 } 36 37 function testPositive(){ 38 $dur = new jDuration(20); 39 $dt = new jDateTime(2007, 12, 25, 15, 28, 17); 40 $dtExpected = new jDateTime(2007, 12, 25, 15, 28, 37); 41 $dt->add($dur); 42 $this->assertEqual($dt, $dtExpected); 43 } 44 45 function testRelative1(){ 46 $dur = new jDuration(array("month" => 1)); 47 $dt = new jDateTime(2007, 8, 14, 15, 28, 17); 48 $dtExpected = new jDateTime(2007, 9, 14, 15, 28, 17); 49 $dt->add($dur); 50 $this->assertEqual($dt, $dtExpected); 51 } 52 53 function testRelative2(){ 54 $dur = new jDuration(array("month" => 1)); 55 $dt = new jDateTime(2007, 1, 14, 15, 28, 17); 56 $dtExpected = new jDateTime(2006, 12, 14, 15, 28, 17); 57 $dt->sub($dur); 58 $this->assertEqual($dt, $dtExpected); 59 } 60 61 // Add one month to August, 31st, you would get something like "September, 62 // 31st", which gets "rounded" to October, 1st. For the moment, jDuration 63 // has no option to prevent from crossing the "month" barrier. 64 function testRelativeTricky(){ 65 $dur = new jDuration(array("month" => 1)); 66 $dt = new jDateTime(2007, 8, 31, 15, 28, 17); 67 $dtExpected = new jDateTime(2007, 10, 1, 15, 28, 17); 68 $dt->add($dur); 69 $this->assertEqual($dt, $dtExpected); 70 } 71 72 function testNegative(){ 73 $dur = new jDuration(-20); 74 $dt = new jDateTime(2007, 12, 25, 15, 28, 17); 75 $dtExpected = new jDateTime(2007, 12, 25, 15, 27, 57); 76 $dt->add($dur); 77 $this->assertEqual($dt, $dtExpected); 78 } 79 80 function testMultiplication(){ 81 $dur = new jDuration(array("year" => 1)); 82 $dur->mult(10); // Changed our mind, 10 years is better... 83 $dt = new jDateTime(2007, 1, 1, 23, 58, 3); 84 $dtExpected = new jDateTime(1997, 1, 1, 23, 58, 3); 85 $dt->sub($dur); 86 $this->assertEqual($dt, $dtExpected); 87 } 88 89 function testLeap1(){ 90 $dur = new jDuration(array("year" => 8)); 91 $dt = new jDateTime(2000, 2, 29, 12, 12, 12); 92 $dtExpected = new jDateTime(2008, 2, 29, 12, 12, 12); 93 $dt->add($dur); 94 $this->assertEqual($dt, $dtExpected); 95 } 96 97 function testLeap2(){ 98 $dur = new jDuration(array("year" => 7)); 99 $dt = new jDateTime(2000, 2, 29, 12, 12, 12); 100 $dtExpected = new jDateTime(1993, 3, 1, 12, 12, 12); 101 $dt->sub($dur); 102 $this->assertEqual($dt, $dtExpected); 103 } 104 } 105 ?> -
lib/jelix/utils/jDuration.class.php
old new 1 <?php 2 /** 3 * @package jelix 4 * @subpackage utils 5 * @author Florian Hatat 6 * @copyright 2008 Florian Hatat 7 * 8 * @link http://www.jelix.org 9 * @licence http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public Licence, see LICENCE file 10 */ 11 12 /** 13 * Utility to manipulate durations between two instants 14 * @package jelix 15 * @subpackage utils 16 */ 17 class jDuration { 18 public $months; 19 public $days; 20 public $seconds; 21 22 /** 23 * Construct a new duration. 24 * You can specify the duration as a number of seconds, or as an associative 25 * array which may contain the keys "year", "month", "day", "hour", "minute" 26 * and "second". The former method defines an absolute duration (it will 27 * always add the same number of seconds to any given date/time), while the 28 * latter defines a relative duration (a duration of one month will for 29 * example represent different amounts of time depending on the start date). 30 * 31 * This class represents years as 12 months, minutes as 60 seconds and hours 32 * as 3600 seconds. There is no general conversion between months and days, 33 * nor between days and hours (because of DST). 34 * 35 * @param int/array representation of the duration as an absolute number of seconds, or an array. 36 */ 37 function __construct($init = 0){ 38 $this->days = $this->months = $this->seconds = 0; 39 40 if(is_array($init)){ 41 if(isset($init['year'])){ 42 $this->months += intval($init['year']) * 12; 43 } 44 45 if(isset($init['month'])){ 46 $this->months += intval($init['month']); 47 } 48 49 if(isset($init['day'])){ 50 $this->days += intval($init['days']); 51 } 52 53 if(isset($init['hour'])){ 54 $this->seconds += intval($init['hour']) * 3600; 55 } 56 57 if(isset($init['minute'])){ 58 $this->seconds += intval($init['minute']) * 60; 59 } 60 61 if(isset($init['second'])){ 62 $this->seconds += intval($init['second']); 63 } 64 } 65 elseif(is_int($init)){ 66 $this->seconds = $init; 67 } 68 } 69 70 /** 71 * Add a duration to the current duration 72 * @param jDuration the duration value 73 */ 74 function add($data){ 75 $this->days += $data->days; 76 $this->months += $data->months; 77 $this->seconds += $data->seconds; 78 } 79 80 /** 81 * Multiply the current duration by an integer 82 * @param int the scaling integer 83 */ 84 function mult($scale){ 85 if(is_int($scale)){ 86 $this->days *= $scale; 87 $this->months *= $scale; 88 $this->seconds *= $scale; 89 } 90 } 91 } 92 93 ?> -
lib/jelix/utils/jDateTime.class.php
old new 8 8 * @contributor Florian Hatat 9 9 * @copyright 2005-2006 Laurent Jouanneau 10 10 * @copyright 2007 Loic Mathaud 11 * @copyright 2007 Florian Hatat11 * @copyright 2007-2008 Florian Hatat 12 12 * @copyright 2001-2005 CopixTeam, GeraldCroes, Laurent Jouanneau 13 13 * 14 14 * This class was get originally from the Copix project (CopixDate.lib.php, Copix 2.3dev20050901, http://www.copix.org) … … 347 347 348 348 /** 349 349 * Add a duration to the date. 350 * You can specify the duration in a jD ateTime object (which then is not a date/time)351 * or give each value of the duration352 * @param jD ateTime/int $year the duration value or a year with 4 digits350 * You can specify the duration in a jDuration object or give each value of 351 * the duration. 352 * @param jDuration/int $year the duration value or a year with 4 digits 353 353 * @param int $month month with 2 digits 354 354 * @param int $day day with 2 digits 355 355 * @param int $hour hour with 2 digits … … 357 357 * @param int $second second with 2 digits 358 358 */ 359 359 public function add($year, $month=0, $day=0, $hour=0, $minute=0, $second=0) { 360 if ($year instanceof jD ateTime) {360 if ($year instanceof jDuration) { 361 361 $dt = $year; 362 362 } else { 363 $dt = new jDateTime($year, $month, $day, $hour, $minute, $second); 363 $dt = new jDuration(array("year" => $year, "month" => $month, 364 "day" => $day, "hour" => $hour, "minute" => $minute, 365 "second" => $second)); 364 366 } 365 $t = mktime ( $this->hour + $dt->hour, $this->minute + $dt->minute, $this->second + $dt->second,366 $this->month + $dt->month , $this->day + $dt->day, $this->year + $dt->year);367 $t = mktime($this->hour, $this->minute, $this->second + $dt->seconds, 368 $this->month + $dt->months, $this->day + $dt->days, $this->year); 367 369 368 370 $t = getdate ($t); 369 371 $this->year = $t['year']; … … 376 378 377 379 /** 378 380 * substract a <b>duration</b> to the date 379 * You can specify the duration in a jD ateTime object (which then is not a date/time)380 * or give each value of the duration381 * @param jD ateTime/int $year the duration value or a year with 4 digits381 * You can specify the duration in a jDuration object or give each value of 382 * the duration. 383 * @param jDuration/int $year the duration value or a year with 4 digits 382 384 * @param int $month month with 2 digits 383 385 * @param int $day day with 2 digits 384 386 * @param int $hour hour with 2 digits … … 386 388 * @param int $second second with 2 digits 387 389 */ 388 390 public function sub($year, $month=0, $day=0, $hour=0, $minute=0, $second=0) { 389 if ($year instanceof jD ateTime) {391 if ($year instanceof jDuration) { 390 392 $dt = $year; 391 393 } else { 392 394 $dt = new jDateTime($year, $month, $day, $hour, $minute, $second); 393 395 } 394 $t = mktime ( $this->hour - $dt->hour, $this->minute - $dt->minute, $this->second - $dt->second , 395 $this->month - $dt->month, $this->day - $dt->day, $this->year - $dt->year); 396 397 $t = getdate ($t); 398 $this->year = $t['year']; 399 $this->month = $t['mon']; 400 $this->day = $t['mday']; 401 $this->hour = $t['hours']; 402 $this->minute = $t['minutes']; 403 $this->second = $t['seconds']; 396 $dt->mult(-1); 397 $this->add($dt); 404 398 } 405 399 406 400 /** 407 401 * to know the duration between two dates. 408 402 * @param jDateTime $dt the date on which a sub will be made with the date on the current object 409 * @return jDateTime a jDateTime object which will contains <b>a duration</b> (not a date) 403 * @param bool $absolute 404 * @return jDuration a jDuration object 410 405 */ 411 public function durationTo($dt){ 412 $t = mktime ( $dt->hour, $dt->minute,$dt->second , $dt->month, $dt->day, $dt->year ) 413 - mktime ( $this->hour, $this->minute,$this->second , $this->month, $this->day, $this->year ); 414 $t = getdate ($t); 415 return new jDateTime( $t['year']-1970,$t['mon']-1, $t['mday']-1, $t['hours']-1, $t['minutes'], $t['seconds']); 406 public function durationTo($dt, $absolute=true){ 407 if($absolute){ 408 $t = mktime($dt->hour, $dt->minute, $dt->second, 409 $dt->month, $dt->day, $dt->year) 410 - mktime($this->hour, $this->minute, $this->second, 411 $this->month, $this->day, $this->year); 412 return new jDuration($t); 413 } 414 else{ 415 return new jDuration(array( 416 "year" => $dt->year - $this->year, 417 "month" => $dt->month - $this->month, 418 "day" => $dt->day - $this-> day, 419 "hour" => $dt->hour - $this->hour, 420 "minute" => $dt->minute - $this->minute, 421 "second" => $dt->second - $this->second 422 )); 423 } 416 424 } 417 425 418 426 /**
