This is Julian.m in view mode; [Download] [Up]
#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
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.