getdate.c

Go to the documentation of this file.
00001 /*-----------------------------------------------------------------------------------*/
00002 /* INRIA */
00003 /*-----------------------------------------------------------------------------------*/
00004 #ifdef _MSC_VER
00005         #define _USE_32BIT_TIME_T 1
00006 #endif
00007 /*-----------------------------------------------------------------------------------*/
00008 
00009 #include <time.h>
00010 #include <locale.h>
00011 #include <stdio.h>
00012 
00013 #include "machine.h"
00014 #include "sciprint.h"
00015 
00016 #ifdef _MSC_VER
00017         #include <sys/types.h> 
00018         #include <sys/timeb.h>
00019 #else
00020         #include <sys/time.h> 
00021 #endif
00022 /*-----------------------------------------------------------------------------------*/
00023 #define ISO_WEEK_START_WDAY 1 /* Monday */
00024 #define ISO_WEEK1_WDAY 4 /* Thursday */
00025 #define YDAY_MINIMUM (-366)
00026 #define TM_YEAR_BASE 1900
00027 #ifndef __isleap
00028 /* Nonzero if YEAR is a leap year (every 4 years,
00029 except every 100th isn't, and every 400th is).  */
00030 # define __isleap(year) \
00031         ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
00032 #endif
00033 /*-----------------------------------------------------------------------------------*/
00034 #ifdef _MSC_VER
00035         #ifndef _MAX__TIME64_T
00036                 #define _MAX__TIME64_T     0x100000000000i64    /* number of seconds from 00:00:00, 01/01/1970 UTC to 23:59:59. 12/31/2999 UTC */
00037         #endif
00038 #endif
00039 /*-----------------------------------------------------------------------------------*/
00040 
00041 static int week_number __PARAMS ((struct tm *tp));
00042 void C2F(scigetdate) __PARAMS ((time_t *dt, int *ierr));
00043 void C2F(convertdate) __PARAMS ((time_t *dt, int w[]));
00044 /*-----------------------------------------------------------------------------------*/
00045 #ifdef _MSC_VER
00046     static struct __timeb64 timebufferW;
00047 #else
00048   static struct timeval timebufferU;
00049 #endif
00050 static int week_days __PARAMS ((int yday, int wday));
00051 /*-----------------------------------------------------------------------------------*/
00052 static int ChronoFlag=0;
00053 /*-----------------------------------------------------------------------------------*/
00054 void  C2F(scigetdate)(time_t *dt,int *ierr)
00055 {
00056   *ierr=0;
00057   if (time(dt) == (time_t) - 1) 
00058   {
00059     *ierr=1;
00060   }
00061   ChronoFlag=1;
00062   
00063   #ifdef _MSC_VER
00064     _ftime64( &timebufferW );
00065   #else
00066         gettimeofday(&timebufferU,NULL);
00067   #endif
00068 }
00069 /*-----------------------------------------------------------------------------------*/
00070 void C2F(convertdate)(time_t *dt,int w[10])
00071 {
00072         #ifdef _MSC_VER
00073         if ( (*dt<0) || (*dt> _MAX__TIME64_T) )
00074         #else
00075         if (*dt<0)
00076         #endif
00077         {
00078                 w[0] = 0;
00079                 w[1] = 0;
00080                 w[2] = 0;
00081                 w[3] = 0;
00082                 w[4] = 0;
00083                 w[5] = 0;
00084                 w[6] = 0;
00085                 w[7] = 0;
00086                 w[8] = 0;
00087                 w[9] = 0;
00088                 if (*dt<0)      sciprint("dt=getdate(x) x must be > 0.\n");
00089                 #ifdef _MSC_VER
00090                 else sciprint("dt=getdate(x) x must be < %d.\n",_MAX__TIME64_T);
00091                 #endif
00092         }
00093         else
00094         {
00095                 struct tm *nowstruct=NULL;
00096                 nowstruct = localtime(dt);
00097                 if (nowstruct)
00098                 {
00099                         w[0] = 1900 + nowstruct->tm_year;
00100                         w[1] = 1    + nowstruct->tm_mon;
00101                         w[2] = week_number(nowstruct);
00102                         w[3] = 1    + nowstruct->tm_yday;
00103                         w[4] = 1    + nowstruct->tm_wday;
00104                         w[5] =        nowstruct->tm_mday;
00105                         w[6] =        nowstruct->tm_hour;
00106                         w[7] =        nowstruct->tm_min;
00107                         w[8] =        nowstruct->tm_sec;
00108             if (ChronoFlag)
00109                         {
00110        #ifdef _MSC_VER
00111                                 w[9] = timebufferW.millitm;
00112                          #else
00113                                 w[9] = timebufferU.tv_usec / 1000;  /* micro to ms */
00114                          #endif
00115                          ChronoFlag=0;
00116                         }
00117                         else
00118                         {
00119                                 w[9] = 0;
00120                         }
00121                 }
00122         }
00123 }
00124 /*-----------------------------------------------------------------------------------*/
00125 /* week_days computes
00126  *  The number of days from the first day of the first ISO week of this
00127  *  year to the year day YDAY with week day WDAY.  ISO weeks start on
00128  *  Monday; the first ISO week has the year's first Thursday.  YDAY may
00129  *  be as small as YDAY_MINIMUM.  */
00130 /*-----------------------------------------------------------------------------------*/
00131 static int week_days (int yday,int wday)
00132 {
00133   /* Add enough to the first operand of % to make it nonnegative.  */
00134   int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
00135   return (yday - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7 + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
00136 }
00137 /*-----------------------------------------------------------------------------------*/
00138 /* week_number computes 
00139  *      the ISO 8601  week  number  as  a  decimal  number
00140  *      [01,53].  In the ISO 8601 week-based system, weeks
00141  *      begin on a Monday and week 1 of the  year  is  the
00142  *      week  that includes both January 4th and the first
00143  *      Thursday of the year.   If  the  first  Monday  of
00144  *      January  is  the  2nd,  3rd, or 4th, the preceding
00145  *      days are part of the last week  of  the  preceding
00146  *      year. */
00147 static int week_number(struct tm *tp)
00148 {
00149   int year = tp->tm_year + TM_YEAR_BASE;
00150   int days = week_days (tp->tm_yday, tp->tm_wday);
00151 
00152   if (days < 0)
00153     {
00154       /* This ISO week belongs to the previous year.  */
00155       year--;
00156       days = week_days (tp->tm_yday + (365 + __isleap
00157                                            (year)),
00158                             tp->tm_wday);
00159     }
00160   else
00161     {
00162       int d = week_days (tp->tm_yday - (365 + __isleap
00163                                             (year)),
00164                              tp->tm_wday);
00165       if (0 <= d)
00166         {
00167           /* This ISO week belongs to the next year.  */
00168           year++;
00169           days = d;
00170         }
00171     }
00172   return ( (int)days / 7 + 1);
00173 }
00174 /*-----------------------------------------------------------------------------------*/

Generated on Sun Mar 4 15:04:01 2007 for Scilab [trunk] by  doxygen 1.5.1