hschumann2/TempleOS-Source-Code
0838
1 2//See ::/Doc/TimeDate.DD3 4U16 mon_start_days1[12]={50,31,59,90,120,151,181,212,243,273,304,334};6U16 mon_start_days2[12]={70,31,60,91,121,152,182,213,244,274,305,335};8 9I64 YearStartDate(I64 year)10{//32-bit day since AD 0, given year number.11 I64 y1=year-1,yd4000=y1/4000,yd400=y1/400,yd100=y1/100,yd4=y1/4;12 return year*365+yd4-yd100+yd400-yd4000;13}14 15CDate Struct2Date(CDateStruct *_ds)16{//Cvt CDateStruct to CDate.17 CDate cdt;18 I64 i1,i2;19 i1=YearStartDate(_ds->year);20 i2=YearStartDate(_ds->year+1);21 if (i2-i1==365)22 i1+=mon_start_days1[_ds->mon-1];23 else24 i1+=mon_start_days2[_ds->mon-1];25 cdt.date=i1+_ds->day_of_mon-1;26 cdt.time=(_ds->sec10000+100*(_ds->sec100+100*(_ds->sec27 +60*(_ds->min+60*_ds->hour))))<<21/(15*15*3*625);28 return cdt;29}30 31I64 DayOfWeek(I64 i)32{//Day of week, given 32-bit day since AD 0.33 i+=CDATE_BASE_DAY_OF_WEEK;34 if (i>=0)35 return i % 7;36 else37 return 6-(6-i)%7;38}39 40U0 Date2Struct(CDateStruct *_ds,CDate cdt)41{//Cvt CDate to CDateStruct.42 I64 i,k,date=cdt.date;43 _ds->day_of_week=DayOfWeek(date);44 _ds->year=(date+1)*100000/CDATE_YEAR_DAYS_INT;45 i=YearStartDate(_ds->year);46 while (i>date) {47 _ds->year--;48 i=YearStartDate(_ds->year);49 }50 date-=i;51 if (YearStartDate(_ds->year+1)-i==365) {52 k=0;53 while (date>=mon_start_days1[k+1] && k<11)54 k++;55 date-=mon_start_days1[k];56 } else {57 k=0;58 while (date>=mon_start_days2[k+1] && k<11)59 k++;60 date-=mon_start_days2[k];61 }62 _ds->mon=k+1;63 _ds->day_of_mon=date+1;64 k=(625*15*15*3*cdt.time)>>21+1;65 _ds->sec10000=ModU64(&k,100);66 _ds->sec100=ModU64(&k,100);67 _ds->sec=ModU64(&k,60);68 _ds->min=ModU64(&k,60);69 _ds->hour =k;70}71 72I64 FirstDayOfMon(I64 i)73{//First day of month, given 32-bit day since AD 0.74 CDateStruct ds;75 CDate cdt=0;76 cdt.date=i;77 Date2Struct(&ds,cdt);78 ds.day_of_mon=1;79 cdt=Struct2Date(&ds);80 return cdt.date;81}82 83I64 LastDayOfMon(I64 i)84{//Last day of month, given 32-bit day since AD 0.85 CDateStruct ds;86 CDate cdt=0;87 cdt.date=i;88 Date2Struct(&ds,cdt);89 ds.mon++;90 if (ds.mon==13) {91 ds.mon=0;92 ds.year++;93 }94 ds.day_of_mon=1;95 cdt=Struct2Date(&ds);96 return cdt.date-1;97}98 99I64 FirstDayOfYear(I64 i)100{//First day of year, given 32-bit day since AD 0.101 CDateStruct ds;102 CDate cdt=0;103 cdt.date=i;104 Date2Struct(&ds,cdt);105 ds.day_of_mon=1;106 ds.mon=1;107 cdt=Struct2Date(&ds);108 return cdt.date;109}110 111I64 LastDayOfYear(I64 i)112{//Last day of year, given 32-bit day since AD 0.113 CDateStruct ds;114 CDate cdt=0;115 cdt.date=i;116 Date2Struct(&ds,cdt);117 ds.day_of_mon=1;118 ds.mon=1;119 ds.year++;120 cdt=Struct2Date(&ds);121 return cdt.date-1;122}123 124I64 Bcd2Bin(U64 b)125{126 I64 i,res=0;127 for (i=0;i<16;i++) {128 res=res*10+b>>60;129 b<<=4;130 }131 return res;132}133 134U0 NowDateTimeStruct(CDateStruct *_ds)135{136 I64 i;137 U8 *b=_ds;138 Bool is_bcd;139 140 MemSet(_ds,0,sizeof(CDateStruct));141 PUSHFD142 CLI143 while (LBts(&sys_semas[SEMA_SYS_DATE],0))144 PAUSE145 146 OutU8(0x70,0x0A);147 do {148 while (InU8(0x71) & 0x80)149 PAUSE150 151 OutU8(0x70,0);152 b[2]=InU8(0x71);153 OutU8(0x70,2);154 b[3]=InU8(0x71);155 OutU8(0x70,4);156 b[4]=InU8(0x71);157 158 OutU8(0x70,6);159 b[5]=InU8(0x71);160 OutU8(0x70,7);161 b[6]=InU8(0x71);162 OutU8(0x70,8);163 b[7]=InU8(0x71);164 OutU8(0x70,9);165 b[8]=InU8(0x71);166 167 OutU8(0x70,0x0A);168 } while (InU8(0x71) & 0x80);169 170 OutU8(0x70,0x0B);171 if (InU8(0x71) & 4)172 is_bcd=FALSE;173 else174 is_bcd=TRUE;175 176 LBtr(&sys_semas[SEMA_SYS_DATE],0);177 POPFD178 if (is_bcd)179 for (i=2;i<9;i++)180 b[i]=Bcd2Bin(b[i]);181 182 if (_ds->year>255) _ds->year=255;183 _ds->year+=2000;184 if (_ds->mon>12) _ds->mon=12;185 if (_ds->day_of_mon>31) _ds->day_of_mon=31;186 if (_ds->day_of_week>6) _ds->day_of_week=6;187 if (_ds->hour>23) _ds->hour=23;188 if (_ds->min>59) _ds->min=59;189 if (_ds->sec>59) _ds->sec=59;190}191 192CDate Now()193{//Current datetime.194 CDateStruct ds;195 NowDateTimeStruct(&ds);196 return Struct2Date(&ds)-local_time_offset;197}198 