home *** CD-ROM | disk | FTP | other *** search
- #import "Julian.h"
- #import <math.h>
- #import <stdlib.h>
- #import <sys/time.h>
- #import <stdio.h>
- @implementation Julian
-
- // getEasterDay will only work for years between 1900 and 2099.
- // It takes a year and gives the day and month for easterDay
-
- + (void) getEasterDay :(int ) year
- :(int *) day
- :(int *) month
-
- {
- int a,b,c,d,e,s,t,theDay,theMonth;
-
- a = year % 19;
- b = year % 4;
- c = year % 7;
- s = 19*a+24;
- d = s % 30;
- t = 2*b+4*c+6*d+5;
- e = t % 7;
- theDay = 22+d+e;
- if (theDay >= 32) {
- theMonth = 4;
- theDay= d+e-9;
- if (theDay == 26) {
- theDay = 19;
- }
- else {
- if (theDay == 25 && a == 16 && d == 28) {
- theDay = 18;
- }
- }
- }
- else {
- theMonth = 3;
- }
-
- *day = theDay;
- *month = theMonth;
-
- return;
- }
-
-
- + (double) getCurrentDate
- {
- int mon,mday,year,hr,min,sec,dow;
- long theDate;
- double theDDate;
-
- struct timeval tp;
- struct timezone tz;
- struct tm *theTime;
- gettimeofday(&tp, &tz);
- theTime = localtime(&(tp.tv_sec));
-
- theDDate = [Julian julianDay:theTime->tm_mday
- :theTime->tm_mon+1
- :theTime->tm_year+1900
- :theTime->tm_hour
- :theTime->tm_min
- :theTime->tm_sec];
-
- theDate = [Julian julianDay:theTime->tm_mday
- :theTime->tm_mon+1
- :theTime->tm_year+1900];
-
- #ifdef DEBUG
- printf("the date is %f\n",theDDate);
- #endif
-
- [Julian calendarDay:theDDate:&mday:&mon:&year:&hr:&min:&sec];
-
- dow = [Julian dow:theDate];
-
- #ifdef DEBUG
- printf(" mm/dd/yy hh:mm:ss = %02i/%02i/%04i %02i:%02i:%02i and dow = %i\n"
- ,mon,mday,year,hr,min,sec,dow);
- #endif
-
- return theDDate;
- }
-
-
-
- // Given a day month and year, calculate the julian date.
- + (double) julianDay:(int) day :(int) month :(int) year
- {
- int a,b;
- double retVal;
-
- float yearCorr;
-
- //Correct for negitive year
- yearCorr = (year > 0? 0.0 : 0.75);
- if( month <= 2)
- {
- year--;
- month += 12;
- }
- b = 0;
- //Deal with Gregorian reform
- if( (year * 10000.0) + (month * 100.0) + day >= 15821015.0)
- {
- a = year / 100;
- b = (2-a)+(a/4);
- }
-
- retVal = (long) ( (365.25 * year) - yearCorr);
- retVal += (long) (30.6001 * (month+1));
- retVal += (long) day;
- retVal += 1720994L;
- retVal += (long) b;
- return(retVal);
- }
-
- + (double) julianDay :(int) day
- :(int) month
- :(int) year
- :(int) hour
- :(int) min
- :(int) sec
- {
- double retVal;
- double retFraction;
-
-
- retVal = [self julianDay:day:month:year];
-
- retFraction = (double)((double)hour/24.0)
- + (double)((double)min/1440.0)
- + (double)((double)sec/86400.0);
-
- return (retVal+retFraction);
- }
-
-
- //Given a julian date, calculate the month day and year.
- //The year will be Negitive if it's BC
- + (void) calendarDay :(double)julian
- :(int *) day
- :(int *) month
- :(int *) year
- {
- long a,b,c,d,e,z, alpha;
-
- z = julian + 1;
- //Deal with Gregorian reform
- if( z < 2299161L)
- a = z;
- else
- {
- alpha = (long) (( z - 1867216.25) / 36524.25);
- a = z + 1 + alpha - alpha / 4;
- }
- b = a + 1524;
- c = (long) (( b - 122.1) / 365.25);
- d = (long) (365.25 * c);
- e = (long) (( b - d ) / 30.6001);
- *day = (int) b - d - (long) (30.6001 * e);
- *month = (int) ( e < 13.5) ? e - 1 : e - 13;
- *year = (int) (*month > 2.5) ? (c - 4716) : c - 4715;
- }
-
- + (void) calendarDay :(double) julian
- :(int *) day
- :(int *) month
- :(int *) year
- :(int *) hour
- :(int *) min
- :(int *) sec
- {
- double fractionalPart;
- double tmpResult;
- double integerPart;
-
- [self calendarDay :(long) julian
- : day
- : month
- : year];
- //days.fractionalDays
- fractionalPart = modf((double)julian,&integerPart);
-
- tmpResult = fractionalPart * 24.0;
- fractionalPart = modf(tmpResult,&integerPart);
- *hour = (int) integerPart;
-
- tmpResult = fractionalPart * 60.0;
- fractionalPart = modf(tmpResult,&integerPart);
- *min = (int) integerPart;
-
- tmpResult = fractionalPart * 60.0;
- fractionalPart = modf(tmpResult,&integerPart);
- *sec = (int) integerPart;
-
- }
-
- //See if the passed in date is a Valid date
- // I.E. Feb 29 on a non leap year is NOT valid
- // returns YES if date is OK
- + (BOOL) validDay :(int) day
- :(int) month
- :(int) year
- {
- int calDay;
- int calMonth;
- int calYear;
-
- //convert it to julian
- [self calendarDay:[self julianDay:day:month:year]
- : &calDay
- : &calMonth
- : &calYear];
-
- return(( day == calDay) && (month == calMonth) && (year == calYear) );
-
- }
-
-
-
- + (BOOL) validDay :(int) day
- :(int) month
- :(int) year
- :(int) hour
- :(int) min
- :(int) sec
- {
- int calDay;
- int calMonth;
- int calYear;
- int calHour;
- int calMin;
- int calSec;
-
- //convert it to julian
- [self calendarDay:[self julianDay:day:month:year:hour:min:sec]
- : &calDay
- : &calMonth
- : &calYear
- : &calHour
- : &calMin
- : &calSec];
- return( (day == calDay)
- && (month == calMonth)
- && (year == calYear)
- && (hour == calHour)
- && (min == calMin)
- && (sec == calSec)
- );
- }
-
- //0=Sunday 2 = Monday .... 6 = Saturday
- + (int) dow:(long) julian
- {
- return (int) ((( julian + 2) % 7) + 1);
- }
-
- //week days from past dates
- + (double) wkd:(int) day
- :(int) month
- :(int) year
- {
- long d;
- double g;
- double f;
- double ans;
-
-
- g = (month > 2) ? year : year-1;
- f = (month > 2) ? month + 1 : month + 13;
-
-
- d = day - (int) ( 0.75* (int) (g/100.0)-7) +
- (int) (365.25*g) + (int) (30.6*f);
-
- d-=2;
- ans = (5* (int) (d/7)) + (0.5*(int) (1.801* (d % 7)));
- return ans;
- }
-
-
-
-
- // Day of year
- + (int) doy:(int) day
- :(int) month
- :(int) year
- {
- double curJulianDay;
- double janJulianDay;
-
- curJulianDay =[Julian julianDay:(int) day
- :(int) month
- :(int) year];
-
- janJulianDay = [Julian julianDay:(int) 1
- :(int) 1
- :(int) year];
-
- return (int) ( (curJulianDay - janJulianDay) + 1.0);
- }
-
-
-
- //instance methods
-
- - init;
- {
- julianDayVal = 0.0;
- return self;
- }
- - (BOOL) initDay
- :(int) month
- :(int) day
- :(int) year
- {
- [super init];
- return [self setJulianDay:month:day:year];
- }
-
- - (BOOL) initDay
- :(int) month
- :(int) day
- :(int) year
- :(int) hour
- :(int) min
- :(int) sec
- {
- [super init];
- return [ self setJulianDay
- :month
- :day
- :year
- :hour
- :min
- :sec];
- }
-
- - read:(NXTypedStream *)stream
- {
- [super read:stream];
- /* class-specific code goes here */
- NXReadType(stream,"d",&julianDayVal);
-
- return self;
- }
-
- - write:(NXTypedStream *)stream
- {
- [super write:stream];
- /* class-specific archiving code goes here */
- NXWriteType(stream,"d",&julianDayVal);
- return self;
- }
-
- - (double) getJulianDay
- {
- return julianDayVal;
- }
-
-
-
- - (BOOL) setJulianDay :(double) day
- {
- julianDayVal = day;
- return YES;
- }
-
-
- - (BOOL) setJulianDay :(int) month
- :(int) day
- :(int) year
- {
- if( [Julian validDay :(int) day
- :(int) month
- :(int) year])
- {
- julianDayVal = [Julian julianDay:(int) month
- :(int) day
- :(int) year];
- return YES;
- }
- return NO;
- }
-
- - (BOOL) setJulianDay :(int) day
- :(int) month
- :(int) year
- :(int) hour
- :(int) min
- :(int) sec
- {
- if( [Julian validDay :(int) month
- :(int) day
- :(int) year
- :(int) hour
- :(int) min
- :(int) sec])
- {
- julianDayVal = [Julian validDay
- :(int) month
- :(int) day
- :(int) year
- :(int) hour
- :(int) min
- :(int) sec];
- return YES;
- }
- return NO;
- }
-
- - getCalendarDay :(int*) month
- :(int*) day
- :(int*) year
- {
- [Julian calendarDay : julianDayVal
- : day
- : month
- : year];
- return self;
- }
-
-
-
- - getCalendarDay :(int*) month
- :(int*) day
- :(int*) year
- :(int*) hour
- :(int*) min
- :(int*) sec
- {
- [Julian calendarDay : julianDayVal
- : day
- : month
- : year
- : hour
- : min
- : sec];
-
- return self;
- }
-
-
- @end
-