<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Ondrej Jombik <nepto@pobox.sk> |
// +----------------------------------------------------------------------+
//
// $Id: Week_Magic.php,v 1.4 2002/05/29 19:40:05 jombik9 Exp $
/**
* Date_Week_Magic - ISO 8601 implemetation
*
* This package implements ISO 8601 specification. It can count week and day
* number for specified date. It can also count date of Monday for
* specified week in year.
*
* Usage:
* <?php
* require_once 'Date/Week_Magic.php';
*
* // First example
* $day = 1;
* $month = 6;
* $year = 1981;
* $ar = Date_Week_Magic::week($year, $month, $day);
*
* echo "Date $day/$month/$year was day $ar[weekday] in week $ar[week].";
*
* // Second example
* $week = 50;
* $year = 1998;
* $ar = Date_Week_Magic::monday($year, $week);
*
* echo "Monday of week $week in year $year was $ar[day]/$ar[month].";
* ?>
*
* @author Ondrej Jombik <nepto@pobox.sk>
* @package Date_Week_Magic
* @version 0.1
* @access public
*/
class Date_Week_Magic
{
/**
* Validate date
*
* Validate passed date.
*
* @access public
* @param int $year year (allowed forms: YYYY, YY)
* @param int $month month (from 1 to 12)
* @param int $day day (from 1 to 31)
* @return bool true if is valid date, false otherwise
*/
function validate($year, $month, $day)
{
$timeNowInSeconds = mktime(0, 0, 0, $month, $day, $year);
$timeNow = localtime($timeNowInSeconds, 1 /* associative */);
if ((($timeNow['tm_year'] >= 100 && $timeNow['tm_year'] - 100 == $year)
|| ($timeNow['tm_year'] < 100 && $timeNow['tm_year'] == $year)
|| (1900 + $timeNow['tm_year'] == $year))
&& $timeNow['tm_mon'] + 1 == $month
&& $timeNow['tm_mday'] == $day)
{
return true;
}
return false;
}
/**
* Get week information for date
*
* Method returns associative array with two keys: week and weekday.
* Key week contain week number (from 1 to 53) and weekday contain week
* day number. First day of week is Monday with value of 1. Sunday
* have value 7. 0 is undefined. On error, false is returned.
*
* @access public
* @param int $year year (allowed forms: YYYY, YY)
* @param int $month month (from 1 to 12)
* @param int $day day (from 1 to 31)
* @return array 'week' => week number
* 'weekday' => week day (1 - Mon, 7 - Sun)
* on error false is returned
*/
function week($year, $month, $day)
{
if (Date_Week_Magic::validate($year, $month, $day) == false) {
return false;
}
$timeNow = localtime(mktime(0, 0, 0, $month, $day, $year),
1 /* associative */);
// Function localtime() 'tm_yday' 0 based, we need it 1 based.
$YearDay_I = $timeNow['tm_yday'] + 1;
$yearNow = $timeNow['tm_year'];
// American weeks begin on Sundays. ISO doesn't.
$WeekDay_I = $timeNow['tm_wday'];
if (0 == $WeekDay_I) { // if it's Sunday
$WeekDay_I = 7; // make it Sunday
}
$WeekNo_I = intval($YearDay_I / 7);
$FirstWeek_I = $YearDay_I % 7;
$FirstWeek_I -= $WeekDay_I;
if (($FirstWeek_I <= 0) && ($WeekNo_I > 0)) {
// Break up one week and add the days to FirstWeek_I.
$WeekNo_I--;
$FirstWeek_I += 7;
}
if ($FirstWeek_I > (-4)) {
$WeekNo_I += 1;
}
if ($FirstWeek_I > 3) {
$WeekNo_I += 1;
}
if ($WeekNo_I == 0) {
// Same as previous year's last day.
$ar = Date_Week_Magic::week($year - 1, 12 /* December is 12 */, 31);
$WeekNo_I = $ar['week'];
}
else if($WeekNo_I > 52) {
// The last days of the year.
if($WeekDay_I < 4 && $day > 28) {
// Three or less days of this year in 53 makes it week 1 instead!
$WeekNo_I = 1;
}
}
return array(
'week' => $WeekNo_I,
'weekday' => $WeekDay_I
);
}
/**
* Get day information for week
*
* Returns asssociative array with two keys: day and month. It is day and
* month of Monday of passed week and year. Note, that the first week can
* begin in the previous year.
*
* @access public
* @param int $year year (allowed forms: YYYY, YY)
* @param int $week week (from 1 to 53)
* @return array 'day' => day of Monday
* 'month' => month of Monday
* on error false is returned
*/
function monday($year, $week)
{
$day = 15;
while ($week > 53) {
$week -= 53;
}
$month = intval((11 * $week) / 53); // assume 53 weeks a year
while (1) {
$ar = Date_Week_Magic::week($year, $month + 1, $day);
if ($ar == false) {
$month++;
$day = 1;
continue;
}
$getweek = $ar['week'];
$getday = $ar['weekday'];
if (($getweek > $week - 3) && ($getweek < $week + 3)) {
if (($getweek == $week) && ($getday == 1)) {
break;
}
else {
if ($day == 1 && $month == 0) {
return false;
}
if ($getweek < $week) {
if ($week - $getweek > 1) {
$day += 7;
}
else {
$day += (8 - $getday);
}
}
else {
if ($getweek - $week > 1) {
$day -= 7;
}
else if ($getweek == $week) {
$day -= ($getday - 1);
}
else {
$day -= ($getday + 6);
}
if ($day <= 0) {
$day = 28;
$month--;
}
}
}
}
else {
if(++$month > 11) {
return false;
}
}
}
return array(
'day' => $day,
'month' => $month + 1
);
}
}
?>
Platon Group <platon@platon.sk> http://platon.sk/
|