home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / UNIX / ARCHIE / CLIENTS / NEXTARCH / DATE.M < prev    next >
Encoding:
Text File  |  1992-01-24  |  9.4 KB  |  444 lines

  1. #import "Date.h"
  2. #import <appkit/appkit.h>
  3.  
  4. #import <time.h>
  5. #import <stdlib.h>
  6. #import <stdio.h>
  7. #import <string.h>
  8. #import <math.h>
  9.  
  10. #define OK 1
  11. #define CANCEL 2
  12. #define DATE_SIZE 18
  13. static const char *errNibPath = "DateError.nib";
  14. static const char *DayOfWeek[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
  15. static const char *MonthStr[] = {"Jan","Feb","Mar","Apr",
  16.                         "May","Jun","Jul","Aug",
  17.                         "Sep","Oct","Nov","Dec"};
  18. static BOOL parseError;
  19. static id dateField;    // A TextField used to allow a user to edit incorrect dates
  20. static id selField;        // A TextField used to display the method which invoked invalidDate
  21. static char tmpdateString[DATE_SIZE];
  22.  
  23. @implementation Date
  24.  
  25. /* Class methods */
  26. /* Used to get the SEL method for displaying which
  27.     method called invalidDate: */
  28. + (const char *) selName : (SEL) theSEL
  29. {
  30.     if(theSEL == @selector(initFromString:) )
  31.         return "initFromString:";
  32.     else if(theSEL ==  @selector(initFromDate:::) )
  33.         return "initFromDate:::";
  34.     else if(theSEL ==  @selector(initFromJulianDate:) )
  35.         return "initFromJulianDate:";
  36.     else
  37.         return "NoMethod";
  38. }
  39.  
  40. - setErrorMode : (int) mode
  41. {
  42.     errorMode = mode;
  43.     return self;
  44. }
  45.  
  46. - free
  47. {
  48.     if(dateString != NULL)
  49.         NX_FREE(dateString);
  50.     return [super free];
  51. }
  52.  
  53. /* Parse a date string("mm/dd/yy[yy]") into its integer components */
  54. - parseDateString : (char *) dateStrng : (Day *) d : (Month *) m : (Year *) y
  55. {
  56. char tmpDate[16],*tmpDatePtr,*token;
  57. short yr,century;
  58.     /* Assign the integer values to day,month,year */
  59.     strcpy(tmpDate, dateStrng);
  60.     tmpDatePtr = tmpDate;
  61.     token = strtok(tmpDatePtr,"/");
  62.     tmpDatePtr = NULL;
  63.     if(token == NULL)
  64.     {
  65.         parseError = YES;
  66.         *m = 0;
  67.     }
  68.     else
  69.         *m = atoi(token);
  70.     token = strtok(tmpDatePtr,"/");
  71.     if(token == NULL)
  72.     {
  73.         parseError = YES;
  74.         *d = 0;
  75.     }
  76.     else
  77.         *d = atoi(token);
  78.     token = strtok(tmpDatePtr,"/");
  79.     if(token == NULL)
  80.     {
  81.         parseError = YES;
  82.         *y = 0;
  83.     }
  84.     else
  85.         *y = atoi(token);
  86.     if(*y < 100)
  87.     {    // Get the current century
  88.         [self now : NULL : NULL : &yr : NULL : NULL : NULL];
  89.         century = yr - (yr % 100);
  90.         (*y) += century;
  91.     }
  92.     return self;
  93. }
  94.  
  95. /* The day, month & year must be set before calling */
  96. - (BOOL) validDate
  97. {
  98. short calDay,calMonth,calYear;
  99. long jDate;
  100.     /* Convert date to Julian day number and back */
  101.     jDate = [self julianRep : day : month : year];
  102.     [self calendarDate : jDate : &calDay : &calMonth : &calYear];
  103.     /* See if the date has changed */
  104.     if(day != calDay)
  105.         return NO;
  106.     else if(month != calMonth)
  107.         return NO;
  108.     else if(year != calYear)
  109.         return NO;
  110.     else
  111.         return YES;
  112. }
  113.  
  114. - invalidDate : (SEL) callingMethod;
  115. {
  116. int rtnVal;
  117. static id editErrorPanel = nil;
  118. char dateStrng[16];
  119.     switch(errorMode)
  120.     {
  121.         case 0 :
  122.             return nil;
  123.             break;
  124.         case 1 :
  125.             NXRunAlertPanel(NULL,"%d/%d/%d is not a valid date",
  126.                 NULL,NULL, NULL,month,day,year);
  127.             return nil;
  128.             break;
  129.         case 2 :
  130.             if(editErrorPanel == nil)
  131.                 editErrorPanel = [NXApp loadNibFile : errNibPath
  132.                     owner : self withNames : YES];
  133.             if(parseError == YES)
  134.                 strcpy(dateStrng,dateString);
  135.             else
  136.                 sprintf(dateStrng,"%d/%d/%d",month,day,year);
  137.             /* Get the panel fields by name and initialize then */
  138.             dateField = NXGetNamedObject("DateErrordateField", editErrorPanel);
  139.             [dateField setStringValue : dateStrng];
  140.             selField = NXGetNamedObject("DateErrorselField", editErrorPanel);
  141.             [selField setStringValue : [Date selName : callingMethod]];
  142.             /* Put the error panel in a modal loop */
  143.             rtnVal = [NXApp runModalFor : editErrorPanel];
  144.             [editErrorPanel orderOut : self];
  145.             if(rtnVal == OK)
  146.             {
  147.                 /* Assign the string representation */
  148.                 if(!dateString)
  149.                     NX_MALLOC(dateString,char,11);
  150.                 sprintf(dateString,"%d/%d/%d",month,day,year);
  151.                 /* Assign the Julian date representation*/
  152.                 date = [self julianRep : day : month : year];
  153.                 return self;
  154.             }
  155.             else
  156.                 return nil;
  157.             break;
  158.         default :
  159.             return nil;
  160.     }
  161. }
  162.  
  163. /* Method invoked by the Ok button of the editErrorPanel */
  164. - dateOk : sender
  165. {
  166.     parseError = NO;
  167.     [self parseDateString : (char *) [dateField stringValue] : &day : &month : &year];
  168.     if(parseError == YES || [self validDate] == NO)
  169.         NXBeep();
  170.     else
  171.         [NXApp stopModal : OK];
  172.     return self;
  173. }
  174. /* Method invoked by the ``Return nil'' button of the editErrorPanel */
  175. - dateCancel : sender
  176. {
  177.     [NXApp stopModal : CANCEL];
  178.     return self;
  179. }
  180.  
  181. - initFromString : (char *) theDate
  182. {
  183.     parseError = NO;
  184.     [self parseDateString : theDate : &day : &month : &year];
  185.     if(parseError == YES)
  186.     {
  187.         dateString = theDate;
  188.         return [self invalidDate : _cmd];
  189.     }
  190.     if([self validDate] == NO)
  191.         return [self invalidDate : _cmd];
  192.  
  193.     /* Assign the string representation */
  194.     if(!dateString)
  195.         NX_MALLOC(dateString,char,11);
  196.     sprintf(dateString,"%d/%d/%d",month,day,year);
  197.  
  198.     /* Assign the Julian representation */
  199.     date = [self julianRep : day : month : year];
  200.  
  201.     return self;
  202. }
  203.  
  204. - initFromDate : (Day) d : (Month) m : (Year) y
  205. {
  206. short yr,century;
  207.  
  208.     /* Assign the integer values to day,month,year */
  209.     day = d;
  210.     month = m;
  211.     if(y < 100)
  212.     {
  213.         [self now : NULL : NULL : &yr : NULL : NULL : NULL];
  214.         century = yr - (yr % 100);
  215.         y += century;
  216.     }
  217.     year = y;
  218.     if([self validDate] == NO)
  219.         return [self invalidDate : _cmd];
  220.     
  221.     /* Assign the Julian representation */
  222.     date = [self julianRep : day : month : year];
  223.  
  224.     /* Assign the string representation */
  225.     if(!dateString)
  226.         NX_MALLOC(dateString,char,11);
  227.     sprintf(dateString,"%d/%d/%d",month,day,year);
  228.     
  229.     return self;
  230. }
  231.  
  232. - initFromJulianDate : (JulianDate) jDate
  233. {
  234.     date = jDate;
  235.     [self calendarDate : jDate : &day : &month : &year];
  236.     if([self validDate] == NO)
  237.         return [self invalidDate : _cmd];
  238.     if(!dateString)
  239.         NX_MALLOC(dateString,char,11);
  240.     sprintf(dateString,"%d/%d/%d",month,day,year);
  241.     
  242.     return self;
  243. }
  244.  
  245. - initFromNow
  246. {
  247.  
  248.     [self now : &day : &month : &year : &hours : &minutes : &seconds];
  249.     /* Assign the Julian representation */
  250.     date = [self julianRep : day : month : year];
  251.  
  252.     /* Assign the string representation */
  253.     if(!dateString)
  254.         NX_MALLOC(dateString,char,11);
  255.     sprintf(dateString,"%d/%d/%d",month,day,year);
  256.     
  257.     return self;
  258. }
  259.  
  260. - setTime : (short) hr : (short) min : (short) sec
  261. {
  262.     hours = hr;
  263.     minutes = min;
  264.     seconds = sec;
  265.     return self;
  266. }
  267.  
  268. - (void) now : (Day *) d : (Month *) m : (Year *) y : (short *) hr : (short *) min : (short *) sec
  269. {
  270. struct tm *timeStruct;
  271. time_t now;
  272.  
  273.     time(&now);
  274.     timeStruct = localtime(&now);
  275.     /* Assign the integer values to day,month,year */
  276.     if(d != NULL)
  277.         *d = timeStruct->tm_mday;
  278.     if(m != NULL)
  279.         *m = timeStruct->tm_mon + 1;
  280.     if(y != NULL)
  281.         *y = timeStruct->tm_year + 1900;
  282.     if(hr != NULL)
  283.         *hr = timeStruct->tm_hour;
  284.     if(min != NULL)
  285.         *min = timeStruct->tm_min;
  286.     if(sec != NULL)
  287.         *sec = timeStruct->tm_sec;
  288. }
  289.  
  290. - (long) sysTime
  291. {
  292.     return time( (long *) 0);
  293. }
  294.  
  295. /* Conversion functions */
  296. - calendarDate : (long) jDate : (Day *) dy : (Month *) m : (Year *) y
  297. {
  298. long a,b,c,d,e,z,alpha;
  299.  
  300.     /* Calculate the day, month and year */
  301.     z = jDate + 1;
  302.     if(z < 2299161L)
  303.         a = z;
  304.     else
  305.     {
  306.         alpha = (long) ((z - 1867216.25) / 36524.25);
  307.         a = z + 1 + alpha - alpha / 4;
  308.     }
  309.     b = a + 1524;
  310.     c = (long) ((b - 122.1) / 365.25);
  311.     d = (long) (365.25 * c);
  312.     e = (long) ((b - d) / 30.6001);
  313.     *dy = (Day) b - d - (long)(30.6001 * e);
  314.     *m = (Month) (e < 13.5) ? e - 1 : e - 13;
  315.     *y = (Year) (*m > 2.5) ? (c - 4716) : c - 4715;
  316.  
  317.     return self;
  318. }
  319.  
  320. - (JulianDate) julianRep : (Day) d : (Month) m : (Year) y
  321. {
  322. int a,b;
  323. long jDate;
  324. float year_corr;
  325.     
  326.     /* Assign the Julian representation */
  327.     year_corr = (y > 0 ? 0.0 : 0.75);
  328.     if(m <= 2)
  329.     {
  330.         y --;
  331.         m += 12;
  332.     }
  333.     b = 0;
  334.     /* Cope with Greogrian calendar reform */
  335.     if(y * 10000.0 + m * 100.0 + d >= 15821015.0)
  336.     {
  337.         a = y / 100;
  338.         b = 2 - a + a / 4;
  339.     }
  340.     jDate = (JulianDate)(365.25 * y - year_corr) + (JulianDate)(30.6001 * (m+1)) +
  341.             (JulianDate)(d + 1720994L + b);
  342.     return jDate;
  343. }
  344.  
  345. - (JulianDate) julianDate
  346. {
  347.     return(date);
  348. }
  349.  
  350. - (WeekDay) weekDay
  351. {
  352.     // Return day : [0-6] = Sunday - Saturday
  353.     return (WeekDay)((date + 2) % 7);
  354. }
  355.  
  356. - (Day) day
  357. {
  358.     return day;
  359. }
  360.  
  361. - (Month) month
  362. {
  363.     return((Month) month - 1);
  364. }
  365.  
  366. - (Year) year
  367. {
  368.     return((Year) year);
  369. }
  370. - (short) hours
  371. {
  372.     return hours;
  373. }
  374. - (short) minutes
  375. {
  376.     return minutes;
  377. }
  378. - (short) seconds
  379. {
  380.     return seconds;
  381. }
  382.  
  383. - (void) time : (short *) hr : (short *) min : (short *) sec
  384. {
  385.     if(hr != NULL)
  386.         *hr = hours;
  387.     if(min != NULL)
  388.         *min = minutes;
  389.     if(sec != NULL)
  390.         *sec = seconds;
  391. }
  392.  
  393. - (const char *) stringDate
  394. {
  395.     strcpy(tmpdateString,dateString);
  396.     return tmpdateString;
  397. }
  398.  
  399. - (const char *) stringFixedDate
  400. {
  401.     sprintf(tmpdateString,"%.2d/%.2d/%.4d",month,day,year);
  402.     return tmpdateString;
  403. }
  404.  
  405. - (const char *) fullStringDate
  406. {
  407.     sprintf(tmpdateString,"%s %s %.2d %.4d",
  408.         DayOfWeek[[self weekDay]],MonthStr[month-1],day,year);
  409.     return tmpdateString;
  410. }
  411.  
  412. - (const char *) time24hr
  413. {
  414.     sprintf(tmpdateString,"%.2d:%.2d",hours,minutes);
  415.     return tmpdateString;
  416. }
  417.  
  418. - (const char *) timeAM_PM
  419. {
  420. int hrs,am_pm;
  421.     if(hours > 12)
  422.     {
  423.         hrs = hours - 12;
  424.         am_pm = 1;
  425.     }
  426.     else
  427.     {
  428.         hrs = hours;
  429.         am_pm = 0;
  430.     }
  431.     sprintf(tmpdateString,"%d:%.2d %s",hrs,minutes,(am_pm == 0 ? "AM" : "PM"));
  432.     return tmpdateString;
  433. }
  434.  
  435. /* Output */
  436. - (void) print
  437. {
  438.     printf("\tdateString : %s\n",dateString);
  439.     printf("\tJulianDate : %ld\n",date);
  440.     printf("\tday : %d month : %d year : %d\n",day,month,year);
  441. }
  442.  
  443. @end
  444.