int32_t OS_conv_unixtime(int32_t *secondsp,time_t timestamp) // gmtime -> datenum + number of seconds { struct tm t; int32_t datenum; uint32_t checktime; char buf[64]; t = *gmtime(×tamp); strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%SZ",&t); //printf("%s\n",buf); datenum = conv_date(secondsp,buf); if ( (checktime= OS_conv_datenum(datenum,*secondsp/3600,(*secondsp%3600)/60,*secondsp%60)) != timestamp ) { printf("error: timestamp.%lu -> (%d + %d) -> %u\n",timestamp,datenum,*secondsp,checktime); return(-1); } return(datenum); }
int main(int argc, const char * argv[]) { int i; char str[111],str2[111],str3[111],str4[111]; struct taitime ct; struct tai t,start = tai_now(); for (i=0; i<100; i++) { sleep(1); t = tai_now(); taidate_str(str2,tai2date(t)); printf("(%s) time.%s date.%s %ld start.%ld %s %u %u\n",tai_str(str3,t),taitime_str(str,ct),str2,(long)tai2utime(t),(long)tai2utime(start),utime_str(str4,t),tai2utc(t),(uint32_t)time(NULL)); } // insert code here... { char str[65]; struct tai t; double startmillis; int32_t datenum,seconds; uint64_t i,checkval,timestamp,now = (uint32_t)time(NULL); startmillis = OS_milliseconds(); for (i=0; i<1000000; i++) { timestamp = now - (rand() % 100000000LL); // range -100000000LL to +500000000LL datenum = OS_conv_unixtime(&t,&seconds,timestamp); // gmtime -> datenum + number of seconds checkval = OS_conv_datenum(datenum,seconds/3600,(seconds/60)%60,seconds%60); // datenum+H:M:S -> unix time if ( checkval != timestamp ) printf("%s i.%lld timestamp.%-12llu -> (%d:%06d) -> checkval.%-12llu diff.[%lld]\n",tai_str(str,t),(long long)i,(long long)timestamp,datenum,seconds,(long long)checkval,(long long)(timestamp-checkval)); } printf("million tai compares in %.3f microseconds per encode/decode\n",1000. * (OS_milliseconds()-startmillis)/i); } /* struct tai t = tai_now(); double diff,lastdiff = 0.; for (i=0; i<1000000; i++) { diff = tai_diff(t,tai_now()); if ( diff < lastdiff ) printf("embargo.x %f %llu.%3.3f %llu.%3.3f\n",tai_diff(t,tai_now()),(long long)t.x,t.millis,(long long)tai_now().x,tai_now().millis); lastdiff = diff; //usleep(100000); } getchar(); */ return 0; }
int32_t OS_conv_unixtime(struct tai *tp,int32_t *secondsp,time_t timestamp) // gmtime -> datenum + number of seconds { struct tm tm,*ptr; int32_t datenum; uint32_t checktime; char buf[64]; struct tai t; struct taitime ct; if ( 1 ) { *tp = t = utc2tai((uint32_t)timestamp); ct = tai2time(t,0,0); *secondsp = (ct.hour*3600 + ct.minute*60 + ct.second); return(calc_datenum(ct.date.year,ct.date.month,ct.date.day)); } else { if ( (ptr= gmtime(×tamp)) != 0 ) tm = *ptr;; strftime(buf,sizeof(buf), "%Y-%m-%dT%H:%M:%SZ",&tm); //printf("%s\n",buf); datenum = conv_date(secondsp,buf); if ( (checktime= OS_conv_datenum(datenum,*secondsp/3600,(*secondsp%3600)/60,*secondsp%60)) != timestamp ) { printf("error: timestamp.%u -> (%d + %d) -> %u\n",(uint32_t)timestamp,datenum,*secondsp,checktime); return(-1); } return(datenum); } }
void PAX_btcprices(struct peggy_info *PEGS,int32_t enddatenum,int32_t numdates) { int32_t i,n,year,month,day,seconds,datenum; char url[1024],date[64],*dstr,*str; uint32_t timestamp,utc32[MAX_SPLINES]; struct tai t; cJSON *coindesk,*quandl,*btcdhist,*bpi,*array,*item; double btcddaily[MAX_SPLINES],cdaily[MAX_SPLINES],qdaily[MAX_SPLINES],ask,high,low,bid,close,vol,quotevol,open,price = 0.; coindesk = url_json("http://api.coindesk.com/v1/bpi/historical/close.json"); sprintf(url,"https://poloniex.com/public?command=returnChartData¤cyPair=BTC_BTCD&start=%ld&end=9999999999&period=86400",(long)(time(NULL)-numdates*3600*24)); if ( (bpi= jobj(coindesk,"bpi")) != 0 ) { datenum = enddatenum; memset(utc32,0,sizeof(utc32)); memset(cdaily,0,sizeof(cdaily)); if ( datenum == 0 ) { datenum = OS_conv_unixtime(&t,&seconds,(uint32_t)time(NULL)); printf("got datenum.%d %d %d %d\n",datenum,seconds/3600,(seconds/60)%24,seconds%60); } for (i=0; i<numdates; i++) { expand_datenum(date,datenum); if ( (price= jdouble(bpi,date)) != 0 ) { utc32[numdates - 1 - i] = OS_conv_datenum(datenum,12,0,0); cdaily[numdates - 1 - i] = price * .001; //printf("(%s %u %f) ",date,utc32[numdates - 1 - i],price); } datenum = ecb_decrdate(&year,&month,&day,date,datenum); } PAX_genspline(&PEGS->splines[MAX_CURRENCIES],MAX_CURRENCIES,"coindesk",utc32,cdaily,numdates,cdaily); } else printf("no bpi\n"); quandl = url_json("https://www.quandl.com/api/v1/datasets/BAVERAGE/USD.json?rows=64"); if ( (str= jstr(quandl,"updated_at")) != 0 && (datenum= conv_date(&seconds,str)) > 0 && (array= jarray(&n,quandl,"data")) != 0 ) { printf("datenum.%d data.%d %d\n",datenum,n,cJSON_GetArraySize(array)); memset(utc32,0,sizeof(utc32)), memset(qdaily,0,sizeof(qdaily)); for (i=0; i<n&&i<MAX_SPLINES; i++) { // ["Date","24h Average","Ask","Bid","Last","Total Volume"] // ["2015-07-25",289.27,288.84,288.68,288.87,44978.61] item = jitem(array,i); if ( Debuglevel > 2 ) printf("(%s) ",cJSON_Print(item)); if ( (dstr= jstr(jitem(item,0),0)) != 0 && (datenum= conv_date(&seconds,dstr)) > 0 ) { price = jdouble(jitem(item,1),0), ask = jdouble(jitem(item,2),0), bid = jdouble(jitem(item,3),0); close = jdouble(jitem(item,4),0), vol = jdouble(jitem(item,5),0); if ( Debuglevel > 2 ) fprintf(stderr,"%d.[%d %f %f %f %f %f].%d ",i,datenum,price,ask,bid,close,vol,n); utc32[numdates - 1 - i] = OS_conv_datenum(datenum,12,0,0), qdaily[numdates - 1 - i] = price * .001; } } PAX_genspline(&PEGS->splines[MAX_CURRENCIES+1],MAX_CURRENCIES+1,"quandl",utc32,qdaily,n<MAX_SPLINES?n:MAX_SPLINES,qdaily); } btcdhist = url_json(url); //{"date":1406160000,"high":0.01,"low":0.00125,"open":0.01,"close":0.001375,"volume":1.50179994,"quoteVolume":903.58818412,"weightedAverage":0.00166204}, if ( (array= jarray(&n,btcdhist,0)) != 0 ) { memset(utc32,0,sizeof(utc32)), memset(btcddaily,0,sizeof(btcddaily)); //printf("GOT.(%s)\n",cJSON_Print(array)); for (i=0; i<n; i++) { item = jitem(array,i); timestamp = juint(item,"date"), high = jdouble(item,"high"), low = jdouble(item,"low"), open = jdouble(item,"open"); close = jdouble(item,"close"), vol = jdouble(item,"volume"), quotevol = jdouble(item,"quoteVolume"), price = jdouble(item,"weightedAverage"); //printf("[%u %f %f %f %f %f %f %f]",timestamp,high,low,open,close,vol,quotevol,price); if ( Debuglevel > 2 ) printf("[%u %d %f]",timestamp,OS_conv_unixtime(&t,&seconds,timestamp),price); utc32[i] = timestamp - 12*3600, btcddaily[i] = price * 100.; } if ( Debuglevel > 2 ) printf("poloniex.%d\n",n); PAX_genspline(&PEGS->splines[MAX_CURRENCIES+2],MAX_CURRENCIES+2,"btcdhist",utc32,btcddaily,n<MAX_SPLINES?n:MAX_SPLINES,btcddaily); } // https://poloniex.com/public?command=returnChartData¤cyPair=BTC_BTCD&start=1405699200&end=9999999999&period=86400 }
uint32_t OS_conv_utime(char *utime) { int32_t datenum,seconds; datenum = conv_date(&seconds,utime); return((uint32_t)OS_conv_datenum(datenum,seconds/3600,(seconds%3600)/60,seconds%60)); }