Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #96062 > unrolled thread

What about my last date functions? there are some error?

Started byRosario19 <Ros@invalid.invalid>
First post2016-11-08 11:28 +0100
Last post2016-11-08 08:19 -0800
Articles 20 on this page of 24 — 9 participants

Back to article view | Back to comp.lang.c


Contents

  What about my last date functions? there are some error? Rosario19 <Ros@invalid.invalid> - 2016-11-08 11:28 +0100
    Re: What about my last date functions? there are some error? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-11-08 10:55 +0000
      Re: What about my last date functions? there are some error? "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-11-08 19:00 +0800
      Re: What about my last date functions? there are some error? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-11-08 11:04 +0000
        Re: What about my last date functions? there are some error? "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-11-08 19:22 +0800
      Re: What about my last date functions? there are some error? Richard Heathfield <rjh@cpax.org.uk> - 2016-11-08 11:35 +0000
        Re: What about my last date functions? there are some error? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-11-08 15:46 +0000
          Re: What about my last date functions? there are some error? Richard Heathfield <rjh@cpax.org.uk> - 2016-11-08 16:20 +0000
            Re: What about my last date functions? there are some error? Rosario19 <Ros@invalid.invalid> - 2016-11-08 17:44 +0100
              Re: What about my last date functions? there are some error? Richard Heathfield <rjh@cpax.org.uk> - 2016-11-08 16:51 +0000
                Re: What about my last date functions? there are some error? Jerry Stuckle <jstucklex@attglobal.net> - 2016-11-08 13:21 -0500
            Re: What about my last date functions? there are some error? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-11-08 18:06 +0000
              Re: What about my last date functions? there are some error? Richard Heathfield <rjh@cpax.org.uk> - 2016-11-08 18:56 +0000
                Re: What about my last date functions? there are some error? Keith Thompson <kst-u@mib.org> - 2016-11-08 12:05 -0800
                Re: What about my last date functions? there are some error? David Brown <david.brown@hesbynett.no> - 2016-11-08 21:10 +0100
                  Re: What about my last date functions? there are some error? Richard Heathfield <rjh@cpax.org.uk> - 2016-11-08 20:16 +0000
            Re: What about my last date functions? there are some error? jadill33@gmail.com - 2016-11-08 11:16 -0800
              Re: What about my last date functions? there are some error? Richard Heathfield <rjh@cpax.org.uk> - 2016-11-08 20:08 +0000
              Re: What about my last date functions? there are some error? Keith Thompson <kst-u@mib.org> - 2016-11-08 12:11 -0800
                Re: What about my last date functions? there are some error? Keith Thompson <kst-u@mib.org> - 2016-11-08 12:29 -0800
        Re: What about my last date functions? there are some error? Rosario19 <Ros@invalid.invalid> - 2016-11-08 17:41 +0100
          Re: What about my last date functions? there are some error? asetofsymbols@gmail.com - 2016-11-08 11:26 -0800
            Re: What about my last date functions? there are some error? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-11-08 19:38 +0000
    Re: What about my last date functions? there are some error? Keith Thompson <kst-u@mib.org> - 2016-11-08 08:19 -0800

Page 1 of 2  [1] 2  Next page →


#96062 — What about my last date functions? there are some error?

FromRosario19 <Ros@invalid.invalid>
Date2016-11-08 11:28 +0100
SubjectWhat about my last date functions? there are some error?
Message-ID<gh932ctlqkebuct208fqbbc7rdak1b2c1o@4ax.com>
What about my last date functions? there are some error?
just today i find someones...

in theory one has to check that date representation is ok
only in the input and in the outuput not in each function
so in function GetsDate and in function  PrintDate [only for see if
there is some error]

so if someone admit their routines are 100% right the only problem is
validate the input of the program not validate the input each
function...

                           DATES
Date is 3 numbers integer number: y, m, g where y[one number in
0..0xFFFFFF]
is the year, m[one number in 0..11] is the month g[in 1..31] is the
day.

    isDate(y,m,g)
that says if date y,m,g is ok as date [for example y>=0 or 0<=m<=11
etc]

    GetsDate(number*ry,number*rm,number*rg)
that gets date from stdin, from file or some other place
the date in the format  day[ -/\]month[ -/\]year
and put it in variables *ry=year *rm=month-1 *rg=day
that represent one date

    PrintDate(y,m,g)
that print the date

    NDaysMonth(y,m)
that return the days of the month m of the year y

    NDaysYear(y)
that return number of days of the year y

    NDayWeek(y,m,g)
return the number of day for the date y,m,g for example
0 for Monday .. 6 for Sunday

    cmp(y,m,g,ya,ma,ga)
that return -1 if y m g>ya ma ga; 0 if they are the same; else 1

    month(m)
that return the name of the month m as string [for example month(1)
return "Feb"]

    day(g)
as above for month for days 0..6

    Ndays(y,m,g,ya,ma,ga)
return the difference in days from (y m g) to (ya ma ga); return one
negative
number if  (y m g) > (ya ma ga)

    AddToDateDays(N*ry,N*rm,N*rg,N y,N m,N g,N v)
sum to date (y,m,g) the number [positive or negative] v; put the date
result in result (ry,rm,rg)

