home *** CD-ROM | disk | FTP | other *** search
/ MACD 4 / MACD4.iso / Emulatory / AROS / dos / datetostr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1978-03-06  |  4.9 KB  |  220 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: datetostr.c,v 1.4 1996/10/24 15:50:25 aros Exp $
  4.     $Log: datetostr.c,v $
  5.     Revision 1.4  1996/10/24 15:50:25  aros
  6.     Use the official AROS macros over the __AROS versions.
  7.  
  8.     Revision 1.3  1996/08/13 13:52:53  digulla
  9.     Replaced <dos/dosextens.h> by "dos_intern.h" or added "dos_intern.h"
  10.     Replaced AROS_LA by AROS_LHA
  11.  
  12.     Revision 1.2  1996/08/01 17:40:48  digulla
  13.     Added standard header for all files
  14.  
  15.     Desc:
  16.     Lang: english
  17. */
  18. #include <dos/datetime.h>
  19. #include "dos_intern.h"
  20.  
  21. /*****************************************************************************
  22.  
  23.     NAME */
  24.     #include <clib/dos_protos.h>
  25.  
  26.     AROS_LH1(BOOL, DateToStr,
  27.  
  28. /*  SYNOPSIS */
  29.     AROS_LHA(struct DateTime *, datetime, D1),
  30.  
  31. /*  LOCATION */
  32.     struct DosLibrary *, DOSBase, 124, Dos)
  33.  
  34. /*  FUNCTION
  35.  
  36.     INPUTS
  37.  
  38.     RESULT
  39.  
  40.     NOTES
  41.  
  42.     EXAMPLE
  43.  
  44.     BUGS
  45.  
  46.     SEE ALSO
  47.  
  48.     INTERNALS
  49.  
  50.     HISTORY
  51.     29-10-95    digulla automatically created from
  52.                 dos_lib.fd and clib/dos_protos.h
  53.  
  54. *****************************************************************************/
  55. {
  56.     AROS_LIBFUNC_INIT
  57.     AROS_LIBBASE_EXT_DECL(struct DosLibrary *,DOSBase)
  58.  
  59.     /* Starting days of the months in a leap year. */
  60.     const ULONG daytabl[]=
  61.     { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
  62.  
  63.     char *const monthtable[]=
  64.     { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  65.       "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
  66.  
  67.     char *const weektable[]=
  68.     { "Sunday", "Monday", "Tuesday", "Wednesday",
  69.       "Thursday", "Friday", "Saturday" };
  70.  
  71.     STRPTR buf, name, fstring;
  72.  
  73.     LONG year, month, days, mins, tick, leap=1;
  74.  
  75.     /* Read time. */
  76.     days=datetime->dat_Stamp.ds_Days;
  77.     mins=datetime->dat_Stamp.ds_Minute;
  78.     tick=datetime->dat_Stamp.ds_Tick;
  79.  
  80.     /*
  81.     Check if timestamp is correct. Correct timestamps lie
  82.     between the 1.1.1978 0:00:00 and the 11.7.5881588 23:59:59.
  83.     */
  84.     if(days<0||(ULONG)mins>=24*60||(ULONG)tick>=TICKS_PER_SECOND*60)
  85.     return 0;
  86.  
  87.     if(datetime->dat_StrDay!=NULL)
  88.     {
  89.     /* Get weekday name. The 1.1.1978 was a sunday. */
  90.     buf=datetime->dat_StrDay;
  91.     name=weektable[days%7];
  92.     while((*buf++=*name++)!=0)
  93.         ;
  94.     }
  95.  
  96.     if(datetime->dat_StrDate!=NULL)
  97.     {
  98.     /*
  99.         Calculate year and the days in the year. Use a short method
  100.         if the date is between the 1.1.1978 and the 1.1.2100:
  101.         Every year even divisible by 4 in this time span is a leap year.
  102.         There are 92 normal and 30 leap years there.
  103.     */
  104.     if(days<92*365+30*365)
  105.     {
  106.         /*
  107.         1976 was a leap year so use it as a base to divide the days
  108.         into 4-year blocks (each beginning with a leap year).
  109.         */
  110.         days+=366+365;
  111.         year=4*(days/(366+3*365))+1976;
  112.         days%=(366+3*365);
  113.         /* Now divide the 4-year blocks into single years. */
  114.         if(days>=366)
  115.         {
  116.         leap=0;
  117.         days--;
  118.         year+=days/365;
  119.         days%=365;
  120.         }
  121.     }else
  122.     {
  123.         /*
  124.         The rule for calendar calculations are:
  125.         1. Every year even divisible by 4 is a leap year.
  126.         2. As an exception from rule 1 every year even divisible by
  127.            100 is not.
  128.         3. Every year even divisible by 400 is a leap year as an
  129.            exception from rule 2.
  130.         So 1996, 2000 and 2004 are leap years - 1900 and 1999 are not.
  131.  
  132.         Use 2000 as a base to devide the days into 400 year blocks,
  133.         those into 100 year blocks and so on...
  134.         */
  135.         days-=17*365+5*366;
  136.         year=400*(days/(97*366+303*365))+2000;
  137.         days%=(97*366+303*365);
  138.         if(days>=366)
  139.         {
  140.         leap=0;
  141.         days--;
  142.         year+=100*(days/(24*366+76*365));
  143.         days%=(24*366+76*365);
  144.         if(days>=365)
  145.         {
  146.             leap=1;
  147.             days++;
  148.             year+=4*(days/(366+3*365));
  149.             days%=(366+3*365);
  150.             if(days>=366)
  151.             {
  152.             leap=0;
  153.             days--;
  154.             year+=days/365;
  155.             days%=365;
  156.             }
  157.         }
  158.         }
  159.     }
  160.     /*
  161.          The starting-day table assumes a leap year - so add one day if
  162.          the date is after february 28th and the year is no leap year.
  163.     */
  164.     if(!leap&&days>=31+28)
  165.         days++;
  166.     for(month=11;;month--)
  167.         if(days>=daytabl[month])
  168.         {
  169.         days-=daytabl[month];
  170.         break;
  171.         }
  172.     /* Remember that 0 means 1.1.1978. */
  173.     days++;
  174.  
  175.     /* Build date string */
  176.     buf=datetime->dat_StrDate;
  177.     fstring="d-m-y";
  178.     do
  179.         switch(*fstring)
  180.         {
  181.         case 'y':
  182.             *buf++=year/10%10+'0';
  183.             *buf++=year%10+'0';
  184.             break;
  185.         case 'm':
  186.             name=monthtable[month];
  187.             while(*name)
  188.             *buf++=*name++;
  189.             break;
  190.         case 'd':
  191.             *buf++=days/10+'0';
  192.             *buf++=days%10+'0';
  193.             break;
  194.         default:
  195.             *buf++=*fstring;
  196.             break;
  197.         }
  198.     while(*fstring++);
  199.     }
  200.  
  201.     if(datetime->dat_StrTime!=NULL)
  202.     {
  203.     /* Build time string */
  204.     datetime->dat_StrTime[0]=mins/(10*60)+'0';
  205.     datetime->dat_StrTime[1]=mins/60%10+'0';
  206.     datetime->dat_StrTime[2]=':';
  207.     datetime->dat_StrTime[3]=mins/10%6+'0';
  208.     datetime->dat_StrTime[4]=mins%10+'0';
  209.     datetime->dat_StrTime[5]=':';
  210.     datetime->dat_StrTime[6]=tick/(10*TICKS_PER_SECOND)+'0';
  211.     datetime->dat_StrTime[7]=tick/TICKS_PER_SECOND%10+'0';
  212.     datetime->dat_StrTime[8]=0;
  213.     }
  214.  
  215.     /* All done. Return OK. */
  216.     return 1;
  217.  
  218.     AROS_LIBFUNC_EXIT
  219. } /* DateToStr */
  220.