//
//	MiscTime.m -- a generic class to simplify manipulation of times
//		Written by Don Yacktman Copyright (c) 1993 by Don Yacktman.
//				Version 1.2.  All rights reserved.
//
//		This notice may not be removed from this source code.
//
//		This is a free object!  Contact the author for the latest version.
//		Don Yacktman, 4279 N. Ivy Lane, Provo, UT, 84604
//		e-mail:  Don_Yacktman@byu.edu
//
//	This object is included in the MiscKit by permission from the author
//	and its use is governed by the MiscKit license, found in the file
//	"LICENSE.rtf" in the MiscKit distribution.  Please refer to that file
//	for a list of all applicable permissions and restrictions.
//	

	// *****  denotes an unfinished/unimplemented method.

#import <misckit/misckit.h>
#import <sys/time.h>

// a few functions to handle date wierdnesses

//	seconds per minute
#define	SPM	60 
//	seconds per hour
#define	SPH	(60*SPM)
//	seconds per day
#define	SPD	(24*SPH)
//	non-leap days per year
#define	DPY	365
//	month per year
#define	MPY	12
#define	BaseYear	1970
// Maximum days in a year
#define	MX_DPY	366

const short	d2m[]={0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};	//days to month

const short	d2ml[]={ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335};//days to month Leap

static int isLeapYear(int year)
{ // shorter version:
	return !(year%400) || (!(year%4) && !!(year%100));
/*
	if ( year % 400 == 0 ) return 1;	// 2000 is a leap year
	if ( year % 100 == 0 ) return 0;	// 1900 is not a leap year
	if ( year %   4 == 0)  return 1;	// 1996 is a leap year
	return 0;				// 1994 is not a leap year
*/
}

static int Misc_daysUpTo(int month, int year)
{
	if (month < 2) return d2m[month];
	return (d2m[month] + (isLeapYear(year) ? 1 : 0));
}