------------------------------------------------
    #define R return
    #define L(i) for(;i-->0;)
    #define I if
    #define N int
    #define C unsigned char
    #define F for
    #define G goto
    #define P printf
    #define E else

    // Data=year, month, day = y,m,g where y>0  0<=m<=11  1<=g<=31

    // ritorna il numero dei giorni di anno=y mese=m con mese in 0..11
    // m==1 significa febbraio
    // 2773=0101011010101
    //       CBA987654321      30 nov[B] apr[4] giu[6] sett[9]  altri
31
    NDaysMonth(y,m){R
m-1?30+((2773>>m)&1):28+(y%4?0:y%100?1:!(y%400));}

    //controlla se la data e' valida

isDate(y,m,g){R!(y<0||y>0xFFFFFF||m<0||m>11||g<1||g>NDaysMonth(y,m));}

    //Cerca di prendere la data da stdin in formato giorno[ -/\]mese[
-/\]anno
    //in input: 1<=day<=31   1<=month<=12  year>=0 where
isDate(year,month-1,day)==1
    GetsDate(N*ry,N*rm,N*rg)
    {C v[1024], c;
     N       q, r;
     *ry=*rm=*rg=0; *v=c=0;
     P("Insert data(gg/mm/aaaa)> ");fflush(0);
     r=scanf("%1020[^\n]%c",v,&c); // in c prende \n
     I(c!='\n')R 0;
     I(sscanf(v,"%d %d %d",rg,rm,ry)!=3&&
       sscanf(v,"%d-%d-%d",rg,rm,ry)!=3&&
       sscanf(v,"%d/%d/%d",rg,rm,ry)!=3&&
       sscanf(v,"%d\\%d\\%d",rg,rm,ry)!=3
      )      R 0;
     --*rm;
     R isDate(*ry,*rm,*rg);
    }
    
    //In output:  1<=day<=31   1<=month<=12  year>=0 where
