home *** CD-ROM | disk | FTP | other *** search
- #import "Date.h"
- #import <appkit/appkit.h>
-
- #import <time.h>
- #import <stdlib.h>
- #import <stdio.h>
- #import <string.h>
- #import <math.h>
-
- #define OK 1
- #define CANCEL 2
- #define DATE_SIZE 18
- static const char *errNibPath = "DateError.nib";
- static const char *DayOfWeek[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
- static const char *MonthStr[] = {"Jan","Feb","Mar","Apr",
- "May","Jun","Jul","Aug",
- "Sep","Oct","Nov","Dec"};
- static BOOL parseError;
- static id dateField; // A TextField used to allow a user to edit incorrect dates
- static id selField; // A TextField used to display the method which invoked invalidDate
- static char tmpdateString[DATE_SIZE];
-
- @implementation Date
-
- /* Class methods */
- /* Used to get the SEL method for displaying which
- method called invalidDate: */
- + (const char *) selName : (SEL) theSEL
- {
- if(theSEL == @selector(initFromString:) )
- return "initFromString:";
- else if(theSEL == @selector(initFromDate:::) )
- return "initFromDate:::";
- else if(theSEL == @selector(initFromJulianDate:) )
- return "initFromJulianDate:";
- else
- return "NoMethod";
- }
-
- - setErrorMode : (int) mode
- {
- errorMode = mode;
- return self;
- }
-
- - free
- {
- if(dateString != NULL)
- NX_FREE(dateString);
- return [super free];
- }
-
- /* Parse a date string("mm/dd/yy[yy]") into its integer components */
- - parseDateString : (char *) dateStrng : (Day *) d : (Month *) m : (Year *) y
- {
- char tmpDate[16],*tmpDatePtr,*token;
- short yr,century;
- /* Assign the integer values to day,month,year */
- strcpy(tmpDate, dateStrng);
- tmpDatePtr = tmpDate;
- token = strtok(tmpDatePtr,"/");
- tmpDatePtr = NULL;
- if(token == NULL)
- {
- parseError = YES;
- *m = 0;
- }
- else
- *m = atoi(token);
- token = strtok(tmpDatePtr,"/");
- if(token == NULL)
- {
- parseError = YES;
- *d = 0;
- }
- else
- *d = atoi(token);
- token = strtok(tmpDatePtr,"/");
- if(token == NULL)
- {
- parseError = YES;
- *y = 0;
- }
- else
- *y = atoi(token);
- if(*y < 100)
- { // Get the current century
- [self now : NULL : NULL : &yr : NULL : NULL : NULL];
- century = yr - (yr % 100);
- (*y) += century;
- }
- return self;
- }
-
- /* The day, month & year must be set before calling */
- - (BOOL) validDate
- {
- short calDay,calMonth,calYear;
- long jDate;
- /* Convert date to Julian day number and back */
- jDate = [self julianRep : day : month : year];
- [self calendarDate : jDate : &calDay : &calMonth : &calYear];
- /* See if the date has changed */
- if(day != calDay)
- return NO;
- else if(month != calMonth)
- return NO;
- else if(year != calYear)
- return NO;
- else
- return YES;
- }
-
- - invalidDate : (SEL) callingMethod;
- {
- int rtnVal;
- static id editErrorPanel = nil;
- char dateStrng[16];
- switch(errorMode)
- {
- case 0 :
- return nil;
- break;
- case 1 :
- NXRunAlertPanel(NULL,"%d/%d/%d is not a valid date",
- NULL,NULL, NULL,month,day,year);
- return nil;
- break;
- case 2 :
- if(editErrorPanel == nil)
- editErrorPanel = [NXApp loadNibFile : errNibPath
- owner : self withNames : YES];
- if(parseError == YES)
- strcpy(dateStrng,dateString);
- else
- sprintf(dateStrng,"%d/%d/%d",month,day,year);
- /* Get the panel fields by name and initialize then */
- dateField = NXGetNamedObject("DateErrordateField", editErrorPanel);
- [dateField setStringValue : dateStrng];
- selField = NXGetNamedObject("DateErrorselField", editErrorPanel);
- [selField setStringValue : [Date selName : callingMethod]];
- /* Put the error panel in a modal loop */
- rtnVal = [NXApp runModalFor : editErrorPanel];
- [editErrorPanel orderOut : self];
- if(rtnVal == OK)
- {
- /* Assign the string representation */
- if(!dateString)
- NX_MALLOC(dateString,char,11);
- sprintf(dateString,"%d/%d/%d",month,day,year);
- /* Assign the Julian date representation*/
- date = [self julianRep : day : month : year];
- return self;
- }
- else
- return nil;
- break;
- default :
- return nil;
- }
- }
-
- /* Method invoked by the Ok button of the editErrorPanel */
- - dateOk : sender
- {
- parseError = NO;
- [self parseDateString : (char *) [dateField stringValue] : &day : &month : &year];
- if(parseError == YES || [self validDate] == NO)
- NXBeep();
- else
- [NXApp stopModal : OK];
- return self;
- }
- /* Method invoked by the ``Return nil'' button of the editErrorPanel */
- - dateCancel : sender
- {
- [NXApp stopModal : CANCEL];
- return self;
- }
-
- - initFromString : (char *) theDate
- {
- parseError = NO;
- [self parseDateString : theDate : &day : &month : &year];
- if(parseError == YES)
- {
- dateString = theDate;
- return [self invalidDate : _cmd];
- }
- if([self validDate] == NO)
- return [self invalidDate : _cmd];
-
- /* Assign the string representation */
- if(!dateString)
- NX_MALLOC(dateString,char,11);
- sprintf(dateString,"%d/%d/%d",month,day,year);
-
- /* Assign the Julian representation */
- date = [self julianRep : day : month : year];
-
- return self;
- }
-
- - initFromDate : (Day) d : (Month) m : (Year) y
- {
- short yr,century;
-
- /* Assign the integer values to day,month,year */
- day = d;
- month = m;
- if(y < 100)
- {
- [self now : NULL : NULL : &yr : NULL : NULL : NULL];
- century = yr - (yr % 100);
- y += century;
- }
- year = y;
- if([self validDate] == NO)
- return [self invalidDate : _cmd];
-
- /* Assign the Julian representation */
- date = [self julianRep : day : month : year];
-
- /* Assign the string representation */
- if(!dateString)
- NX_MALLOC(dateString,char,11);
- sprintf(dateString,"%d/%d/%d",month,day,year);
-
- return self;
- }
-
- - initFromJulianDate : (JulianDate) jDate
- {
- date = jDate;
- [self calendarDate : jDate : &day : &month : &year];
- if([self validDate] == NO)
- return [self invalidDate : _cmd];
- if(!dateString)
- NX_MALLOC(dateString,char,11);
- sprintf(dateString,"%d/%d/%d",month,day,year);
-
- return self;
- }
-
- - initFromNow
- {
-
- [self now : &day : &month : &year : &hours : &minutes : &seconds];
- /* Assign the Julian representation */
- date = [self julianRep : day : month : year];
-
- /* Assign the string representation */
- if(!dateString)
- NX_MALLOC(dateString,char,11);
- sprintf(dateString,"%d/%d/%d",month,day,year);
-
- return self;
- }
-
- - setTime : (short) hr : (short) min : (short) sec
- {
- hours = hr;
- minutes = min;
- seconds = sec;
- return self;
- }
-
- - (void) now : (Day *) d : (Month *) m : (Year *) y : (short *) hr : (short *) min : (short *) sec
- {
- struct tm *timeStruct;
- time_t now;
-
- time(&now);
- timeStruct = localtime(&now);
- /* Assign the integer values to day,month,year */
- if(d != NULL)
- *d = timeStruct->tm_mday;
- if(m != NULL)
- *m = timeStruct->tm_mon + 1;
- if(y != NULL)
- *y = timeStruct->tm_year + 1900;
- if(hr != NULL)
- *hr = timeStruct->tm_hour;
- if(min != NULL)
- *min = timeStruct->tm_min;
- if(sec != NULL)
- *sec = timeStruct->tm_sec;
- }
-
- - (long) sysTime
- {
- return time( (long *) 0);
- }
-
- /* Conversion functions */
- - calendarDate : (long) jDate : (Day *) dy : (Month *) m : (Year *) y
- {
- long a,b,c,d,e,z,alpha;
-
- /* Calculate the day, month and year */
- z = jDate + 1;
- 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);
- *dy = (Day) b - d - (long)(30.6001 * e);
- *m = (Month) (e < 13.5) ? e - 1 : e - 13;
- *y = (Year) (*m > 2.5) ? (c - 4716) : c - 4715;
-
- return self;
- }
-
- - (JulianDate) julianRep : (Day) d : (Month) m : (Year) y
- {
- int a,b;
- long jDate;
- float year_corr;
-
- /* Assign the Julian representation */
- year_corr = (y > 0 ? 0.0 : 0.75);
- if(m <= 2)
- {
- y --;
- m += 12;
- }
- b = 0;
- /* Cope with Greogrian calendar reform */
- if(y * 10000.0 + m * 100.0 + d >= 15821015.0)
- {
- a = y / 100;
- b = 2 - a + a / 4;
- }
- jDate = (JulianDate)(365.25 * y - year_corr) + (JulianDate)(30.6001 * (m+1)) +
- (JulianDate)(d + 1720994L + b);
- return jDate;
- }
-
- - (JulianDate) julianDate
- {
- return(date);
- }
-
- - (WeekDay) weekDay
- {
- // Return day : [0-6] = Sunday - Saturday
- return (WeekDay)((date + 2) % 7);
- }
-
- - (Day) day
- {
- return day;
- }
-
- - (Month) month
- {
- return((Month) month - 1);
- }
-
- - (Year) year
- {
- return((Year) year);
- }
- - (short) hours
- {
- return hours;
- }
- - (short) minutes
- {
- return minutes;
- }
- - (short) seconds
- {
- return seconds;
- }
-
- - (void) time : (short *) hr : (short *) min : (short *) sec
- {
- if(hr != NULL)
- *hr = hours;
- if(min != NULL)
- *min = minutes;
- if(sec != NULL)
- *sec = seconds;
- }
-
- - (const char *) stringDate
- {
- strcpy(tmpdateString,dateString);
- return tmpdateString;
- }
-
- - (const char *) stringFixedDate
- {
- sprintf(tmpdateString,"%.2d/%.2d/%.4d",month,day,year);
- return tmpdateString;
- }
-
- - (const char *) fullStringDate
- {
- sprintf(tmpdateString,"%s %s %.2d %.4d",
- DayOfWeek[[self weekDay]],MonthStr[month-1],day,year);
- return tmpdateString;
- }
-
- - (const char *) time24hr
- {
- sprintf(tmpdateString,"%.2d:%.2d",hours,minutes);
- return tmpdateString;
- }
-
- - (const char *) timeAM_PM
- {
- int hrs,am_pm;
- if(hours > 12)
- {
- hrs = hours - 12;
- am_pm = 1;
- }
- else
- {
- hrs = hours;
- am_pm = 0;
- }
- sprintf(tmpdateString,"%d:%.2d %s",hrs,minutes,(am_pm == 0 ? "AM" : "PM"));
- return tmpdateString;
- }
-
- /* Output */
- - (void) print
- {
- printf("\tdateString : %s\n",dateString);
- printf("\tJulianDate : %ld\n",date);
- printf("\tday : %d month : %d year : %d\n",day,month,year);
- }
-
- @end
-