static int Misc_daysIn(int month, int year)
{
	int array[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
	if (month != 1) return array[month];
	return (array[month] + (isLeapYear(year) ? 1 : 0));
}

@implementation MiscTime

+ initialize
{
	if ( self == [MiscTime class] ) [MiscTime setVersion:1];
	return self;
}

+ (int)daysInMonth:(int)aMonth ofYear:(int)aYear
{
	return Misc_daysIn(aMonth, aYear);
}

+ (int)daysUpToMonth:(int)aMonth ofYear:(int)aYear
{
	return Misc_daysUpTo(aMonth, aYear);
}

+ (int)isLeapYear:(int)aYear
{
	return isLeapYear(aYear);
}

- init
{
	id ret;
	if (!_initted) ret = [super init];
	else ret = self;
	_initted = YES;
	dow = MISC_TIME_UNKNOWN_DOW;
	if (!myStringValue) myStringValue = (char *)malloc(256);
	year = 0; day = 0; month = 0; hour = 0;
	minute = 0; second = 0; microsecond = 0;
	isRelative = NO;
	return ret;
}

- initWithCurrentTime
{
	struct timeval tp;
	struct timezone tzp;
	struct tm *tv;
	
	id ret = [self init];

	gettimeofday(&tp, &tzp);
	tv = localtime(&tp.tv_sec);
	
	microsecond = tp.tv_usec;
	second = tv->tm_sec;
	minute = tv->tm_min;
	hour   = tv->tm_hour;
	day    = tv->tm_mday - 1;
	dow    = tv->tm_wday;
	month  = tv->tm_mon;
	year   = tv->tm_year + 1900;
	return ret;
}

- initWithTime_t: (time_t)aTime
{
	id  ret = [self init];
	struct tm  *tv;
	
	tv = localtime ((const time_t *)&aTime);
	microsecond = 0;
	second = tv->tm_sec;
	minute = tv->tm_min;
	hour   = tv->tm_hour;
	day    = tv->tm_mday - 1;
	dow    = tv->tm_wday;
	month  = tv->tm_mon;
	year   = tv->tm_year + 1900;
	return ret;
}

/* This is the original

- calcDayOfWeek
{
	// Fill in a struct tm and let mktime figure out the day of the week.
	// (0 = Sunday)
	struct tm tm;
	time_t t;
	
	tm.tm_sec = second;
	tm.tm_min = minute;
	tm.tm_hour = hour;
	tm.tm_mday  = day + 1;
	tm.tm_mon = month;
	tm.tm_year = year - 1900;
	
	t = mktime(&tm);
	
	// Upon succesful completion of mktime(), the tm_mday and tm_wday fields
	// are set correctly. Record the day of the week.
	
	dow = tm.tm_wday;
	
	return self;
}
*/
/*	This is an alternate version by Kurt Werle.  Which is better?
	Does it even matter?

- calcDayOfWeek
{
	// I need the next two just to get timezone info
	struct timeval tp;
	struct timezone tzp;

	struct tm tv;
	time_t realtime;
	
	tv.tm_sec = second;
	tv.tm_min = minute;
	tv.tm_hour = hour;
	tv.tm_mday = day + 1;
	tv.tm_mon = month;
	tv.tm_year = year - 1900;

	gettimeofday(&tp, &tzp);
	tv.tm_gmtoff = localtime(&tp.tv_sec)->tm_gmtoff;

	realtime = mktime(&tv);
	dow = localtime(&realtime)->tm_wday;
	
	return self;
}
*/
/*	This is an alternate version by Carl Lindberg.  This is probably
	faster, but has the disadvantage of working only after the Gregorian
	calendar.  Seems to be more reliable than mktime() for dates _after_
	that, however.
	
	We're using it since it seems to have the fewest problems, though it
	is somewhat imperfect.  At least it works outside of the range of
	years from 1970 to 2037, which seems to be mktime's limit.  This one
	works fom 1752 onward.  (Note that the calendar changed in 1752...) 
*/
- calcDayOfWeek
{
	long tmonth = month+1;
	long tyear = year;
	long tday = day+1;
	long century;
	
	if ((tmonth == 1) || (tmonth == 2)) {
	  tmonth += 12;
	  tyear--;
	}
	tmonth -= 2;
	century = tyear / 100;
	tyear %= 100;
	dow = ((260 * tmonth - 19) / 100) + tday + tyear + (tyear / 4) 
	      + (century / 4) - (2 * century);
	dow %= 7;
	
	return self;
}


- setYear:(int)t { year = t; dow = MISC_TIME_UNKNOWN_DOW; return self; }
- setMonth:(int)t { month = t; dow = MISC_TIME_UNKNOWN_DOW; return self; }
- setDayOfWeek:(int)t { dow = t; return self; }
- setDay:(int)t { day = t; dow = MISC_TIME_UNKNOWN_DOW; return self; }
- setHour:(int)t { hour = t; return self; }
- setMinute:(int)t { minute = t; return self; }
- setSecond:(int)t { second = t; return self; }
- setMicrosecond:(int)t { microsecond = t; return self; }
- setRelative:(BOOL)t { isRelative = t; return self; }

- (int)_nintValue // ignores usecs.
{
	return ((((((year - 1970) * MISC_TIME_MAX_DAYS
				+ Misc_daysUpTo(month, year) + day)
				* MISC_TIME_MAX_HOURS) + hour)
				* MISC_TIME_MAX_MINUTES + minute)
				* MISC_TIME_MAX_SECONDS + second);
}
/*
- (int)intValue // # seconds since Jan 1, 1970
{ // rounds usec. and add in...
	return ([self _nintValue] +
				((microsecond < MISC_TIME_MAX_MICROSECONDS / 2) ? 0 : 1));
}
*/
- (double)doubleValue
{
	// *****
	return 0.0;
}

- (float)floatValue
{
	// *****
	return 0.0;
}


/*
 * Return a formatted string in the manner of strftime(), where
          %%   identical to %
          %a   abbreviated weekday name
          %A   full weekday name
          %b   abbreviated month name
          %B   full month name
          %c   time and date using the time and date representa-
               tion for the locale (%X %x)
          %d   day of the month as a decimal number (01-31)
          %H   hour based on a 24-hour clock as a decimal number
               (00-23)
          %I   hour based on a 12-hour clock as a decimal number
               (01-12)
          %j   day of the year as a decimal number (001-366)
          %m   month as a decimal number (01-12)
          %M   minute as a decimal number (00-59)
          %p   AM/PM designation associated with a 12-hour clock
          %S   second as a decimal number (00-61)
          %w   weekday as a decimal number (0-6), where Sunday is 0
          %x   date using the date representation for the locale
          %X   time using the time representation for the locale
          %y   year without century (00-99)
          %Y   year with century (e.g. 1990)
          %Z   time zone name or abbreviation, or no characters
               if no time zone is determinable.
*/

/*
 *  don't free the result!.  (need to rethink this to use MiscString or something
 *  instead of blindly allocating 256 chars.)
 */	       
- (const char *)format:(const char *)format
{ /* Warning:  This is buggy due to mktime() and strftime(), which may
	 crash your app!  Worse, mktime() ssems to only work for the range
	 of years between 1970 and 2037.  Be forewarned!  Anyone have a
	 better strftime() we can use instead?  That would help! */

    struct tm tm;
    
     
    if (!myStringValue) myStringValue = (char *)malloc(256);
    tm.tm_sec = second;
    tm.tm_min = minute;
    tm.tm_hour = hour;
    tm.tm_mday  = day + 1;
    tm.tm_mon = month;
    tm.tm_year = year - 1900;
    
    /*
     * this will calculate and fill in the day of week and day of year fields,
     * which we might need.
     */
    mktime(&tm);
    
    strftime( myStringValue, 256, format, &tm );
    
    return myStringValue;
}

- (const char *)stringValue
{ 	
	// For historical reasons we return things in this format, although
	// I think [self format:"%c"] would be better, which would produce
	// something appropriate for the locale.
	
	return [self format:"%H : %M : %S"];
	// old way:
	// Don't free this!  that's why it's a const!
	// if (!myStringValue) myStringValue = (char *)malloc(256);

	// sprintf(myStringValue, "%ld : %ld : %ld", hour, minute, second);
	// return myStringValue;
}

- free
{
	free(myStringValue);
	return [super free];
}

- (int)dayOfWeek
{
	if (dow < 0) [self calcDayOfWeek];
	return dow;
}

- (int)year { return year; }
- (int)month { return month; }
- (int)day { return day; }
- (int)hour { return hour; }
- (int)minute { return minute; }
- (int)second { return second; }
- (int)microsecond { return microsecond; }
- (BOOL)isRelative { return isRelative; }


- addTime:aTime
{
	if (![aTime isKindOf:[MiscTime class]]) return nil;
	[self addMicroseconds:[aTime microsecond]];
	[self addSeconds:[aTime second]];
	[self addMinutes:[aTime minute]];
	[self addHours:[aTime hour]];
	[self addDays:[aTime day]];
	[self addMonths:[aTime month]];
	[self addYears:[aTime year]];
	return self;
}

- subtractTime:aTime
{
	if (![aTime isKindOf:[MiscTime class]]) return nil;
	[self subtractMicroseconds:[aTime microsecond]];
	[self subtractSeconds:[aTime second]];
	[self subtractMinutes:[aTime minute]];
	[self subtractHours:[aTime hour]];
	[self subtractDays:[aTime day]];
	[self subtractMonths:[aTime month]];
	[self subtractYears:[aTime year]];
	return self;
}

- addMicroseconds:(long)t
{
	long x = [self microsecond] + t;
	if (!t) return self;
	[self setMicrosecond:(x % MISC_TIME_MAX_MICROSECONDS)];
	[self addSeconds:(x / MISC_TIME_MAX_MICROSECONDS)];
	return self;
}

- addSeconds:(long)t
{
	long x = [self second] + t;
	if (!t) return self;
	[self setSecond:(x % MISC_TIME_MAX_SECONDS)];
	[self addMinutes:(x / MISC_TIME_MAX_SECONDS)];
	return self;
}

- addMinutes:(long)t
{
	long x = [self minute] + t;
	if (!t) return self;
	[self setMinute:(x % MISC_TIME_MAX_MINUTES)];
	[self addHours:(x / MISC_TIME_MAX_MINUTES)];
	return self;
}

- addHours:(long)t
{
	long x = [self hour] + t;
	if (!t) return self;
	[self setHour:(x % MISC_TIME_MAX_HOURS)];
	[self addDays:(x / MISC_TIME_MAX_HOURS)];
	return self;
}

- addDays:(long)t
{
	long x = [self day] + t; int k;
	if (!t) return self;
	
	k = Misc_daysIn(month, year);
	while (x >= k) { // This is slow, but it works.
		[self addMonths:1];
		x -= k; k = Misc_daysIn(month, year);
	}
	[self setDay:(x % MISC_TIME_MAX_DAYS)];
	return self;
}

- addWeeks:(long)t
{
	return [self addDays:(t * 7)];
}

- addMonths:(long)t
{
	long x = [self month] + t;
	if (!t) return self;
	[self setMonth:(x % MISC_TIME_MAX_MONTHS)];
	[self addYears:(x / MISC_TIME_MAX_MONTHS)];
	return self;
}

- addYears:(long)t
{
	if (t) [self setYear:([self year] + t)];
	return self;
}

- (BOOL)isAfter:aTime
{ // returns YES if we are "older" than time passed in
	int si = [self _nintValue];
	int oi = [aTime _nintValue];
	if (si > oi) return YES;
	if ((si == oi) && ([self microsecond] > [aTime microsecond])) return YES;
	return NO;
}

- (BOOL)isEqual:aTime
{ // returns YES if we are "same" as time passed in
	if (([self _nintValue] == [aTime _nintValue]) &&
			([self microsecond] == [aTime microsecond])) return YES;
	return NO;
}

- subtractMicroseconds:(long)t
{
	long us = t % MISC_TIME_MAX_MICROSECONDS;
	long s = t / MISC_TIME_MAX_MICROSECONDS;
	long sus = [self microsecond];
	if (us > sus) { s++; sus += MISC_TIME_MAX_MICROSECONDS; }
	[self subtractSeconds:s];
	[self setMicrosecond:(sus - us)];
	return self;
}

- subtractSeconds:(long)t
{
	long s = t % MISC_TIME_MAX_SECONDS;
	long m = t / MISC_TIME_MAX_SECONDS;
	long ss = [self second];
	if (s > ss) { m++; ss += MISC_TIME_MAX_SECONDS; }
	[self subtractMinutes:m];
	[self setSecond:(ss - s)];
	return self;
}

- subtractMinutes:(long)t
{
	long m = t % MISC_TIME_MAX_MINUTES;
	long h = t / MISC_TIME_MAX_MINUTES;
	long sm = [self minute];
	if (m > sm) { h++; sm += MISC_TIME_MAX_MINUTES; }
	[self subtractHours:h];
	[self setMinute:(sm - m)];
	return self;
}

- subtractHours:(long)t
{
	long h = t % MISC_TIME_MAX_HOURS;
	long d = t / MISC_TIME_MAX_HOURS;
	long sh = [self hour];
	if (h > sh) { d++; sh += MISC_TIME_MAX_HOURS; }
	[self subtractDays:d];
	[self setHour:(sh - h)];
	return self;
}

- subtractDays:(long)t
{
	long sd = [self day];
	while (t > sd) { // this is slow, but it works.
		[self subtractMonths:1];
		sd += Misc_daysIn(month, year);
	}
	[self setDay:(sd - t)];
	return self;
}

- subtractWeeks:(long)t
{
	return [self subtractDays:(t * 7)];
}

- subtractMonths:(long)t
{
	long m = t % MISC_TIME_MAX_MONTHS;
	long y = t / MISC_TIME_MAX_MONTHS;
	long sm = [self month];
	if (m > sm) { y++; sm += MISC_TIME_MAX_MONTHS; }
	[self subtractYears:y];
	[self setMonth:(sm - m)];
	return self;
}

- subtractYears:(long)t
{
	if (t) [self setYear:([self year] - t)];
	return self;
}

- copy
{
	id myCopy = [[[self class] alloc] init];
	[myCopy setYear:year];
	[myCopy setMonth:month];
	[myCopy setDay:day];
	[myCopy setDayOfWeek:dow];
	[myCopy setHour:hour];
	[myCopy setMinute:minute];
	[myCopy setSecond:second];
	[myCopy setMicrosecond:microsecond];
	[myCopy setRelative:isRelative];
	return myCopy;
}

- copyTimeFrom:aTime
{
	[self setYear:[aTime year]];
	[self setMonth:[aTime month]];
	[self setDay:[aTime day]];
	[self setDayOfWeek:[aTime dayOfWeek]];
	[self setHour:[aTime hour]];
	[self setMinute:[aTime minute]];
	[self setSecond:[aTime second]];
	[self setMicrosecond:[aTime microsecond]];
	[self setRelative:[aTime isRelative]];
	return self;
}

- read:(NXTypedStream *)stream
{
    int version;
	[super read:stream];
    version = NXTypedStreamClassVersion(stream, [MiscTime name]);
	NXReadTypes(stream, "cllllllll", &isRelative, &microsecond, &second,
			&minute, &hour, &dow, &day, &month, &year);
	if (!myStringValue) myStringValue = (char *)malloc(256);
	if (version < 1) year += 1900;
	return self;
}

- write:(NXTypedStream *)stream
{
	[super write:stream];
	NXWriteTypes(stream, "cllllllll", &isRelative, &microsecond, &second,
			&minute, &hour, &dow, &day, &month, &year);
	return self;
}

// NXTransport protocol implementation:
- encodeUsing:(id <NXEncoding>)portal
{
	[portal encodeData:&isRelative  ofType:"c"];
	[portal encodeData:&microsecond ofType:"i"];
	[portal encodeData:&second      ofType:"i"];
	[portal encodeData:&minute      ofType:"i"];
	[portal encodeData:&hour        ofType:"i"];
	[portal encodeData:&dow         ofType:"i"];
	[portal encodeData:&day         ofType:"i"];
	[portal encodeData:&month       ofType:"i"];
	[portal encodeData:&year        ofType:"i"];
	return self;
}

- decodeUsing:(id <NXDecoding>)portal
{
	[portal decodeData:&isRelative  ofType:"c"];
	[portal decodeData:&microsecond ofType:"i"];
	[portal decodeData:&second      ofType:"i"];
	[portal decodeData:&minute      ofType:"i"];
	[portal decodeData:&hour        ofType:"i"];
	[portal decodeData:&dow         ofType:"i"];
	[portal decodeData:&day         ofType:"i"];
	[portal decodeData:&month       ofType:"i"];
	[portal decodeData:&year        ofType:"i"];
	return self;
}

- encodeRemotelyFor:(NXConnection *)connection
	freeAfterEncoding:(BOOL *)flagp isBycopy:(BOOL)isByCopy
{
	if (isByCopy) {
		*flagp = NO; // object will copy.
		return self; //encode object (copy it)
	}
	*flagp = NO; // object will copy.
	// super will encode the proxy otherwise
	return [super encodeRemotelyFor:connection
				freeAfterEncoding:flagp isBycopy:isByCopy];
}

// Stefan's stuff

#define	compLn(date,form)	([form charAt:1]? [date spotOf:[form charAt:1]]: [date length])

int	membersInIntv(int lft,int rgt, int intv)	//left closed, right open
{	return rgt/intv-lft/intv+!(lft%intv)-!(rgt%intv);
}

int	daysUntilMonthInYear(int mon,int y)
{	return isLeapYear(y)? d2ml[mon]: d2m[mon];
}

int leapYearsInInterv(int yearSt, int yearSp)
{	return	membersInIntv(yearSt,yearSp,4)-
			membersInIntv(yearSt,yearSp,100)+
			membersInIntv(yearSt,yearSp,400);
}

int	daysUntilYear(int year)
{	return (year-BaseYear)*DPY + leapYearsInInterv(BaseYear,year);
}

int	daysOfYear(int year)
{
	return DPY + isLeapYear(year);
}

int	yearOfDays(int days)
{	int	sgn=days>=0? 1: -1,adj=days>=0? 0: -1;
	int	y=BaseYear,dc=0,dy,diff;

	do{	y+=(days-dc)/MX_DPY;	//underestimate count of years for the days given
		dy=daysOfYear(y+adj);
		dc=daysUntilYear(y);	//calc actual no.of day until estimated year
		if (days<dc || dy<=days-dc)	//adjust one further year to avoid infitiy loops
			dc+=sgn*dy,y+=sgn;
	} while (!((diff=days-dc)>=0 && diff<dy));	//break if remaining days lie in cur.year
	return y;
}

int	makeTimeDays(int day,int mon,int year)
{	int	days=daysUntilMonthInYear(mon,year) + day;
	return days + daysUntilYear(year);
}

int	makeTimeSec(int sec,int min,int hour,int day,int mon,int year)
{	return (sec + min*SPM + hour*SPH) + makeTimeDays(day,mon,year)*SPD;
}

int	searchArray(const short *arr,short val,short arrSize)
{	short	min=0,max=arrSize,mid=0,c=0;

	while (min<=max && (c=arr[mid=(min+max)/2])!=val)
		if (c<val) min=mid+1; else max=mid-1;
	return c==val? mid: min-1;
}

int	monOfDaysInYear(int day,int y)
{	if (day<0) day+=daysOfYear(y);
	return searchArray(isLeapYear(y)? d2ml: d2m,day,MPY-1);
}

typedef struct {
	int	day;
	int	month;
	int	year;
} DateVec;

DateVec	splitTime(int days)
{	DateVec	dv;
	dv.year=yearOfDays(days), days-=daysUntilYear(dv.year);
	dv.month=monOfDaysInYear(days,dv.year), days-=daysUntilMonthInYear(dv.month,dv.year);
	dv.day=days;
	return dv;
}

DateVec	splitTime_(int days)
{	DateVec	dv=splitTime(days);
	dv.day++,dv.month++;
	return dv;
}

/*
int makeDays_(int day,int month,int year)
{
	return makeDays(day,month-1,year-1900);
}
*/

int	makeDays_(DateVec d) { return makeTimeDays(d.day,d.month-1,d.year-1900); }

- setDaysSince1970:(int) n
{	[self init];
	[self setYear:1970];
	((n > 0) ? [self addDays:n] : [self subtractDays:-n]);
	return self;
}

-(int) daysSince1970
{	return makeTimeDays(day,month,year);
}

- setFromFormat:(const char *)formatString andDateString:(const char *)dateString
{	MiscString	*format=[[MiscString alloc] initString:formatString],
				*date  =[[MiscString alloc] initString:  dateString],
				*currStr,*newString;
	List		*felems=[format tokenize:"%" into:nil];
	int			 i,compLength;

	format=[format free];

	for (i=0; currStr=[felems objectAt:i]; i++)
	{	if ([currStr charAt:0]=='d')
		{	newString=[date left:compLength=compLn(date,currStr)];
			[self setDay:[newString intValue]-1];
			newString=[newString free];
			newString=[date right:[date length]-compLength-1],[date free],date=newString;
		} else if ([currStr charAt:0]=='m')
		{	newString=[date left:compLength=compLn(date,currStr)];
			[self setMonth:[newString intValue]-1];
			newString=[newString free];
			newString=[date right:[date length]-compLength-1],[date free],date=newString;
		} else if ([currStr charAt:0]=='y')
		{	newString=[date left:compLength=compLn(date,currStr)];
			[self setYear:[newString intValue]+1900];
			newString=[newString free];
			newString=[date right:[date length]-compLength-1],[date free],date=newString;
		}
		else if ([currStr charAt:0]=='H')
		{	newString=[date left:compLength=compLn(date,currStr)];
			[self setHour:[newString intValue]-1];
			newString=[newString free];
			newString=[date right:[date length]-compLength-1],[date free],date=newString;
		} else if ([currStr charAt:0]=='M')
		{	newString=[date left:compLength=compLn(date,currStr)];
			[self setMinute:[newString intValue]];
			newString=[newString free];
			newString=[date right:[date length]-compLength-1],[date free],date=newString;
		} else if ([currStr charAt:0]=='S')
		{	newString=[date left:compLength=compLn(date,currStr)];
			[self setSecond:[newString intValue]];
			newString=[newString free];
			newString=[date right:[date length]-compLength-1],[date free],date=newString;
		}



	} [[felems freeObjects] free], date=[date free];
	return self;
}

-(int) daysSinceYear:(int)byear dayOffset:(int) doff
{
	return makeTimeDays(day+doff,month,year);//, byear);
}

-(int) daysSinceYear:(int)byear
{
	return [self daysSinceYear:byear dayOffset:0];
}

-(int) timeForQuantrix
{
	return [self daysSinceYear:1900 dayOffset:2];
}

- (void)setFromDateVec:(DateVec)dv
{	[self setYear:dv.year];
	[self setMonth:dv.month];
	[self setDay:dv.day];
}

// bug fix (replaces old method)
-(int) intValue
{	return makeTimeSec(second,minute,hour,day,month,year);
}

- setIntValue:(int)n
{
	[self init];
	[self setFromDateVec:splitTime(n/SPD)];
	return self;
}

- (time_t)time_t
{	struct tm tm={0};	

	tm.tm_sec = second;
	tm.tm_min = minute;
	tm.tm_hour = hour;
	tm.tm_mday  = day + 1;
	tm.tm_mon = month;
	tm.tm_year = year - 1900;

	return mktime(&tm);
}

static MiscTime *currTime;

+ currentTime
{	if(!currTime) currTime=[[MiscTime alloc] initWithCurrentTime];
	else [currTime initWithCurrentTime];

	return currTime;
}

@end