isDate(year,month-1,day)==1
    PrintDate(y,m,g){P("%02d/%02d/%d",g,m+1,y); I(!isDate(y,m,g))P("
\aData Print Error\n");}
    
    GetsYearWeekDay(N*ry,N*rw,N*rn)
    {C v[1024], c;
     N q, r;
     *ry=*rw=*rn=0; *v=c=0;
     P("Insert data(year/Nweek/day)> ");fflush(0);
     r=scanf("%1020[^\n]%c",v,&c);
     if(c!='\n')R 0;
     I(sscanf(v,"%d %d %d",ry,rw,rn)!=3&&
       sscanf(v,"%d-%d-%d",ry,rw,rn)!=3&&
       sscanf(v,"%d/%d/%d",ry,rw,rn)!=3&&
       sscanf(v,"%d\\%d\\%d",ry,rw,rn)!=3
      )      R 0;
     I(*ry<0||*ry>0xFFFFFF||*rw<1||*rw>53||*rn<0||*rn>6)
             R 0;
     R 1;
    }
    
    
    // ritorna il numero dei giorni di anno=y[0..0xFFFFFF]
    NDaysYear(y){R 337+NDaysMonth(y,1);} //365-28=337
    
    
    // argomenti anno:y[0..0xFFFFFF]  mese:m[0..11]
giorno:g[1..NDaysMonth(y,m)]
    // ritorna il numero del giorno[0..6]
    NDayWeek(y,m,g)
    {g+=4; //lultimo lunedi' dell'anno -1: anno mese giorno = -1,12,27
     L(m)g+=  NDaysMonth(y,m),g%=7; // m:0..m-1  somma mod 7 i giorni
del mese dell'anno y
     L(y)g+=1+NDaysMonth(y,1),g%=7; // y:0..y-1  somma mod 7 gli anni
da 0..y-1
      // g+=1+NDaysMonth(y,1) poiche' (365-28)%7=1 (1 in
NDaysMonth(y,1) e' febbraio)
     R g; // g=(NumeroGiorni tra -1,12,27[lunedi'] ed y m g)%7
    }
    
    cmp(y,m,g,ya,ma,ga)
    {I(y==ya&&m==ma&&g==ga) R  0;
     I(y<ya||(y==ya&&m<ma)||(y==ya&&m==ma&&g<ga)) R -1;
     R 1;
    }


C*mx[]={"Gen","Feb","Mar","Apr","Mag","Giu","Lug","Ago","Set","Ott","Nov","Dic"};
    C*gx[]={"Lun","Mar","Mer","Gio","Ven","Sab","Dom"};
    
    C*month(a){R 0<=a&&a<12?mx[a]:"\n\aErrore Mese\n";}  //0..11
    C*  day(a){R 0<=a&&a<7 ?gx[a]:"\n\aErrore Giorno\n";}//0..6
 
    NDays(y,m,g,ya,ma,ga)
    {N yt,mt,gt,z=1,t;
     I(cmp(y,m,g,ya,ma,ga)==1)
          {z=-1;
           yt=y ;mt=m ;gt=g ;
           y =ya;m =ma;g =ga;
           ya=yt;ma=mt;ga=gt; 
          } 
     I(y==ya&&m==ma)R z*(ga-g);
     gt=NDaysMonth(y,m)-g;
     I(y!=ya)
        F(mt=m+1;mt<12;++mt) gt+=NDaysMonth(y,mt);
     F(yt=y+1;yt<ya;++yt)    gt+=  NDaysYear(yt);
     F(mt=y==ya?m+1:0;mt<ma;++mt)
                             gt+=NDaysMonth(ya,mt);
     R z*(gt+ga);
    }
    
    //ry,rm,rg = y m g + v con v>0 oppure v<0 anche
    AddToDateDays(N*ry,N*rm,N*rg,N y,N m,N g,N v)
    {   N  r;
        *ry=y;*rm=m;*rg=g;
        I(v>=0)
           {
     a:     r=NDaysMonth(*ry,*rm);
            I(v< r){*rg+=v; R;}
            v-=r;
            ++*rm;
            I(*rm==12){++*ry;*rm=0;*rg=1;}
            G a;
           }
        v=-v;
        if(v<g){*rg-=v;R;}
        v-=g;
        --*rm;
        if(*rm<0){--*ry;*rm=11;*rg=31;}
     b: r=NDaysMonth(*ry,*rm);
        I(v<r){*rg-=v;R;}
        v-=r;
        --*rm;
        I(*rm<0){--*ry;*rm=11;*rg=31;}
        G b;
    }
    
    //argomenti anno:y[0..0xFFFFFF]  mese:m[0..11]
giorno:g[1..NDaysMonth(y,m)]
    //          risultato w:numero Settimane   n:NgiornoSettiamana
    //il resto e' il numero della settiamana dell'anno 
    FromDateToNWeekAndDay(N*y1,N*w,N*n,N y,N m,N g)
    {N c, v;
     c=NDayWeek(y,0,1);// nome del giorno primo gennaio
     //P("Nome del giorno 1 gennaio =%s ", day(c));
     c=c<3?3-c:10-c;   // y 0 c primo giovedi' dell'anno, prima
settimana dell'anno
     c-=2;             // c e' il primo giorno di gennaio che capita
lunedi'
                       // (o dicembre) in questo caso c e' negativo
della I settimana
     //P("Alla fine c=%d\n", c);
     I(g<c){--y;
            c=NDayWeek(y,0,1);
            c=c<3?3-c:10-c;
            c-=2;
            v=NDaysYear(y); v+=g+7; v-=c;
           }
     E      v=NDays(y,0,c,y,m,g);
     *y1=y;*w=1+v/7;*n=v%7;
    }

    //argomenti anno:y[0..0xFFFFFF]  SettimanaAnno:w[0..Nsettimane(y)]
giorno:g[1..NDaysMonth(y,m)] c=0
    //ritorna il numero del giorno nel primo byte della word che
ritorna
    //il resto e' il numero della settiamana dell'anno
    FromNWeekAndDayToDate(N*ry,N*rm,N*rg,  N y,N w,N n)
    {N yy,m,g,c,gg;
     c=NDayWeek(y,0,1);// nome del giorno primo gennaio
     c=c<3?3-c:10-c;   // y 0 c primo giovedi' dell'anno, prima
settimana dell'anno
                       //P("##Lunedi' c=%d |", c);
     c-=3;--w;         // c e' il primo giorno di gennaio che capita
lunedi'
                       // (o dicembre) in questo caso c e' negativo
della I settimana
                       //P("##c=%d |", c);
     gg=7*w+n; yy=NDaysYear(y);
     gg+=gg>=yy?(--y,-c):c;
     AddToDateDays( ry,rm,rg, y, 0, 1, gg);
    }
       
    
    #define W while 
    #define M main
    #define U unsigned
    #define B break
    #define J(a,b)  if(a)goto b
    #define P printf
    #define D double
    #define A getchar()
    #define O putchar
    #define Y malloc
    #define Z free
    #define S sizeof
    #define T struct
    #define Q static
    #define X continue
    
    Test()
    {N r,r1,v, y,m,g, y1, m1, g1, w, n, i;
     P("Montsh");
     F(y=1;y<13;++y)
        P("%s = %d |",  month(y-1), NDaysMonth(2000,y-1));
     P("\n-----------------------------\n");
     P("NDaysYear(y))==366\n");
     F(y=1000; y<1203; ++y) 
         I((r=NDaysYear(y))==366)P("%d ",y);
         E I(r!=365){P("\a\nError\n");R 0;}
     P("\n----------------------------\n");
     P("NDayWeek(y,m,g) \n");
     y =1970;m =2; g =19; r=NDayWeek(y,m,g);
     P("The ");PrintDate(y,m,g);P(" is %s\n", day(r));
     y1=2016;m1=10;g1=3; r=NDayWeek(y1,m1,g1);
     P("The ");PrintDate(y1,m1,g1);P(" is %s\n", day(r));
     P("----------------------------\n");
     P("NDays(y,m,g,ya,ma,ga)\n");
     r =NDays(y,m,g,y1,m1,g1);
     PrintDate(y1,m1,g1);P(" - ");PrintDate(y,m,g);P("=%d\n",r );
     r1=NDays(y1,m1,g1,y,m,g);
     PrintDate(y,m,g);P(" - ");PrintDate(y1,m1,g1);P("=%d\n",r1);
     I(r1+r)R 0;
     P("----------------------------\n");
     P("AddToDateDays(N*ry,N*rm,N*rg,N y,N m,N g,N v)\n");
     v=1000; AddToDateDays(&y1,&m1,&g1,  y,m,g,  v);
     PrintDate(y,m,g);P(" + %d=",v);PrintDate(y1,m1,g1);P("\n");
     AddToDateDays(&y,&m,&g,  y1,m1,g1, -v);
     PrintDate(y1,m1,g1);P(" - %d=",v);PrintDate(y,m,g);P("\n");
     P("----------------------------\n");
     y=2016; m=0; 
     F(i=1;i<20;++i){g=i;
                     FromDateToNWeekAndDay(&y1,&w,&n,y,m,g); 
                     P("Settimana %d, giorno %d, anno=%d----", w, n,
y1);PrintDate(y,m,g);P("\n");
                     FromNWeekAndDayToDate(&y1,&m1,&g1, y,w,n);
PrintDate(y1,m1,g1);P("\n");
                    }
     R 1;
    }
    
    M(){Test();P("\n");}

    /*

[toc] | [next] | [standalone]


#96063

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-11-08 10:55 +0000
Message-ID<87d1i69r5w.fsf@bsb.me.uk>
In reply to#96062
Rosario19 <Ros@invalid.invalid> writes:

> What about my last date functions? there are some error?
> just today i find someones...

Great, a C question!

<snip>
>                            DATES
> Date is 3 numbers integer number: y, m, g where y[one number in
> 0..0xFFFFFF]
> is the year, m[one number in 0..11] is the month g[in 1..31] is the
> day.
>
>     isDate(y,m,g)
> that says if date y,m,g is ok as date [for example y>=0 or 0<=m<=11
> etc]
>
>     GetsDate(number*ry,number*rm,number*rg)
> that gets date from stdin, from file or some other place
> the date in the format  day[ -/\]month[ -/\]year
> and put it in variables *ry=year *rm=month-1 *rg=day
> that represent one date

There's no FILE * parameter, so how does the function know where to get
the date from?

>     PrintDate(y,m,g)
> that print the date
>
>     NDaysMonth(y,m)
> that return the days of the month m of the year y
>
>     NDaysYear(y)
> that return number of days of the year y
>
>     NDayWeek(y,m,g)
> return the number of day for the date y,m,g for example
> 0 for Monday .. 6 for Sunday
>
>     cmp(y,m,g,ya,ma,ga)
> that return -1 if y m g>ya ma ga; 0 if they are the same; else 1
>
>     month(m)
> that return the name of the month m as string [for example month(1)
> return "Feb"]
>
>     day(g)
> as above for month for days 0..6
>
>     Ndays(y,m,g,ya,ma,ga)

I'm surprised you don't have a date structure, at least as an
alternative.

> return the difference in days from (y m g) to (ya ma ga); return one
> negative
> number if  (y m g) > (ya ma ga)
>
>     AddToDateDays(N*ry,N*rm,N*rg,N y,N m,N g,N v)
> sum to date (y,m,g) the number [positive or negative] v; put the date
> result in result (ry,rm,rg)

There's not enough explanation here.  I don't know what this function
does exactly.  The notation (for exaple N*rg) does not help.

> ------------------------------------------------
>     #define R return
>     #define L(i) for(;i-->0;)
>     #define I if
>     #define N int
>     #define C unsigned char
>     #define F for
>     #define G goto
>     #define P printf
>     #define E else

Ah.  I'm not surprised there are bugs, but I'm not going to wade through
this to try to fund any.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#96064

From"Mr. Man-wai Chang" <toylet.toylet@gmail.com>
Date2016-11-08 19:00 +0800
Message-ID<nvsb84$fuf$2@dont-email.me>
In reply to#96063
On 8/11/2016 6:55 PM, Ben Bacarisse wrote:
>...
> Ah.  I'm not surprised there are bugs, but I'm not going to wade through
> this to try to fund any.

Do NOT try to be C compilers and pre-processors! You are NOT a software 
machine. ;)

[toc] | [prev] | [next] | [standalone]


#96065

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-11-08 11:04 +0000
Message-ID<877f8e9qr4.fsf@bsb.me.uk>
In reply to#96063
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
<snip>
> Ah.  I'm not surprised there are bugs, but I'm not going to wade through
> this to try to fund any.

"find" not "fund" -- a frozen finger fumble.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#96067

From"Mr. Man-wai Chang" <toylet.toylet@gmail.com>
Date2016-11-08 19:22 +0800
Message-ID<nvscg7$klr$1@dont-email.me>
In reply to#96065
On 8/11/2016 7:04 PM, Ben Bacarisse wrote:
> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> <snip>
>> Ah.  I'm not surprised there are bugs, but I'm not going to wade through
>> this to try to fund any.
>
> "find" not "fund" -- a frozen finger fumble.

I want some fun... sorry, I meant "fund"!  :)

[toc] | [prev] | [next] | [standalone]


#96068

FromRichard Heathfield <rjh@cpax.org.uk>
Date2016-11-08 11:35 +0000
Message-ID<nvsd9k$nd4$1@dont-email.me>
In reply to#96063
On 08/11/16 10:55, Ben Bacarisse wrote:
> Rosario19 <Ros@invalid.invalid> writes:
>
>> What about my last date functions? there are some error?
>> just today i find someones...
>
> Great, a C question!

Aye. (Read on!)

<snip>
>>
>>     Ndays(y,m,g,ya,ma,ga)
>
> I'm surprised you don't have a date structure, at least as an
> alternative.

And that's one of the reasons I read comp.lang.c.

A few years ago, I stole a Julian date algorithm from the Web, and it 
never, ever occurred to me to use a struct to package up the day, month, 
and year parameters.

<snip>

>>     #define R return
>>     #define L(i) for(;i-->0;)
>>     #define I if
>>     #define N int
>>     #define C unsigned char
>>     #define F for
>>     #define G goto
>>     #define P printf
>>     #define E else
>
> Ah.  I'm not surprised there are bugs, but I'm not going to wade through
> this to try to fund any.

Will you fund my bugs instead?

But yes, of course you're right - such code renders itself useless 
because it's unreadable.

Even if there were /no/ bugs, it would still be useless *as code*, 
because it's unreadable. (That doesn't mean it couldn't be useful as a 
black box routine, right up until the point where a bug was found, after 
which it would revert to being useless again.)

My own Julian date routines (at least, the ones for converting to and 
from Julian date) are completely unreadable, because I stole the 
algorithm from the Web rather than devising it myself. I spent about an 
hour figuring out how it worked, neglected to write it down on that 
occasion, and have never since summoned up the energy to repeat the 
analysis.

It was so unreadable that I tried to make it worse! I wrote a 
'compressed' version of it (with minimal line count and minimal spaces) 
just for fun.

  The 'date of Easter' source is pretty hairy, too.

As source code, the library (at least the bits of it that I purloined) 
is quite useless. But until it breaks, I'll keep on using it as a black 
box. And it hasn't broken yet.

I suppose, after telling you all that, I have to show you. Here are the 
minimalist versions of tojul() and fromjul():

long tojul(int yp,int mp,int dp){long 
a=(14-mp)/12,y=yp+4800-a,m=mp+12*a-3,jdn=dp+(153*m+2)/5+365*y+y/4-y/100+y/400-32045;return 
jdn;}
void fromjul(int*yp,int*mp,int*dp,long jdn){long 
y=4716,j=1401,m=2,n=12,r=4,p=1461,v=3,u=5,s=153,w=2,b=274277,c=-38,f=jdn+j+(((4*jdn+b)/146097)*3)/4+c,e=r*f+v,g=(e%p)/r,h=u*g+w;*dp=(h%s)/u+1;*mp=((h/s+m)%n)+1;*yp=e/p-y+(n+m-*mp)/n;}

To calculate the day of the week from a Julian date, just % 7. Monday is 
0, Tuesday is 1, etc.

Once you have a Julian date, some date tasks become trivial:

difference in days = onejdate - anotherjdate
six weeks after a given date = jdate + 42

etc.

With a little fiddling, you can do things like "third Thursday of the 
month" or, more generally, nth Xday of the month; or a function 
is_bank_holiday() - which is fairly easy in the UK because we have 
fairly predictable bank holidays, and even easier in the USA because you 
don't have bank holidays at all!

But I never thought of a struct. So thanks for that.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

[toc] | [prev] | [next] | [standalone]


#96087

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-11-08 15:46 +0000
Message-ID<871sym9dpv.fsf@bsb.me.uk>
In reply to#96068
Richard Heathfield <rjh@cpax.org.uk> writes:
<snip>
> My own Julian date routines (at least, the ones for converting to and
> from Julian date) are completely unreadable, because I stole the
> algorithm from the Web rather than devising it myself. I spent about
> an hour figuring out how it worked, neglected to write it down on that
> occasion, and have never since summoned up the energy to repeat the
> analysis.
>
> It was so unreadable that I tried to make it worse! I wrote a
> 'compressed' version of it (with minimal line count and minimal
> spaces) just for fun.

How odd.  Maybe a joke I'm not getting.

> long tojul(int yp,int mp,int dp){long
> a=(14-mp)/12,y=yp+4800-a,m=mp+12*a-3,jdn=dp+(153*m+2)/5+365*y+y/4-y/100+y/400-32045;return
> jdn;}
> void fromjul(int*yp,int*mp,int*dp,long jdn){long
> y=4716,j=1401,m=2,n=12,r=4,p=1461,v=3,u=5,s=153,w=2,b=274277,c=-38,f=jdn+j+(((4*jdn+b)/146097)*3)/4+c,e=r*f+v,g=(e%p)/r,h=u*g+w;*dp=(h%s)/u+1;*mp=((h/s+m)%n)+1;*yp=e/p-y+(n+m-*mp)/n;}

I usually use the standard library function for this sort of thing, but
if this works for you why rock the boat?

> But I never thought of a struct. So thanks for that.

If you use the standard library functions there's even one ready to be
used.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#96098

FromRichard Heathfield <rjh@cpax.org.uk>
Date2016-11-08 16:20 +0000
Message-ID<nvstum$jt5$1@dont-email.me>
In reply to#96087
On 08/11/16 15:46, Ben Bacarisse wrote:
> Richard Heathfield <rjh@cpax.org.uk> writes:

<snip>

>> long tojul(int yp,int mp,int dp){long
>> a=(14-mp)/12,y=yp+4800-a,m=mp+12*a-3,jdn=dp+(153*m+2)/5+365*y+y/4-y/100+y/400-32045;return
>> jdn;}
>> void fromjul(int*yp,int*mp,int*dp,long jdn){long
>> y=4716,j=1401,m=2,n=12,r=4,p=1461,v=3,u=5,s=153,w=2,b=274277,c=-38,f=jdn+j+(((4*jdn+b)/146097)*3)/4+c,e=r*f+v,g=(e%p)/r,h=u*g+w;*dp=(h%s)/u+1;*mp=((h/s+m)%n)+1;*yp=e/p-y+(n+m-*mp)/n;}
>
> I usually use the standard library function for this sort of thing, but
> if this works for you why rock the boat?

A search of N1570 for "Julian" yields no hits.

<time.h> gives us clock(), difftime(), mktime(), time(), timespec_get(), 
asctime(), ctime(), gmtime(), localtime(), and strftime(). None of these 
claims to work with Julian dates.

Of course, the standard library functions are perfectly adequate for 
many date-related tasks. But they do have their limitations, and for 
some purposes Julian dates are much more convenient. What's more, on 
some Unix systems the range of dates representable in a time_t is rather 
less than 140 years (roughly 1901 to 2038). If one needs to work with 
dates outside that range, one must find another way of doing so. The 
code I presented assumes astronomical numbering, i.e. there *is* a year 
0, and that may be a problem for some people, so I will make the lesser 
claim that it works from 1/1/1 AD to many millions of years into the 
future. (I tested various cases up to 1,000,000,000 years.)

>> But I never thought of a struct. So thanks for that.
>
> If you use the standard library functions there's even one ready to be
> used.

Yes, but it doesn't have a spare member for the Julian date.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

[toc] | [prev] | [next] | [standalone]


#96103

FromRosario19 <Ros@invalid.invalid>
Date2016-11-08 17:44 +0100
Message-ID<c5042c1i67ad9417i0r5va07j30tmg7d2b@4ax.com>
In reply to#96098
On Tue, 8 Nov 2016 16:20:02 +0000, Richard Heathfield wrote:

>(I tested various cases up to 1,000,000,000 years.)

copy and paste your code it seems to me here overflow in year
                                   9,000,000

[toc] | [prev] | [next] | [standalone]


#96106

FromRichard Heathfield <rjh@cpax.org.uk>
Date2016-11-08 16:51 +0000
Message-ID<nvsvpo$r4r$1@dont-email.me>
In reply to#96103
On 08/11/16 16:44, Rosario19 wrote:

> it seems to me here overflow in year
>                                    9,000,000

(a) It doesn't on mine. That may be because I have wider integers on the 
compiler I'm using at the moment (gcc 4.8.4).
(b) It works fine for the dates I typically use it for (which are, 
broadly speaking, dates in the first, second, and third millennia), so I 
don't plan to fix it any time soon.
(c) Feel free to use your own instead.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

[toc] | [prev] | [next] | [standalone]


#96111

FromJerry Stuckle <jstucklex@attglobal.net>
Date2016-11-08 13:21 -0500
Message-ID<nvt521$ed3$1@jstuckle.eternal-september.org>
In reply to#96106
On 11/8/2016 11:51 AM, Richard Heathfield wrote:
> On 08/11/16 16:44, Rosario19 wrote:
> 
>> it seems to me here overflow in year
>>                                    9,000,000
> 
> (a) It doesn't on mine. That may be because I have wider integers on the
> compiler I'm using at the moment (gcc 4.8.4).
> (b) It works fine for the dates I typically use it for (which are,
> broadly speaking, dates in the first, second, and third millennia), so I
> don't plan to fix it any time soon.
> (c) Feel free to use your own instead.
> 

Oh, no! A Y9M bug!

-- 
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================

[toc] | [prev] | [next] | [standalone]


#96108

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-11-08 18:06 +0000
Message-ID<87bmxp978j.fsf@bsb.me.uk>
In reply to#96098
Richard Heathfield <rjh@cpax.org.uk> writes:

> On 08/11/16 15:46, Ben Bacarisse wrote:
>> Richard Heathfield <rjh@cpax.org.uk> writes:
>
> <snip>
>
>>> long tojul(int yp,int mp,int dp){long
>>> a=(14-mp)/12,y=yp+4800-a,m=mp+12*a-3,jdn=dp+(153*m+2)/5+365*y+y/4-y/100+y/400-32045;return
>>> jdn;}
>>> void fromjul(int*yp,int*mp,int*dp,long jdn){long
>>> y=4716,j=1401,m=2,n=12,r=4,p=1461,v=3,u=5,s=153,w=2,b=274277,c=-38,f=jdn+j+(((4*jdn+b)/146097)*3)/4+c,e=r*f+v,g=(e%p)/r,h=u*g+w;*dp=(h%s)/u+1;*mp=((h/s+m)%n)+1;*yp=e/p-y+(n+m-*mp)/n;}
>>
>> I usually use the standard library function for this sort of thing, but
>> if this works for you why rock the boat?
>
> A search of N1570 for "Julian" yields no hits.

I meant I'd implement to_julian using C's functions.  For one thing, I'd
then be using a standard date structure.  It's not a lot of code though
if you need a very wide range of dates it might be more fussy.

> <time.h> gives us clock(), difftime(), mktime(), time(),
> timespec_get(), asctime(), ctime(), gmtime(), localtime(), and
> strftime(). None of these claims to work with Julian dates.
>
> Of course, the standard library functions are perfectly adequate for
> many date-related tasks. But they do have their limitations, and for
> some purposes Julian dates are much more convenient. What's more, on
> some Unix systems the range of dates representable in a time_t is
> rather less than 140 years (roughly 1901 to 2038).

I'd try really hard to avoid using one of these!  2038 (the real Y2K
problem) is just too near.

> work with dates outside that range, one must find another way of doing
> so. The code I presented assumes astronomical numbering, i.e. there
> *is* a year 0, and that may be a problem for some people, so I will
> make the lesser claim that it works from 1/1/1 AD to many millions of
> years into the future. (I tested various cases up to 1,000,000,000
> years.)

Not on all systems.  I suspect your preferred code will not go that far
out on exactly the same systems that have a limited range of time_t
values.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#96113

FromRichard Heathfield <rjh@cpax.org.uk>
Date2016-11-08 18:56 +0000
Message-ID<nvt73j$o68$1@dont-email.me>
In reply to#96108
On 08/11/16 18:06, Ben Bacarisse wrote:
<snip>
> I suspect your preferred code will not go that far
> out on exactly the same systems that have a limited range of time_t
> values.

You're right, of course. Nevertheless, it's still a win over time_t. 
Let's assume time_t uses a long int under the bonnet, and let's further 
assume that it encodes seconds (a not uncommon implementation, as we 
both know). On a 32-bit-long-int system, that gives us a range of 49710 
days, which is 136+ years. Julian dates, on the same system, can cover 
well over 11,000,000 years.

I have no particular need for /millions/ of years, at least not yet, but 
I find the ability to stretch back through the second millennium (and 
even into the first) to be useful from time to time.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

[toc] | [prev] | [next] | [standalone]


#96123

FromKeith Thompson <kst-u@mib.org>
Date2016-11-08 12:05 -0800
Message-ID<lnh97hrb3q.fsf@kst-u.example.com>
In reply to#96113
Richard Heathfield <rjh@cpax.org.uk> writes:
> On 08/11/16 18:06, Ben Bacarisse wrote:
> <snip>
>> I suspect your preferred code will not go that far
>> out on exactly the same systems that have a limited range of time_t
>> values.
>
> You're right, of course. Nevertheless, it's still a win over time_t. 
> Let's assume time_t uses a long int under the bonnet, and let's further 
> assume that it encodes seconds (a not uncommon implementation, as we 
> both know). On a 32-bit-long-int system, that gives us a range of 49710 
> days, which is 136+ years. Julian dates, on the same system, can cover 
> well over 11,000,000 years.
>
> I have no particular need for /millions/ of years, at least not yet, but 
> I find the ability to stretch back through the second millennium (and 
> even into the first) to be useful from time to time.

Desktop Unix-like systems these days tend to make time_t a 64-bit signed
integer.

On the other hand, 32-bit systems still exist.  They can still be
updated to use a 64-bit time_t, and I expect that's what will happen
between now and 2038, but so far I haven't heard of a system with 32-bit
long int and 64-bit time_t.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#96125

FromDavid Brown <david.brown@hesbynett.no>
Date2016-11-08 21:10 +0100
Message-ID<nvtbef$ahk$1@dont-email.me>
In reply to#96113
On 08/11/16 19:56, Richard Heathfield wrote:
> On 08/11/16 18:06, Ben Bacarisse wrote:
> <snip>
>> I suspect your preferred code will not go that far
>> out on exactly the same systems that have a limited range of time_t
>> values.
>
> You're right, of course. Nevertheless, it's still a win over time_t.
> Let's assume time_t uses a long int under the bonnet, and let's further
> assume that it encodes seconds (a not uncommon implementation, as we
> both know). On a 32-bit-long-int system, that gives us a range of 49710
> days, which is 136+ years. Julian dates, on the same system, can cover
> well over 11,000,000 years.
>
> I have no particular need for /millions/ of years, at least not yet, but
> I find the ability to stretch back through the second millennium (and
> even into the first) to be useful from time to time.
>

These things can be important.  For example, what day of the week will 
Andromeda hit the Milky Way?  I hope it is not a Tuesday - I am usually 
busy on Tuesdays.

[toc] | [prev] | [next] | [standalone]


#96130

FromRichard Heathfield <rjh@cpax.org.uk>
Date2016-11-08 20:16 +0000
Message-ID<nvtbqf$c4q$1@dont-email.me>
In reply to#96125
On 08/11/16 20:10, David Brown wrote:

<snip>
>
> These things can be important.  For example, what day of the week will
> Andromeda hit the Milky Way?

It'll be a Thursday, just before lunch.

> I hope it is not a Tuesday - I am usually
> busy on Tuesdays.

No, you're fine.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

[toc] | [prev] | [next] | [standalone]


#96115

Fromjadill33@gmail.com
Date2016-11-08 11:16 -0800
Message-ID<a4078985-def6-4593-9f9d-3989b2a8ff18@googlegroups.com>
In reply to#96098
On Tuesday, November 8, 2016 at 11:20:11 AM UTC-5, Richard Heathfield wrote:
> On 08/11/16 15:46, Ben Bacarisse wrote:
> > Richard Heathfield <r...@cpax.org.uk> writes:
> 
> <snip>
> 
> >> long tojul(int yp,int mp,int dp){long
> >> a=(14-mp)/12,y=yp+4800-a,m=mp+12*a-3,jdn=dp+(153*m+2)/5+365*y+y/4-y/100+y/400-32045;return
> >> jdn;}
> >> void fromjul(int*yp,int*mp,int*dp,long jdn){long
> >> y=4716,j=1401,m=2,n=12,r=4,p=1461,v=3,u=5,s=153,w=2,b=274277,c=-38,f=jdn+j+(((4*jdn+b)/146097)*3)/4+c,e=r*f+v,g=(e%p)/r,h=u*g+w;*dp=(h%s)/u+1;*mp=((h/s+m)%n)+1;*yp=e/p-y+(n+m-*mp)/n;}
> >
> > I usually use the standard library function for this sort of thing, but
> > if this works for you why rock the boat?
> 
> A search of N1570 for "Julian" yields no hits.
> 
> <time.h> gives us clock(), difftime(), mktime(), time(), timespec_get(), 
> asctime(), ctime(), gmtime(), localtime(), and strftime(). None of these 
> claims to work with Julian dates.
> 
> Of course, the standard library functions are perfectly adequate for 
> many date-related tasks. But they do have their limitations, and for 
> some purposes Julian dates are much more convenient. What's more, on 
> some Unix systems the range of dates representable in a time_t is rather 
> less than 140 years (roughly 1901 to 2038). If one needs to work with 
> dates outside that range, one must find another way of doing so. The 
> code I presented assumes astronomical numbering, i.e. there *is* a year 
> 0, and that may be a problem for some people, so I will make the lesser 
> claim that it works from 1/1/1 AD to many millions of years into the 
> future. (I tested various cases up to 1,000,000,000 years.)
> 
> >> But I never thought of a struct. So thanks for that.
> >
> > If you use the standard library functions there's even one ready to be
> > used.
> 
> Yes, but it doesn't have a spare member for the Julian date.

I'm curious, if you don't mind, what's your use-case on calculating a
Julian date when the Gregorian calendar is primarily what we use these
days?

Best regards,
John D.

[toc] | [prev] | [next] | [standalone]


#96124

FromRichard Heathfield <rjh@cpax.org.uk>
Date2016-11-08 20:08 +0000
Message-ID<nvtbaf$9uf$1@dont-email.me>
In reply to#96115
On 08/11/16 19:16, jadill33@gmail.com wrote:

<snip>

> I'm curious, if you don't mind, what's your use-case on calculating a
> Julian date when the Gregorian calendar is primarily what we use these
> days?

Oh, I don't care about it being Julian. In fact, that's just a name as 
far as I'm concerned. What I find useful is simply the fact that the 
date is represented as a single integer, such that to get tomorrow's 
date from today's, all I have to do is ++d, without worrying about 
whether this is the last day of the month or the last day of the year.

Consider how we might prepare a list of dates, 30 days apart, starting 
from next Tuesday, and continuing until 17th January 2021. We might do 
it like this (I'm assuming C90 here, for maximum portability):

time_t tmtstart = {0};
time_t tmtend = {0};

struct tm start_date = {0};
struct tm end_date = {0};

start_date.tm_year = 116; /* tm_year is 1900-based! */
start_date.tm_mon = 10; /* November, not October! tm_mon is 0-11 */
start_date.tm_mday = 15; /* 15th, not 14th! tm_mday is 1-31 */
end_date.tm_year = 121;
end_date.tm_mon = 0;
end_date.tm_mday = 17;
tmtstart = mktime(&start_date);
tmtend = mktime(&end_date);

while(difftime(tmtend, tmtstart) > 0.0)
{
   /* I could use strftime here, but it seems unnecessary for such a 
simple printf */
   printf("%02d/%02d/%04d\n",
          tmtstart.tm_mday,
          tmtstart.tm_mon,
          tmtstart.tm_year + 1900);
   start_date.tm_mday += 30;
   tmtstart = mktime(&start_date);
}

And that's fine. But it's a lot of code for such a simple task (and, to 
my eyes at least, it's ugly code). Now consider this:

long start = tojul(2016, 11, 15);
long end = tojul(2021, 1, 17);
int d = 0;
int m = 0;
int y = 0;
while(start < end)
{
   fromjul(&y, &m, &d, start);
   printf("%02d/%02d/%04d\n", d, m, y);
   start += 30;
}

(I note in passing that the Julian version uses two function calls per 
loop iteration rather than three.)

Okay, some people might prefer the former code, but I'm not one of them.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

[toc] | [prev] | [next] | [standalone]


#96128

FromKeith Thompson <kst-u@mib.org>
Date2016-11-08 12:11 -0800
Message-ID<lnd1i5rasx.fsf@kst-u.example.com>
In reply to#96115
jadill33@gmail.com writes:
[...]
> I'm curious, if you don't mind, what's your use-case on calculating a
> Julian date when the Gregorian calendar is primarily what we use these
> days?

Confusingly, the word "Julian" is used for two different purposes
in calendar discussions.

The Julian calendar was the one that was replaced by the Gregorian
calendar starting in 1582.  The Julian calendar has a leap year
every 4 years.  The Gregorian calendar uses a formula that gives
us 97 leap years in every 400 years, which is a much better (but
still imperfect) approximation to reality.

A Julian Day Number (JDN) is the whole number of days since noon,
Jan 1, 4713 BCE.  A Julian date is the same thing, but with an added
fractional part.  They're commonly used in astronomy, because they
make calculations simpler (no leap years, no variable number of
days per month).  It plays a similar role to the Unix epoch time,
the number of seconds since 1970-01-01 00:00:00 UTC, a representation
optimized for ease of calculation rather than for human readability.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#96132

FromKeith Thompson <kst-u@mib.org>
Date2016-11-08 12:29 -0800
Message-ID<ln8tstr9yw.fsf@kst-u.example.com>
In reply to#96128
Keith Thompson <kst-u@mib.org> writes:
[...]
> A Julian Day Number (JDN) is the whole number of days since noon,
> Jan 1, 4713 BCE.

And that date is specified in the proleptic Julian calendar.
("Proleptic" means that the rules of the Julian calendar, with one leap
year every 4 years, are extrapolated back to before the calendar was
instituted.)

[...]

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.c


csiph-web