Source for file DateAndTime.class.php

Documentation is available at DateAndTime.class.php

  1. <?php
  2. /**
  3. * @since 5/2/05
  4. * @package harmoni.primitives.chronology
  5. *
  6. * @copyright Copyright &copy; 2005, Middlebury College
  7. * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License (GPL)
  8. *
  9. * @version $Id: DateAndTime.class.php,v 1.6 2007/09/04 20:25:25 adamfranco Exp $
  10. *
  11. * @link http://harmoni.sourceforge.net/
  12. * @author Adam Franco <adam AT adamfranco DOT com> <afranco AT middlebury DOT edu>
  13. */
  14.  
  15. require_once(dirname(__FILE__)."/../Magnitudes/Magnitude.class.php");
  16.  
  17.  
  18. /**
  19. * I represent a point in UTC time as defined by ISO 8601. I have zero duration.
  20. *
  21. * My implementation uses two Integers and a Duration:
  22. * - jdn - julian day number.
  23. * - seconds - number of seconds since midnight.
  24. * - offset - duration from UTC.
  25. *
  26. * To create new DateAndTime instances, <b>use one of the static instance-creation
  27. * methods</b>, NOT 'new DateAndTime':
  28. * - {@link epoch DateAndTime::epoch()}
  29. * - {@link epoch DateAndTime::epoch()}
  30. * - {@link fromString DateAndTime::fromString($aString)}
  31. * - {@link midnight DateAndTime::midnight()}
  32. * - {@link now DateAndTime::now()}
  33. * - {@link noon DateAndTime::noon()}
  34. * - {@link today DateAndTime::today()}
  35. * - {@link tomorrow DateAndTime::tomorrow()}
  36. * - {@link withDateAndTime DateAndTime::withDateAndTime($aDate, $aTime)}
  37. * - {@link withJulianDayNumber DateAndTime::withJulianDayNumber($aJulianDayNumber)}
  38. * - {@link withYearDay DateAndTime::withYearDay($anIntYear, $anIntDayOfYear)}
  39. * - {@link withYearDayHourMinuteSecond DateAndTime::withYearDayHourMinuteSecond(}
  40. * $anIntYear, $anIntDayOfYear, $anIntHour, $anIntMinute,
  41. * $anIntSecond)}
  42. * - {@link withYearDayHourMinuteSecondOffset}
  43. * DateAndTime::withYearDayHourMinuteSecondOffset($anIntYear,
  44. * $anIntDayOfYear, $anIntHour, $anIntMinute, $anIntSecond,
  45. * $aDurationOffset)}
  46. * - {@link withYearMonthDay DateAndTime::withYearMonthDay($anIntYear,}
  47. * $anIntOrStringMonth, $anIntDay)}
  48. * - {@link withYearMonthDayHourMinute DateAndTime::withYearMonthDayHourMinute(}
  49. * $anIntYear, $anIntOrStringMonth, $anIntDay, $anIntHour,
  50. * $anIntMinute)}
  51. * - {@link withYearMonthDayHourMinuteSecond}
  52. * DateAndTime::withYearMonthDayHourMinuteSecond($anIntYear,
  53. * $anIntOrStringMonth, $anIntDay, $anIntHour, $anIntMinute,
  54. * $anIntSecond)}
  55. * - {@link withYearMonthDayHourMinuteSecondOffset}
  56. * DateAndTime::withYearMonthDayHourMinuteSecondOffset($anIntYear,
  57. * $anIntOrStringMonth, $anIntDay, $anIntHour, $anIntMinute,
  58. * $anIntSecond, $aDurationOffset)}
  59. * - {@link yesterday DateAndTime::yesterday()}
  60. *
  61. * @since 5/2/05
  62. * @package harmoni.primitives.chronology
  63. *
  64. * @copyright Copyright &copy; 2005, Middlebury College
  65. * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License (GPL)
  66. *
  67. * @version $Id: DateAndTime.class.php,v 1.6 2007/09/04 20:25:25 adamfranco Exp $
  68. *
  69. * @link http://harmoni.sourceforge.net/
  70. * @author Adam Franco <adam AT adamfranco DOT com> <afranco AT middlebury DOT edu>
  71. */
  72. class DateAndTime
  73. extends Magnitude
  74. {
  75.  
  76. /*******************************************************
  77. * Instance Variables
  78. *********************************************************/
  79.  
  80.  
  81. /**
  82. * @var integer $jdn; JulianDateNumber
  83. * @access private
  84. * @since 5/11/05
  85. */
  86. var $jdn;
  87. /**
  88. * @var integer $seconds; Seconds this day
  89. * @access private
  90. * @since 5/11/05
  91. */
  92. var $seconds;
  93. /**
  94. * @var object Duration $offset; The offset from UTC
  95. * @access private
  96. * @since 5/11/05
  97. */
  98. var $offset;
  99.  
  100. /*******************************************************
  101. * Class Methods
  102. *********************************************************/
  103.  
  104. /**
  105. * One second precision.
  106. *
  107. * @return object Duration
  108. * @access public
  109. * @since 5/12/05
  110. * @static
  111. */
  112. function clockPrecision () {
  113. $obj = Duration::withSeconds(1);
  114. return $obj;
  115. }
  116. /**
  117. * Answer the duration we are offset from UTC
  118. *
  119. * @return object Duration
  120. * @access public
  121. * @static
  122. * @since 5/3/05
  123. */
  124. function localOffset () {
  125. $timeZone = DateAndTime::localTimeZone();
  126. return $timeZone->offset();
  127. }
  128. /**
  129. * Answer the local TimeZone
  130. *
  131. * @return object Duration
  132. * @access public
  133. * @static
  134. * @since 5/3/05
  135. */
  136. function localTimeZone () {
  137. $tzAbbreviation = date('T');
  138. $tzOffset = date('Z');
  139. if ($tzAbbreviation && $tzOffset)
  140. $obj = TimeZone::offsetNameAbbreviation(
  141. Duration::withSeconds($tzOffset),
  142. $tzAbbreviation,
  143. $tzAbbreviation);
  144. else
  145. $obj = TimeZone::defaultTimeZone();
  146. return $obj;
  147. }
  148. /*******************************************************
  149. * Class Methods - Instance Creation
  150. *
  151. * All static instance creation methods have an optional
  152. * $class parameter which is used to get around the limitations
  153. * of not being able to find the class of the object that
  154. * recieved the initial method call rather than the one in
  155. * which it is implemented. These parameters SHOULD NOT BE
  156. * USED OUTSIDE OF THIS PACKAGE.
  157. *********************************************************/
  158.  
  159. /**
  160. * Answer a new instance representing the Squeak epoch: 1 January 1901
  161. *
  162. * @param optional string $class DO NOT USE OUTSIDE OF PACKAGE.
  163. * This parameter is used to get around the limitations of not being
  164. * able to find the class of the object that recieved the initial
  165. * method call.
  166. * @return object DateAndTime
  167. * @access public
  168. * @since 5/2/05
  169. * @static
  170. */
  171. function epoch ( $class = 'DateAndTime' ) {
  172. eval('$result = '.$class.'::withJulianDayNumber(
  173. ChronologyConstants::SqueakEpoch(),
  174. $class
  175. );');
  176. return $result;
  177. }
  178. /**
  179. * Answer a new instance represented by a string:
  180. *
  181. * - '-1199-01-05T20:33:14.321-05:00'
  182. * - ' 2002-05-16T17:20:45.00000001+01:01'
  183. * - ' 2002-05-16T17:20:45.00000001'
  184. * - ' 2002-05-16T17:20'
  185. * - ' 2002-05-16T17:20:45'
  186. * - ' 2002-05-16T17:20:45+01:57'
  187. * - ' 2002-05-16T17:20:45-02:34'
  188. * - ' 2002-05-16T17:20:45+00:00'
  189. * - ' 1997-04-26T01:02:03+01:02:3'
  190. *
  191. * @param string $aString The input string.
  192. * @param optional string $class DO NOT USE OUTSIDE OF PACKAGE.
  193. * This parameter is used to get around the limitations of not being
  194. * able to find the class of the object that recieved the initial
  195. * method call.
  196. * @return object DateAndTime
  197. * @access public
  198. * @since 5/12/05
  199. * @static
  200. */
  201. function fromString ( $aString, $class = 'DateAndTime' ) {
  202. $parser = StringParser::getParserFor($aString);
  203.  
  204. if (!is_string($aString) || !preg_match('/[^\W]/', $aString) || !$parser) {
  205. $null = null;
  206. return $null;
  207. // die("'".$aString."' is not in a valid format.");
  208. }
  209. if (!is_null($parser->offsetHour()))
  210. eval('$result = '.$class.'::withYearMonthDayHourMinuteSecondOffset(
  211. $parser->year(), $parser->month(), $parser->day(), $parser->hour(),
  212. $parser->minute(), $parser->second(),
  213. Duration::withDaysHoursMinutesSeconds(0, $parser->offsetHour(),
  214. $parser->offsetMinute(), $parser->offsetSecond()), $class);');
  215. else if (!is_null($parser->hour()))
  216. eval('$result = '.$class.'::withYearMonthDayHourMinuteSecond(
  217. $parser->year(), $parser->month(), $parser->day(), $parser->hour(),
  218. $parser->minute(), $parser->second(), $class);');
  219. else
  220. eval('$result = '.$class.'::withYearMonthDay(
  221. $parser->year(), $parser->month(), $parser->day(), $class);');
  222. return $result;
  223. }
  224. /**
  225. * Answer a new instance starting at midnight local time.
  226. *
  227. * @param optional string $class DO NOT USE OUTSIDE OF PACKAGE.
  228. * This parameter is used to get around the limitations of not being
  229. * able to find the class of the object that recieved the initial
  230. * method call.
  231. * @return object DateAndTime
  232. * @access public
  233. * @since 5/3/05
  234. * @static
  235. */
  236. function midnight ( $class = 'DateAndTime' ) {
  237. eval('$result = '.$class.'::now("'.$class.'");');
  238. $obj =$result->atMidnight();
  239. return $obj;
  240. }
  241. /**
  242. * Answer a new instance starting at noon local time.
  243. *
  244. * @param optional string $class DO NOT USE OUTSIDE OF PACKAGE.
  245. * This parameter is used to get around the limitations of not being
  246. * able to find the class of the object that recieved the initial
  247. * method call.
  248. * @return object DateAndTime
  249. * @access public
  250. * @since 5/3/05
  251. * @static
  252. */
  253. function noon ( $class = 'DateAndTime' ) {
  254. eval('$result = '.$class.'::now('.$class.');');
  255. $obj =$result->atNoon();
  256. return $obj;
  257. }
  258. /**
  259. * Answer the current date and time.
  260. *
  261. * @param optional string $class DO NOT USE OUTSIDE OF PACKAGE.
  262. * This parameter is used to get around the limitations of not being
  263. * able to find the class of the object that recieved the initial
  264. * method call.
  265. * @return object DateAndTime
  266. * @access public
  267. * @since 5/12/05
  268. * @static
  269. */
  270. function now ( $class = 'DateAndTime' ) {
  271. eval('$result = '.$class.'::withYearMonthDayHourMinuteSecondOffset(
  272. '.intval(date('Y')).',
  273. '.intval(date('n')).',
  274. '.intval(date('j')).',
  275. '.intval(date('G')).',
  276. '.intval(date('i')).',
  277. '.intval(date('s')).',
  278. $null = NULL,
  279. $class
  280. );');
  281. return $result;
  282. }
  283. /**
  284. * Answer a new instance representing today
  285. *
  286. * @param optional string $class DO NOT USE OUTSIDE OF PACKAGE.
  287. * This parameter is used to get around the limitations of not being
  288. * able to find the class of the object that recieved the initial
  289. * method call.
  290. * @return object DateAndTime
  291. * @access public
  292. * @since 5/12/05
  293. * @static
  294. */
  295. function today ( $class = 'DateAndTime' ) {
  296. eval('$result = '.$class.'::midnight($class);');
  297. return $result;
  298. }
  299. /**
  300. * Answer a new instance representing tomorow
  301. *
  302. * @param optional string $class DO NOT USE OUTSIDE OF PACKAGE.
  303. * This parameter is used to get around the limitations of not being
  304. * able to find the class of the object that recieved the initial
  305. * method call.
  306. * @return object DateAndTime
  307. * @access public
  308. * @since 5/12/05
  309. * @static
  310. */
  311. function tomorrow ( $class = 'DateAndTime' ) {
  312. eval('$today = '.$class.'::today($class);');
  313. $todaysDate =$today->asDate();
  314. $tomorowsDate =$todaysDate->next();
  315. $obj =$tomorowsDate->asDateAndTime();
  316. return $obj;
  317. }
  318. /**
  319. * Create a new instance from Date and Time objects
  320. *
  321. * @param optional string $class DO NOT USE OUTSIDE OF PACKAGE.
  322. * This parameter is used to get around the limitations of not being
  323. * able to find the class of the object that recieved the initial
  324. * method call.
  325. * @return object DateAndTime
  326. * @access public
  327. * @since 5/12/05
  328. * @static
  329. */
  330. function withDateAndTime ( $aDate, $aTime, $class = 'DateAndTime' ) {
  331. eval('$result = '.$class.'::withYearDayHourMinuteSecond(
  332. $aDate->startYear(),
  333. $aDate->dayOfYear(),
  334. $aTime->hour(),
  335. $aTime->minute(),
  336. $aTime->second(),
  337. $class
  338. );');
  339. return $result;
  340. }
  341. /**
  342. * Create a new new instance for a given Julian Day Number.
  343. *
  344. * @param integer $aJulianDayNumber
  345. * @param optional string $class DO NOT USE OUTSIDE OF PACKAGE.
  346. * This parameter is used to get around the limitations of not being
  347. * able to find the class of the object that recieved the initial
  348. * method call.
  349. * @return object DateAndTime
  350. * @access public
  351. * @since 5/2/05
  352. * @static
  353. */
  354. function withJulianDayNumber ( $aJulianDayNumber, $class = 'DateAndTime' ) {
  355. // Validate our passed class name.
  356. if (!(strtolower($class) == strtolower('DateAndTime')
  357. || is_subclass_of(new $class, 'DateAndTime')))
  358. {
  359. die("Class, '$class', is not a subclass of 'DateAndTime'.");
  360. }
  361. $days = Duration::withDays($aJulianDayNumber);
  362. $dateAndTime = new $class;
  363. $dateAndTime->ticksOffset($days->ticks(), DateAndTime::localOffset());
  364. return $dateAndTime;
  365. }
  366. /**
  367. * Create a new instance.
  368. *
  369. * @param integer $anIntYear
  370. * @param integer $anIntDayOfYear
  371. * @param optional string $class DO NOT USE OUTSIDE OF PACKAGE.
  372. * This parameter is used to get around the limitations of not being
  373. * able to find the class of the object that recieved the initial
  374. * method call.
  375. * @access public
  376. * @static
  377. * @since 5/4/05
  378. */
  379. function withYearDay ( $anIntYear, $anIntDayOfYear, $class = 'DateAndTime') {
  380. eval('$result = '.$class.'::withYearDayHourMinuteSecond(
  381. $anIntYear,
  382. $anIntDayOfYear,
  383. 0,
  384. 0,
  385. 0,
  386. $class
  387. );');
  388. return $result;
  389. }
  390. /**
  391. * Create a new instance.
  392. *
  393. * @param integer $anIntYear
  394. * @param integer $anIntDayOfYear
  395. * @param integer $anIntHour
  396. * @param integer $anIntMinute
  397. * @param integer $anIntSecond
  398. * @param optional string $class DO NOT USE OUTSIDE OF PACKAGE.
  399. * This parameter is used to get around the limitations of not being
  400. * able to find the class of the object that recieved the initial
  401. * method call.
  402. * @return object DateAndTime
  403. * @access public
  404. * @static
  405. * @since 5/4/05
  406. */
  407. function withYearDayHourMinuteSecond ( $anIntYear, $anIntDayOfYear,
  408. $anIntHour, $anIntMinute, $anIntSecond, $class = 'DateAndTime' )
  409. {
  410. eval('$return = '.$class.'::withYearDayHourMinuteSecondOffset(
  411. $anIntYear,
  412. $anIntDayOfYear,
  413. $anIntHour,
  414. $anIntMinute,
  415. $anIntSecond,
  416. '.$class.'::localOffset(),
  417. $class
  418. );');
  419. return $return;
  420. }
  421. /**
  422. * Create a new instance.
  423. *
  424. * @param integer $anIntYear
  425. * @param integer $anIntDayOfYear
  426. * @param integer $anIntHour
  427. * @param integer $anIntMinute
  428. * @param integer $anIntSecond
  429. * @param object Duration $aDurationOffset
  430. * @param optional string $class DO NOT USE OUTSIDE OF PACKAGE.
  431. * This parameter is used to get around the limitations of not being
  432. * able to find the class of the object that recieved the initial
  433. * method call.
  434. * @return object DateAndTime
  435. * @access public
  436. * @static
  437. * @since 5/4/05
  438. */
  439. function withYearDayHourMinuteSecondOffset ( $anIntYear, $anIntDayOfYear,
  440. $anIntHour, $anIntMinute, $anIntSecond, $aDurationOffset, $class = 'DateAndTime' )
  441. {
  442. eval('$result = '.$class.'::withYearMonthDayHourMinuteSecondOffset(
  443. $anIntYear,
  444. 1,
  445. 1,
  446. $anIntHour,
  447. $anIntMinute,
  448. $anIntSecond,
  449. $aDurationOffset,
  450. $class
  451. );');
  452. $day = Duration::withDays($anIntDayOfYear - 1);
  453. $obj =$result->plus($day);
  454. return $obj;
  455. }
  456. /**
  457. * Create a new instance.
  458. *
  459. * @param integer $anIntYear
  460. * @param integer $anIntOrStringMonth
  461. * @param integer $anIntDay
  462. * @param optional string $class DO NOT USE OUTSIDE OF PACKAGE.
  463. * This parameter is used to get around the limitations of not being
  464. * able to find the class of the object that recieved the initial
  465. * method call.
  466. * @access public
  467. * @static
  468. * @since 5/4/05
  469. */
  470. function withYearMonthDay ( $anIntYear, $anIntOrStringMonth, $anIntDay,
  471. $class = 'DateAndTime' )
  472. {
  473. eval('$result = '.$class.'::withYearMonthDayHourMinuteSecondOffset(
  474. $anIntYear,
  475. $anIntOrStringMonth,
  476. $anIntDay,
  477. 0,
  478. 0,
  479. 0,
  480. $null = NULL,
  481. $class
  482. );');
  483. return $result;
  484. }
  485. /**
  486. * Create a new instance.
  487. *
  488. * @param integer $anIntYear
  489. * @param integer $anIntOrStringMonth
  490. * @param integer $anIntDay
  491. * @param integer $anIntHour
  492. * @param integer $anIntMinute
  493. * @param optional string $class DO NOT USE OUTSIDE OF PACKAGE.
  494. * This parameter is used to get around the limitations of not being
  495. * able to find the class of the object that recieved the initial
  496. * method call.
  497. * @return object DateAndTime
  498. * @access public
  499. * @static
  500. * @since 5/4/05
  501. */
  502. function withYearMonthDayHourMinute ( $anIntYear, $anIntOrStringMonth,
  503. $anIntDay, $anIntHour, $anIntMinute, $class = 'DateAndTime' )
  504. {
  505. eval('$result = '.$class.'::withYearMonthDayHourMinuteSecondOffset(
  506. $anIntYear,
  507. $anIntOrStringMonth,
  508. $anIntDay,
  509. $anIntHour,
  510. $anIntMinute,
  511. 0,
  512. $null = NULL,
  513. $class
  514. );');
  515. return $result;
  516. }
  517. /**
  518. * Create a new instance.
  519. *
  520. * @param integer $anIntYear
  521. * @param integer $anIntOrStringMonth
  522. * @param integer $anIntDay
  523. * @param integer $anIntHour
  524. * @param integer $anIntMinute
  525. * @param integer $anIntSecond
  526. * @param optional string $class DO NOT USE OUTSIDE OF PACKAGE.
  527. * This parameter is used to get around the limitations of not being
  528. * able to find the class of the object that recieved the initial
  529. * method call.
  530. * @return object DateAndTime
  531. * @access public
  532. * @static
  533. * @since 5/4/05
  534. */
  535. function withYearMonthDayHourMinuteSecond ( $anIntYear, $anIntOrStringMonth,
  536. $anIntDay, $anIntHour, $anIntMinute, $anIntSecond, $class = 'DateAndTime' )
  537. {
  538. eval('$result = '.$class.'::withYearMonthDayHourMinuteSecondOffset(
  539. $anIntYear,
  540. $anIntOrStringMonth,
  541. $anIntDay,
  542. $anIntHour,
  543. $anIntMinute,
  544. $anIntSecond,
  545. $null = NULL,
  546. $class
  547. );');
  548. return $result;
  549. }
  550. /**
  551. * Create a new instance.
  552. *
  553. * @param integer $anIntYear
  554. * @param integer $anIntOrStringMonth
  555. * @param integer $anIntDay
  556. * @param integer $anIntHour
  557. * @param integer $anIntMinute
  558. * @param integer $anIntSecond
  559. * @param object Duration $aDurationOffset
  560. * @param optional string $class DO NOT USE OUTSIDE OF PACKAGE.
  561. * This parameter is used to get around the limitations of not being
  562. * able to find the class of the object that recieved the initial
  563. * method call.
  564. * @return object DateAndTime
  565. * @access public
  566. * @static
  567. * @since 5/4/05
  568. */
  569. function withYearMonthDayHourMinuteSecondOffset ( $anIntYear,
  570. $anIntOrStringMonth, $anIntDay, $anIntHour, $anIntMinute,
  571. $anIntSecond, $aDurationOffset, $class = 'DateAndTime' )
  572. {
  573. // Validate our passed class name.
  574. if (!(strtolower($class) == strtolower('DateAndTime')
  575. || is_subclass_of(new $class, 'DateAndTime')))
  576. {
  577. die("Class, '$class', is not a subclass of 'DateAndTime'.");
  578. }
  579. if (is_numeric($anIntOrStringMonth))
  580. $monthIndex = $anIntOrStringMonth;
  581. else
  582. $monthIndex = Month::indexOfMonth($anIntOrStringMonth);
  583. $p = intval(($monthIndex - 14) / 12);
  584. $q = $anIntYear + 4800 + $p;
  585. $r = $monthIndex - 2 - (12 * $p);
  586. $s = intval(($anIntYear + 4900 + $p) / 100);
  587. $julianDayNumber = intval((1461 * $q) / 4)
  588. + intval((367 * $r) / 12)
  589. - intval((3 * $s) / 4)
  590. + ($anIntDay - 32075);
  591. $since = Duration::withDaysHoursMinutesSeconds($julianDayNumber,
  592. $anIntHour, $anIntMinute, $anIntSecond);
  593.  
  594. if (is_null($aDurationOffset))
  595. $offset = DateAndTime::localOffset();
  596. else
  597. $offset =$aDurationOffset;
  598. $dateAndTime = new $class;
  599. $dateAndTime->ticksOffset($since->ticks(), $offset);
  600. return $dateAndTime;
  601. }
  602. /**
  603. * Answer a new instance representing yesterday
  604. *
  605. * @param optional string $class DO NOT USE OUTSIDE OF PACKAGE.
  606. * This parameter is used to get around the limitations of not being
  607. * able to find the class of the object that recieved the initial
  608. * method call.
  609. * @return object DateAndTime
  610. * @access public
  611. * @since 5/12/05
  612. * @static
  613. */
  614. function yesterday ( $class = 'DateAndTime' ) {
  615. eval('$today = '.$class.'::today($class);');
  616. $todaysDate =$today->asDate();
  617. $yesterdaysDate =$todaysDate->previous();
  618. $obj =$yesterdaysDate->asDateAndTime();
  619. return $obj;
  620. }
  621. /*******************************************************
  622. * Instance Methods - Private
  623. *********************************************************/
  624.  
  625. /**
  626. * Initialize this DateAndTime.
  627. * ticks is {julianDayNumber. secondCount. nanoSeconds}
  628. *
  629. * @param array $ticks
  630. * @param object Duration $utcOffset
  631. * @return void
  632. * @access private
  633. * @since 5/2/05
  634. */
  635. function ticksOffset ( $ticks, $utcOffset ) {
  636. // $this->_normalize($ticks, 2, ChronologyConstants::NanosInSecond());
  637. $this->_normalize($ticks, 1, ChronologyConstants::SecondsInDay());
  638. $this->jdn = $ticks[0];
  639. $this->seconds = $ticks[1];
  640. // $this->nanos = $ticks[2];
  641. $this->offset =$utcOffset;
  642. }
  643. /**
  644. * Normalize tick values to make things like "2 days, 35 hours" into
  645. * "3 days, 9 hours".
  646. *
  647. * @param array $ticks
  648. * @param integer $i The index of the array to normalize.
  649. * @param integer $base The base to normalize to.
  650. * @return void
  651. * @access private
  652. * @since 5/3/05
  653. */
  654. function _normalize ($ticks, $i, $base) {
  655. $tick = $ticks[$i];
  656. $quo = floor(abs($tick)/$base);
  657. $rem = $tick % $base;
  658. if ($rem < 0) {
  659. $quo = $quo-1;
  660. $rem = $base + $rem;
  661. }
  662. $ticks[$i-1] = $ticks[$i-1]+$quo;
  663. $ticks[$i] = $rem;
  664. }
  665. /**
  666. * Private - answer an array with our instance variables. Assumed to be UTC
  667. *
  668. * @return array
  669. * @access private
  670. * @since 5/4/05
  671. */
  672. function ticks () {
  673. return array ($this->jdn, $this->seconds);
  674. }
  675. /*******************************************************
  676. * Instance Methods - Accessing
  677. *********************************************************/
  678.  
  679. /**
  680. * Answer the date and time at midnight on the day of the receiver.
  681. *
  682. * @return object DateAndTime
  683. * @access public
  684. * @since 5/25/05
  685. */
  686. function atMidnight () {
  687. eval('$result = '.get_class($this).'::withYearMonthDay($this->year(),
  688. $this->month(), $this->dayOfMonth(), "'.get_class($this).'");');
  689. return $result;
  690. }
  691. /**
  692. * Answer noon on the day of the reciever
  693. *
  694. * @return object DateAndTime
  695. * @access public
  696. * @since 5/25/05
  697. */
  698. function atNoon () {
  699. eval('$result = '.get_class($this).'::withYearMonthDayHourMinuteSecond(
  700. $this->year(), $this->month(), $this->dayOfMonth(), 12, 0, 0,
  701. '.get_class($this).');');
  702. return $result;
  703. }
  704. /**
  705. * Answer the day
  706. *
  707. * @return integer
  708. * @access public
  709. * @since 5/3/05
  710. */
  711. function day () {
  712. return $this->dayOfYear();
  713. }
  714. /**
  715. * Return an array with the following elements:
  716. * 'dd' => day of the year
  717. * 'mm' => month
  718. * 'yyyy' => year
  719. *
  720. * The algorithm is from Squeak's DateAndTime>>dayMonthYearDo: method.
  721. *
  722. * @return array
  723. * @access public
  724. * @since 5/3/05
  725. */
  726. function dayMonthYearArray () {
  727. $l = $this->jdn + 68569;
  728. $n = floor((4 * $l) / 146097);
  729. $l = $l - floor(((146097 * $n) + 3) / 4);
  730. $i = floor((4000 * ($l + 1)) / 1461001);
  731. $l = ($l - floor((1461 * $i) / 4)) + 31;
  732. $j = floor((80 * $l) / 2447);
  733. $dd = $l - (floor((2447 * $j) / 80));
  734. $l = floor($j / 11);
  735. $mm = $j + 2 - (12 * $l);
  736. $yyyy = (100 * ($n - 49)) + $i + $l;
  737. return array('dd' => $dd, 'mm' => $mm, 'yyyy' => $yyyy);
  738. }
  739. /**
  740. * Answer the day of the month
  741. *
  742. * @return integer
  743. * @access public
  744. * @since 5/3/05
  745. */
  746. function dayOfMonth () {
  747. $array = $this->dayMonthYearArray();
  748. return $array['dd'];
  749. }
  750. /**
  751. * Answer the day of the week
  752. *
  753. * @return integer
  754. * @access public
  755. * @since 5/3/05
  756. */
  757. function dayOfWeek () {
  758. $x = $this->jdn + 1;
  759. return ($x - (intval($x / 7) * 7)) + 1;
  760. }
  761. /**
  762. * Answer the day of the week abbreviation
  763. *
  764. * @return string
  765. * @access public
  766. * @since 5/3/05
  767. */
  768. function dayOfWeekAbbreviation () {
  769. return substr($this->dayOfWeekName(), 0, 3);
  770. }
  771. /**
  772. * Answer the day of the week name
  773. *
  774. * @return string
  775. * @access public
  776. * @since 5/3/05
  777. */
  778. function dayOfWeekName () {
  779. return Week::nameOfDay($this->dayOfWeek());
  780. }
  781. /**
  782. * Answer the day of the year
  783. *
  784. * @return integer
  785. * @access public
  786. * @since 5/3/05
  787. */
  788. function dayOfYear () {
  789. $thisYear = Year::withYear($this->year());
  790. $start =$thisYear->start();
  791. return ($this->jdn - $start->julianDayNumber() + 1);
  792. }
  793. /**
  794. * Answer the number of days in the month represented by the receiver.
  795. *
  796. * @return ingteger
  797. * @access public
  798. * @since 5/5/05
  799. */
  800. function daysInMonth () {
  801. $month =$this->asMonth();
  802. return $month->daysInMonth();
  803. }
  804. /**
  805. * Answer the number of days in the year represented by the receiver.
  806. *
  807. * @return ingteger
  808. * @access public
  809. * @since 5/5/05
  810. */
  811. function daysInYear () {
  812. $year =$this->asYear();
  813. return $year->daysInYear();
  814. }
  815. /**
  816. * Answer the number of days in the year after the date of the receiver.
  817. *
  818. * @return ingteger
  819. * @access public
  820. * @since 5/5/05
  821. */
  822. function daysLeftInYear () {
  823. return $this->daysInYear() - $this->dayOfYear();
  824. }
  825. /**
  826. * Answer the duration of this object (always zero)
  827. *
  828. * @return object Duration
  829. * @access public
  830. * @since 5/5/05
  831. */
  832. function duration () {
  833. $obj = Duration::zero();
  834. return $obj;
  835. }
  836. /**
  837. * Answer the day-in-the-year of the first day of our month
  838. *
  839. * @return integer
  840. * @access public
  841. * @since 5/5/05
  842. */
  843. function firstDayOfMonth () {
  844. $month =$this->asMonth();
  845. $monthStart =$month->start();
  846. return $monthStart->day();
  847. }
  848. /**
  849. * Answer just 'hh:mm:ss'. This is equivalent to Squeak's printHMSOn: method.
  850. *
  851. * @return string
  852. * @access public
  853. * @since 5/10/05
  854. */
  855. function hmsString () {
  856. $result = '';
  857. $result .= str_pad($this->hour(), 2, '0', STR_PAD_LEFT);
  858. $result .= ':';
  859. $result .= str_pad($this->minute(), 2, '0', STR_PAD_LEFT);
  860. $result .= ':';
  861. $result .= str_pad($this->second(), 2, '0', STR_PAD_LEFT);
  862. return $result;
  863. }
  864. /**
  865. * Answer the hours (0-23)
  866. *
  867. * @return integer
  868. * @access public
  869. * @since 5/3/05
  870. */
  871. function hour () {
  872. return $this->hour24();
  873. }
  874. /**
  875. * Answer the hours (0-23)
  876. *
  877. * @return integer
  878. * @access public
  879. * @since 5/3/05
  880. */
  881. function hour24 () {
  882. $duration = Duration::withSeconds($this->seconds);
  883. return $duration->hours();
  884. }
  885. /**
  886. * Answer an <integer> between 1 and 12, inclusive, representing the hour
  887. * of the day in the 12-hour clock of the local time of the receiver.
  888. *
  889. * @return integer
  890. * @access public
  891. * @since 5/4/05
  892. */
  893. function hour12 () {
  894. $x = ($this->hour24() - 1) % 12;
  895. if ($x < 0)
  896. $x = $x + 12;
  897. return $x + 1;
  898. }
  899. /**
  900. * Return if this year is a leap year
  901. *
  902. * @return boolean
  903. * @access public
  904. * @since 5/4/05
  905. */
  906. function isLeapYear () {
  907. return Year::isLeapYear($this->year());
  908. }
  909. /**
  910. * Return the JulianDayNumber of this DateAndTime
  911. *
  912. * @return integer
  913. * @access public
  914. * @since 5/4/05
  915. */
  916. function julianDayNumber () {
  917. return $this->jdn;
  918. }
  919. /**
  920. * Return the Meridian Abbreviation ('AM'/'PM')
  921. *
  922. * @return string
  923. * @access public
  924. * @since 5/5/05
  925. */
  926. function meridianAbbreviation () {
  927. $time =$this->asTime();
  928. return $time->meridianAbbreviation();
  929. }
  930. /**
  931. * Answer the miniute (0-59)
  932. *
  933. * @return integer
  934. * @access public
  935. * @since 5/3/05
  936. */
  937. function minute () {
  938. $duration = Duration::withSeconds($this->seconds);
  939. return $duration->minutes();
  940. }
  941. /**
  942. * Answer the month
  943. *
  944. * @return integer
  945. * @access public
  946. * @since 5/3/05
  947. */
  948. function month () {
  949. $array = $this->dayMonthYearArray();
  950. return $array['mm'];
  951. }
  952. /**
  953. * Answer the day of the week abbreviation
  954. *
  955. * @return string
  956. * @access public
  957. * @since 5/3/05
  958. */
  959. function monthAbbreviation () {
  960. return substr($this->monthName(), 0, 3);
  961. }
  962. /**
  963. * Answer the index of the month.
  964. *
  965. * @return integer
  966. * @access public
  967. * @since 5/3/05
  968. */
  969. function monthIndex () {
  970. return $this->month();
  971. }
  972. /**
  973. * Answer the name of the month.
  974. *
  975. * @return string
  976. * @access public
  977. * @since 5/3/05
  978. */
  979. function monthName () {
  980. return Month::nameOfMonth($this->month());
  981. }
  982. /**
  983. * Answer the offset
  984. *
  985. * @return object Duration
  986. * @access public
  987. * @since 5/3/05
  988. */
  989. function offset () {
  990. return $this->offset;
  991. }
  992. /**
  993. * Answer the second (0-59)
  994. *
  995. * @return integer
  996. * @access public
  997. * @since 5/3/05
  998. */
  999. function second () {
  1000. $duration = Duration::withSeconds($this->seconds);
  1001. return $duration->seconds();
  1002. }
  1003. /**
  1004. * Print as per ISO 8601 sections 5.3.3 and 5.4.1.
  1005. * If printLeadingSpaceToo is false, prints either:
  1006. * 'YYYY-MM-DDThh:mm:ss.s+ZZ:zz:z' (for positive years)
  1007. * or
  1008. * '-YYYY-MM-DDThh:mm:ss.s+ZZ:zz:z' (for negative years)
  1009. *
  1010. * If printLeadingSpaceToo is true, prints either:
  1011. * ' YYYY-MM-DDThh:mm:ss.s+ZZ:zz:z' (for positive years)
  1012. * or
  1013. * '-YYYY-MM-DDThh:mm:ss.s+ZZ:zz:z' (for negative years)
  1014. *
  1015. * This is equivalent to Squeak's printOn:withLeadingSpace: method.
  1016. *
  1017. * @return string
  1018. * @access public
  1019. * @since 5/10/05
  1020. */
  1021. function printableString ( $printLeadingSpaceToo = FALSE ) {
  1022. $result = $this->ymdString($printLeadingSpaceToo);
  1023. $result .= 'T';
  1024. $result .= $this->hmsString();
  1025. if ($this->offset->isPositive())
  1026. $result .= '+';
  1027. else
  1028. $result .= '-';
  1029. $result .= str_pad(abs($this->offset->hours()), 2, '0', STR_PAD_LEFT);
  1030. $result .= ':';
  1031. $result .= str_pad(abs($this->offset->minutes()), 2, '0', STR_PAD_LEFT);
  1032. if ($this->offset->seconds() != 0) {
  1033. $result .= ':';
  1034. $result .= intval(abs($this->offset->minutes())/10);
  1035. }
  1036. return $result;
  1037. }
  1038. /**
  1039. * Answer the Time Zone that corresponds to our offset.
  1040. *
  1041. * @return object TimeZone
  1042. * @access public
  1043. * @since 5/10/05
  1044. */
  1045. function timeZone () {
  1046. // Search through the array of timezones for one that matches. Otherwise,
  1047. // build our own. The name and abbreviation are just a guess, as multiple
  1048. // Time Zones have the same offset.
  1049. $zoneArray = TimeZone::timeZones();
  1050. foreach (array_keys($zoneArray) as $key) {
  1051. if ($this->offset->isEqualTo($zoneArray[$key]->offset()))
  1052. return $zoneArray[$key];
  1053. }
  1054. $obj = TimeZone::offsetNameAbbreviation(
  1055. $this->offset,
  1056. $tzAbbreviation,
  1057. $tzAbbreviation);
  1058. return $obj;
  1059. }
  1060. /**
  1061. * Answer the TimeZone abbreviation.
  1062. *
  1063. * @return string
  1064. * @access public
  1065. * @since 5/10/05
  1066. */
  1067. function timeZoneAbbreviation () {
  1068. $timeZone =$this->timeZone();
  1069. return $timeZone->abbreviation();
  1070. }
  1071. /**
  1072. * Answer the TimeZone name.
  1073. *
  1074. * @return string
  1075. * @access public
  1076. * @since 5/10/05
  1077. */
  1078. function timeZoneName () {
  1079. $timeZone =$this->timeZone();
  1080. return $timeZone->name();
  1081. }
  1082. /**
  1083. * Answer the year
  1084. *
  1085. * @return integer
  1086. * @access public
  1087. * @since 5/3/05
  1088. */
  1089. function year () {
  1090. $array = $this->dayMonthYearArray();
  1091. return $array['yyyy'];
  1092. }
  1093. /**
  1094. * Print just the year, month, and day on aStream.
  1095. *
  1096. * If printLeadingSpaceToo is true, then print as:
  1097. * ' YYYY-MM-DD' (if the year is positive) or '-YYYY-MM-DD' (if the year is negative)
  1098. * otherwise print as:
  1099. * 'YYYY-MM-DD' or '-YYYY-MM-DD'
  1100. *
  1101. * This is equivalent to Squeak's printYMDOn:withLeadingSpace: method.
  1102. *
  1103. * @return string
  1104. * @access public
  1105. * @since 5/10/05
  1106. */
  1107. function ymdString ( $printLeadingSpaceToo = FALSE ) {
  1108. $year = $this->year();
  1109. $month = $this->month();
  1110. $day = $this->dayOfMonth();
  1111. $result = '';
  1112. if ($year < 0) {
  1113. $result .= '-';
  1114. } else {
  1115. if ($printLeadingSpaceToo)
  1116. $result .= ' ';
  1117. }
  1118. $result .= str_pad(abs($year), 4, '0', STR_PAD_LEFT);
  1119. $result .= '-';
  1120. $result .= str_pad($month, 2, '0', STR_PAD_LEFT);
  1121. $result .= '-';
  1122. $result .= str_pad($day, 2, '0', STR_PAD_LEFT);
  1123. return $result;
  1124. }
  1125.  
  1126. /**
  1127. * Print just the month, day, and year on aStream.
  1128. *
  1129. * @return string
  1130. * @access public
  1131. * @since 5/10/05
  1132. */
  1133. function mdyString () {
  1134. $year = $this->year();
  1135. $month = $this->month();
  1136. $day = $this->dayOfMonth();
  1137. $result = '';
  1138. if ($year < 0) {
  1139. $year = '-'.$year;
  1140. }
  1141. return "$month/$day/$year";
  1142. }
  1143. /*******************************************************
  1144. * Instance methods - Comparing/Testing
  1145. *********************************************************/
  1146.  
  1147. /**
  1148. * comparand conforms to protocol DateAndTime,
  1149. * or can be converted into something that conforms.
  1150. *
  1151. * @param object $comparand
  1152. * @return boolean
  1153. * @access public
  1154. * @since 5/3/05
  1155. */
  1156. function isEqualTo ( $comparand ) {
  1157. if ($this === $comparand)
  1158. return TRUE;
  1159.  
  1160. if (!method_exists($comparand, 'asDateAndTime'))
  1161. return FALSE;
  1162. $comparandAsDateAndTime =$comparand->asDateAndTime();
  1163. if ($this->offset->isEqualTo($comparandAsDateAndTime->offset())) {
  1164. $myTicks = $this->ticks();
  1165. $comparandTicks = $comparandAsDateAndTime->ticks();
  1166. } else {
  1167. $meAsUTC =$this->asUTC();
  1168. $myTicks = $meAsUTC->ticks();
  1169. $comparandAsUTC =$comparandAsDateAndTime->asUTC();
  1170. $comparandTicks = $comparandAsUTC->ticks();
  1171. }
  1172. if ($myTicks[0] != $comparandTicks[0])
  1173. return FALSE;
  1174. else
  1175. return ($myTicks[1] == $comparandTicks[1]);
  1176. }
  1177. /**
  1178. * comparand conforms to protocol DateAndTime,
  1179. * or can be converted into something that conforms.
  1180. *
  1181. * @param object $comparand
  1182. * @return boolean
  1183. * @access public
  1184. * @since 5/3/05
  1185. */
  1186. function isLessThan ( $comparand ) {
  1187. $comparandAsDateAndTime =$comparand->asDateAndTime();
  1188. if ($this->offset->isEqualTo($comparandAsDateAndTime->offset())) {
  1189. $myTicks = $this->ticks();
  1190. $comparandTicks = $comparandAsDateAndTime->ticks();
  1191. } else {
  1192. $meAsUTC =$this->asUTC();
  1193. $myTicks = $meAsUTC->ticks();
  1194. $comparandAsUTC =$comparandAsDateAndTime->asUTC();
  1195. $comparandTicks = $comparandAsUTC->ticks();
  1196. }
  1197. if ($myTicks[0] < $comparandTicks[0])
  1198. return TRUE;
  1199. else
  1200. return (($myTicks[0] == $comparandTicks[0])
  1201. && ($myTicks[1] < $comparandTicks[1]));
  1202. }
  1203.  
  1204. /*******************************************************
  1205. * Instance methods - Operations
  1206. *********************************************************/
  1207.  
  1208. /**
  1209. * Subtract a Duration or DateAndTime.
  1210. *
  1211. * @param object $operand
  1212. * @return object
  1213. * @access public
  1214. * @since 5/3/05
  1215. */
  1216. function minus ( $operand ) {
  1217. $methods = get_class_methods($operand);
  1218. // If this conforms to the DateAndTimeProtocal
  1219. if (in_array('asdateandtime', $methods)
  1220. | in_array('asDateAndTime', $methods))
  1221. {
  1222. $meLocal =$this->asLocal();
  1223. $lticks = $meLocal->ticks();
  1224. $opDAndT =$operand->asDateAndTime();
  1225. $opLocal =$opDAndT->asLocal();
  1226. $rticks = $opLocal->ticks();
  1227. $obj = Duration::withSeconds(
  1228. (($lticks[0] - $rticks[0]) * ChronologyConstants::SecondsInDay())
  1229. + ($lticks[1] - $rticks[1]));
  1230. return $obj;
  1231. }
  1232. // If this conforms to the Duration protocal
  1233. else {
  1234. $obj =$this->plus($operand->negated());
  1235. return $obj;
  1236. }
  1237. }
  1238. /**
  1239. * Answer a new Duration whose our date + operand. The operand must implement
  1240. * asDuration().
  1241. *
  1242. * @param object $operand
  1243. * @return object DateAndTime
  1244. * @access public
  1245. * @since 5/4/05
  1246. */
  1247. function plus ( $operand ) {
  1248. $ticks = array();
  1249. $duration =$operand->asDuration();
  1250. $durationTicks = $duration->ticks();
  1251. foreach ($this->ticks() as $key => $value) {
  1252. $ticks[$key] = $value + $durationTicks[$key];
  1253. }
  1254. $class = get_class($this);
  1255. $result = new $class();
  1256. $result->ticksOffset($ticks, $this->offset());
  1257. return $result;
  1258. }
  1259.  
  1260. /*******************************************************
  1261. * Instance methods - Converting
  1262. *********************************************************/
  1263.  
  1264. /**
  1265. * Answer a Date that represents this object
  1266. *
  1267. * @return object Date
  1268. * @access public
  1269. * @since 5/5/05
  1270. */
  1271. function asDate () {
  1272. $obj = Date::starting($this);
  1273. return $obj;
  1274. }
  1275. /**
  1276. * Answer a DateAndTime that represents this object
  1277. *
  1278. * @return object DateAndTime
  1279. * @access public
  1280. * @since 5/4/05
  1281. */
  1282. function asDateAndTime () {
  1283. return $this;
  1284. }
  1285. /**
  1286. * Answer a Duration that represents this object, the duration since
  1287. * midnight.
  1288. *
  1289. * @return object Duration
  1290. * @access public
  1291. * @since 5/4/05
  1292. */
  1293. function asDuration () {
  1294. $obj = Duration::withSeconds($this->seconds);
  1295. return $obj;
  1296. }
  1297. /**
  1298. * Answer a DateAndTime that represents the object, but at local time.
  1299. *
  1300. * @return object DateAndTime
  1301. * @access public
  1302. * @since 5/5/05
  1303. */
  1304. function asLocal () {
  1305. $myOffset =$this->offset();
  1306. if ($myOffset->isEqualTo(DateAndTime::localOffset()))
  1307. return $this;
  1308. else {
  1309. $obj =$this->utcOffset(DateAndTime::localOffset());
  1310. return $obj;
  1311. }
  1312. }
  1313. /**
  1314. * Answer the month that represents this date's month
  1315. *
  1316. * @return object Month
  1317. * @access public
  1318. * @since 5/5/05
  1319. */
  1320. function asMonth () {
  1321. $obj = Month::starting($this);
  1322. return $obj;
  1323. }
  1324. /**
  1325. * Return the number of seconds since the Squeak epoch.
  1326. *
  1327. * @return integer
  1328. * @access public
  1329. * @since 5/5/05
  1330. */
  1331. function asSeconds () {
  1332. eval('$epoch = '.get_class($this).'::epoch();');
  1333. $sinceEpoch =$this->minus($epoch);
  1334. return $sinceEpoch->asSeconds();
  1335. }
  1336. /**
  1337. * Answer a Time that represents our time component
  1338. *
  1339. * @return object Time
  1340. * @access public
  1341. * @since 5/5/05
  1342. */
  1343. function asTime () {
  1344. $obj = Time::withSeconds($this->seconds);
  1345. return $obj;
  1346. }
  1347. /**
  1348. * Answer a Timestamp that represents this DateAndTime
  1349. *
  1350. * @return object TimeStamp
  1351. * @access public
  1352. * @since 5/5/05
  1353. */
  1354. function asTimeStamp () {
  1355. $obj =$this->asA('TimeStamp');
  1356. return $obj;
  1357. }
  1358. /**
  1359. * Answer a DateAndTime equivalent to the reciever, but at UTC (offset = 0)
  1360. *
  1361. * @return object DateAndTime
  1362. * @access public
  1363. * @since 5/4/05
  1364. */
  1365. function asUTC () {
  1366. $obj =$this->utcOffset(Duration::withHours(0));
  1367. return $obj;
  1368. }
  1369. /**
  1370. * Answer the week that represents this date's week
  1371. *
  1372. * @return object Week
  1373. * @access public
  1374. * @since 5/5/05
  1375. */
  1376. function asWeek () {
  1377. $obj = Week::starting($this);
  1378. return $obj;
  1379. }
  1380. /**
  1381. * Answer the year that represents this date's year
  1382. *
  1383. * @return object Year
  1384. * @access public
  1385. * @since 5/5/05
  1386. */
  1387. function asYear () {
  1388. $obj = Year::starting($this);
  1389. return $obj;
  1390. }
  1391. /**
  1392. * Return a Timespan where the receiver is the middle of the Duration
  1393. *
  1394. * @param object Duration $aDuration
  1395. * @return object Timespan
  1396. * @access public
  1397. * @since 5/12/05
  1398. */
  1399. function middleOf ( $aDuration ) {
  1400. $duration =$aDuration->asDuration();
  1401. $obj = Timespan::startingDuration(
  1402. $this->minus($duration->dividedBy(2)),
  1403. $duration);
  1404. return $obj;
  1405. }
  1406. /**
  1407. * Answer a <DateAndTime> equivalent to the receiver but offset from UTC by
  1408. * aDuration. This will not convert the recievers time, merely change the
  1409. * offset to anOffset; i.e. 11am at UTC-05:00 would become 11am at UTC-7:00
  1410. * when -7 hours is passed as the offset.
  1411. *
  1412. * @param object Duration $aDuration
  1413. * @return object DateAndTime
  1414. * @access public
  1415. * @since 5/4/05
  1416. */
  1417. function withOffset ( $anOffset ) {
  1418. $class = get_class($this);
  1419. $equiv = new $class;
  1420. $equiv->ticksOffset($this->ticks(), $anOffset->asDuration());
  1421. return $equiv;
  1422. }
  1423. /**
  1424. * Answer a Timespan. anEnd conforms to protocol DateAndTime or protocol Timespan
  1425. *
  1426. * @param object DateAndTime $anEnd
  1427. * @return object Timespan
  1428. * @access public
  1429. * @since 5/12/05
  1430. */
  1431. function to ( $anEnd ) {
  1432. $obj = Timespan::startingEnding($this, $anEnd->asDateAndTime());
  1433. return $obj;
  1434. }
  1435. /**
  1436. * Answer a Timespan. anEnd conforms to protocol DateAndTime or protocol Timespan
  1437. *
  1438. * @param object DateAndTime $anEnd
  1439. * @param object Duration
  1440. * @return object Schedule
  1441. * @access public
  1442. * @since 5/12/05
  1443. */
  1444. function toBy ( $anEnd, $aDuration ) {
  1445. $schedule = Schedule::startingEnding($this, $anEnd->asDateAndTime());
  1446. $schedule->addToSchedule(array($aDuration->asDuration()));
  1447. return $schedule;
  1448. }
  1449. /**
  1450. * Answer a <DateAndTime> equivalent to the receiver but offset from UTC by
  1451. * aDuration. This will convert the recievers time, to the time at anOffset;
  1452. * i.e. 11am at UTC-05:00 would become 9am at UTC-7:00 when -7 hours is passed
  1453. * as the offset.
  1454. *
  1455. * @param object Duration $aDuration
  1456. * @return object DateAndTime
  1457. * @access public
  1458. * @since 5/4/05
  1459. */
  1460. function utcOffset ( $anOffset ) {
  1461. $duration =$anOffset->asDuration();
  1462. $equiv =$this->plus($duration->minus($this->offset()));
  1463. $equiv->ticksOffset($equiv->ticks(), $duration);
  1464. return $equiv;
  1465. }
  1466. }
  1467.  
  1468. require_once(dirname(__FILE__)."/ChronologyConstants.class.php");
  1469. require_once(dirname(__FILE__)."/Date.class.php");
  1470. require_once(dirname(__FILE__)."/Duration.class.php");
  1471. require_once(dirname(__FILE__)."/Month.class.php");
  1472. require_once(dirname(__FILE__)."/Time.class.php");
  1473. require_once(dirname(__FILE__)."/TimeStamp.class.php");
  1474. require_once(dirname(__FILE__)."/TimeZone.class.php");
  1475. require_once(dirname(__FILE__)."/Week.class.php");
  1476. require_once(dirname(__FILE__)."/Year.class.php");
  1477.  
  1478. ?>

Documentation generated on Wed, 19 Sep 2007 10:22:34 -0400 by phpDocumentor 1.3.0RC3