home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Programming / DOpus4-GPL / Library / dates.c < prev    next >
C/C++ Source or Header  |  2000-01-27  |  9KB  |  347 lines

  1. /*
  2.  
  3. Directory Opus 4
  4. Original GPL release version 4.12
  5. Copyright 1993-2000 Jonathan Potter
  6.  
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. All users of Directory Opus 4 (including versions distributed
  22. under the GPL) are entitled to upgrade to the latest version of
  23. Directory Opus version 5 at a reduced price. Please see
  24. http://www.gpsoft.com.au for more information.
  25.  
  26. The release of Directory Opus 4 under the GPL in NO WAY affects
  27. the existing commercial status of Directory Opus 5.
  28.  
  29. */
  30.  
  31. #include "dopuslib.h"
  32.  
  33. extern calcdate(int *,int *,int *);
  34. extern char *getnextbit(char *,int *,int);
  35.  
  36. char
  37.     *def_weekdays[7]={
  38.         "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"},
  39.     *def_months[12]={
  40.         "January","February","March","April","May","June",
  41.         "July","August","September","October","November","December"},
  42.     *def_special_days[4]={
  43.         "Yesterday","Today","Tomorrow","Future"};
  44.  
  45. #define SPEC_YESTERDAY 0
  46. #define SPEC_TODAY     1
  47. #define SPEC_TOMORROW  2
  48. #define SPEC_FUTURE    3
  49.  
  50. char mondays[12]={31,28,31,30,31,30,31,31,30,31,30,31};
  51.  
  52. __asm __saveds DoStampToStr(register __a0 struct DOpusDateTime *dt)
  53. {
  54.     int day,mon,yr,hr,min,sec,wday,diff;
  55.     struct DateStamp now;
  56.     char **weekdays=NULL,**special_days=NULL,**shortmonths=NULL;
  57.     ULONG ds_days,ds_minute,ds_tick;
  58.  
  59.     ds_days=dt->dat_Stamp.ds_Days;
  60.     ds_minute=dt->dat_Stamp.ds_Minute;
  61.     ds_tick=dt->dat_Stamp.ds_Tick;
  62.  
  63.     if (ds_minute>1440) ds_minute%=1440;
  64.     if (ds_tick>3000) ds_tick%=3000;
  65.  
  66.     if (dt->dat_Flags&DDTF_CUSTOM) {
  67.         weekdays=dt->custom_weekdays;
  68.         shortmonths=dt->custom_shortmonths;
  69.         special_days=dt->custom_special_days;
  70.     }
  71.  
  72.     if (!weekdays) weekdays=def_weekdays;
  73.     if (!special_days) special_days=def_special_days;
  74.  
  75.     DateStamp(&now);
  76.     day=ds_days;
  77.     calcdate(&day,&mon,&yr);
  78.     while (yr>99) yr-=100;
  79.  
  80. /*
  81. UWORD DayOfWeek (UWORD Year, UWORD Month, UWORD Day)
  82. {
  83.    return (((3 * Year - (7 * (Year + (Month + 9) / 12)) / 4 +
  84.            (23 * Month) / 9 + Day + 2 + 15 -
  85.            ((Year - (Month < 3)) / 100 + 1) * 3 / 4 ) % 7 ));
  86. }
  87. */
  88.     wday=ds_days%7;
  89.     if (wday<0) wday=6;
  90.     hr=ds_minute/60;
  91.     min=ds_minute%60;
  92.     sec=ds_tick/50;
  93.  
  94.     if (dt->dat_StrDay) strcpy(dt->dat_StrDay,weekdays[wday]);
  95.     if (dt->dat_StrTime) {
  96.         if (dt->dat_Flags&DDTF_12HOUR) {
  97.             int ampm;
  98.  
  99.             if (hr>=12) {
  100.                 if (hr>12) hr-=12;
  101.                 ampm=1;
  102.             }
  103.             else {
  104.                 if (hr==0) hr=12;
  105.                 ampm=0;
  106.             }
  107.             LSprintf(dt->dat_StrTime,"%2ld:%02ld:%02ld%lc",hr,min,sec,(ampm)?'P':'A');
  108.         }
  109.         else LSprintf(dt->dat_StrTime,"%02ld:%02ld:%02ld",hr,min,sec);
  110.     }
  111.     if (dt->dat_StrDate) {
  112.         diff=ds_days-now.ds_Days;
  113.         if (dt->dat_Flags&DDTF_SUBST && diff>-7) {
  114.             char *temp;
  115.  
  116.             if (diff==-1) temp=special_days[SPEC_YESTERDAY];
  117.             else if (diff==0) temp=special_days[SPEC_TODAY];
  118.             else if (diff==1) temp=special_days[SPEC_TOMORROW];
  119.             else if (diff>1) temp=special_days[SPEC_FUTURE];
  120.             else temp=weekdays[wday];
  121.  
  122.             strcpy(dt->dat_StrDate,temp);
  123.         }
  124.         else switch (dt->dat_Format) {
  125.             case FORMAT_INT:
  126.                 LSprintf(dt->dat_StrDate,"%02ld-%02ld-%02ld",yr,mon+1,day);
  127.                 break;
  128.  
  129.             case FORMAT_USA:
  130.                 LSprintf(dt->dat_StrDate,"%02ld-%02ld-%02ld",mon+1,day,yr);
  131.                 break;
  132.  
  133.             case FORMAT_CDN:
  134.                 LSprintf(dt->dat_StrDate,"%02ld-%02ld-%02ld",day,mon+1,yr);
  135.                 break;
  136.  
  137.             case FORMAT_DOS:
  138.             default:
  139.                 {
  140.                     char temp[10];
  141.  
  142.                     if (shortmonths) strcpy(temp,shortmonths[mon]);
  143.                     else {
  144.                         temp[0]=def_months[mon][0];
  145.                         temp[1]=def_months[mon][1];
  146.                         temp[2]=def_months[mon][2];
  147.                         temp[3]=0;
  148.                     }
  149.  
  150.                     LSprintf(dt->dat_StrDate,"%02ld-%3s-%02ld",day,temp,yr);
  151.                 }
  152.                 break;
  153.         }
  154.     }
  155.     return(1);
  156. }
  157.  
  158. calcdate(day,month,year)
  159. int *day,*month,*year;
  160. {
  161.     int i,mdays,ldays,year2;
  162.  
  163.     ldays=1461; year2=78;
  164.     year2+=((*day)/ldays)*4;
  165.     (*day)%=ldays;
  166.     while ((*day)) {
  167.         mdays=365;
  168.         if ((year2&3)==0) mdays++;
  169.         if ((*day)<mdays) break;
  170.         (*day)-=mdays;
  171.         year2++;
  172.     }
  173.     for (i=0,(*day)++;i<12;i++) {
  174.         mdays=mondays[i];
  175.         if (i==1&&(year2&3)==0) mdays++;
  176.         if ((*day)<=mdays) break;
  177.         (*day)-=mdays;
  178.     }
  179.     (*month)=i;
  180.     (*year)=year2;
  181.     return(0);
  182. }
  183.  
  184. __asm __saveds DoStrToStamp(register __a0 struct DOpusDateTime *dt)
  185. {
  186.     int day,mon,yr,hr,min,sec,a,b,wday,c;
  187.     char *ptr,monstr[20];
  188.     struct DateStamp now;
  189.     char **weekdays=NULL,**shortweekdays=NULL,**special_days=NULL,
  190.         **months=NULL,**shortmonths=NULL;
  191.  
  192.     if (dt->dat_Flags&DDTF_CUSTOM) {
  193.         weekdays=dt->custom_weekdays;
  194.         shortweekdays=dt->custom_shortweekdays;
  195.         special_days=dt->custom_special_days;
  196.         months=dt->custom_months;
  197.         shortmonths=dt->custom_shortmonths;
  198.     }
  199.  
  200.     if (!weekdays) weekdays=def_weekdays;
  201.     if (!special_days) special_days=def_special_days;
  202.     if (!months) months=def_months;
  203.  
  204.     c=0;
  205.  
  206.     if (dt->dat_StrTime) {
  207.         ptr=getnextbit(dt->dat_StrTime,&hr,0);
  208.         ptr=getnextbit(ptr,&min,0);
  209.         getnextbit(ptr,&sec,0);
  210.         dt->dat_Stamp.ds_Minute=(hr*60)+min;
  211.         dt->dat_Stamp.ds_Tick=sec*50;
  212.         c=1;
  213.     }
  214.     if (dt->dat_StrDate) {
  215.         DateStamp(&now);
  216.         for (a=0;a<7;a++) {
  217.             if (LStrCmpI(dt->dat_StrDate,weekdays[a])==0) break;
  218.             if (shortweekdays) {
  219.                 if (LStrnCmpI(dt->dat_StrDate,shortweekdays[a],3)==0) break;
  220.             }
  221.             else if (LStrnCmpI(dt->dat_StrDate,weekdays[a],3)==0) break;
  222.         }
  223.         if (a<7) {
  224.             wday=now.ds_Days%7;
  225.             b=0;
  226.             if (dt->dat_Flags&DDTF_FUTURE) {
  227.                 while (wday!=a) {
  228.                     ++wday; ++b;
  229.                     if (wday>6) wday=0;
  230.                 };
  231.             }
  232.             else {
  233.                 while (wday!=a) {
  234.                     --wday; --b;
  235.                     if (wday<0) wday=6;
  236.                 };
  237.             }
  238.             day=now.ds_Days+b;
  239.         }
  240.         else {
  241.             if (LStrCmpI(dt->dat_StrDate,special_days[SPEC_TOMORROW])==0) day=now.ds_Days+1;
  242.             else if (LStrCmpI(dt->dat_StrDate,special_days[SPEC_TODAY])==0) day=now.ds_Days;
  243.             else if (LStrCmpI(dt->dat_StrDate,special_days[SPEC_YESTERDAY])==0) day=now.ds_Days-1;
  244.             else {
  245.                 day=1; mon=1; yr=78;
  246.                 switch (dt->dat_Format) {
  247.                     case FORMAT_DOS:
  248.                         ptr=getnextbit(dt->dat_StrDate,&day,0);
  249.                         ptr=getnextbit(ptr,(int *)monstr,1);
  250.                         getnextbit(ptr,&yr,0);
  251.                         for (a=0;a<12;a++) {
  252.                             if ((LStrCmpI(monstr,months[a])==0) ||
  253.                                 (shortmonths && LStrCmpI(monstr,shortmonths[a])==0) ||
  254.                                 (!shortmonths && LStrnCmpI(monstr,months[a],3)==0)) {
  255.                                 mon=a+1;
  256.                                 break;
  257.                             }
  258.                         }
  259.                         break;
  260.  
  261.                     case FORMAT_INT:
  262.                         ptr=getnextbit(dt->dat_StrDate,&yr,0);
  263.                         ptr=getnextbit(ptr,&mon,0);
  264.                         getnextbit(ptr,&day,0);
  265.                         break;
  266.  
  267.                     case FORMAT_USA:
  268.                         ptr=getnextbit(dt->dat_StrDate,&mon,0);
  269.                         ptr=getnextbit(ptr,&day,0);
  270.                         getnextbit(ptr,&yr,0);
  271.                         break;
  272.  
  273.                     case FORMAT_CDN:
  274.                         ptr=getnextbit(dt->dat_StrDate,&day,0);
  275.                         ptr=getnextbit(ptr,&mon,0);
  276.                         getnextbit(ptr,&yr,0);
  277.                         break;
  278.                 }
  279.                 if (yr<78) yr+=2000;
  280.                 else if (yr<100) yr+=1900;
  281.                 if (yr<1978) yr=1978;
  282.                 else if (yr>2045) yr=2045;
  283.                 --day; --mon;
  284.                 for (a=0;a<mon;a++) {
  285.                     day+=mondays[a];
  286.                     if (a==1 && (yr%4)==0 && ((yr%100)!=0 || (yr%400)==0)) ++day;
  287.                 }
  288.                 for (a=1978;a<yr;a++) {
  289.                     day+=365;
  290.                     if ((a%4)==0 && ((a%100)!=0 || (a%400)==0)) ++day;
  291.                 }
  292.             }
  293.         }
  294.         dt->dat_Stamp.ds_Days=day;
  295.         c=1;
  296.     }
  297.     return(c);
  298. }
  299.  
  300. char *getnextbit(ptr,retbuf,t)
  301. char *ptr;
  302. int *retbuf,t;
  303. {
  304.     int a,b,c;
  305.     char *str;
  306.  
  307.     if (!ptr) return(NULL);
  308.  
  309.     if (t==0) *retbuf=0;
  310.     else str=(char *)retbuf;
  311.     c=1;
  312.     for (a=0;;a++) {
  313.         if (!ptr[a] || ptr[a]=='-' || ptr[a]=='/' || ptr[a]=='.' || ptr[a]==' ') break;
  314.         if (t==0 && (ptr[a]<'0' || ptr[a]>'9')) break;
  315.         c*=10;
  316.     }
  317.     c/=10;
  318.     for (b=0;b<a;b++) {
  319.         if (t==0) {
  320.             *retbuf+=(ptr[b]-'0')*c;
  321.             c/=10;
  322.         }
  323.         else {
  324.             str[b]=ptr[b];
  325.             str[b+1]=0;
  326.         }
  327.     }
  328.     if (ptr[a]==0) return(NULL);
  329.     return(ptr+a+1);
  330. }
  331.  
  332. __asm __saveds DoCompareDate(register __a0 struct DateStamp *date,
  333.     register __a1 struct DateStamp *date2)
  334. {
  335.     if (!date) return(-1);
  336.     if (!date2) return(1);
  337.     if (date->ds_Days>date2->ds_Days) return(1);
  338.     if (date->ds_Days==date2->ds_Days) {
  339.         if (date->ds_Minute>date2->ds_Minute) return(1);
  340.         if (date->ds_Minute==date2->ds_Minute) {
  341.             if (date->ds_Tick>date2->ds_Tick) return(1);
  342.             if (date->ds_Tick==date2->ds_Tick) return(0);
  343.         }
  344.     }
  345.     return(-1);
  346. }
  347.