📄 postime.c
字号:
dt = SECONDS_IN_WEEK*(gwk-UTCRefWeek) + (gsec - ionoutc.tot);
gsec -= ionoutc.dtls + ionoutc.A0 + ionoutc.A1*dt;
if(gsec<0.0)
{
gsec += SECONDS_IN_WEEK;
gwk--;
}
else if(gsec>=SECONDS_IN_WEEK)
{
gsec -= 604800.0;
gwk++;
}
/* If we are within 6 hours of a scheduled leap second event, pick
up the number of leap seconds to be inserted or deleted at the
end of that day. */
TimeToLeapSecondEvent = SECONDS_IN_WEEK*(SchedLeapSecEventWeek-gwk)
+ ionoutc.dn*86400UL - gsec;
if(TimeToLeapSecondEvent>21600.0)
{
/* Scheduled leap second event is more than 6 hours in the
future. Adjust according to the leap second count prior to
the event. */
TodaysLeapSecs = 0;
PriorLeapSecs = ionoutc.dtls;
}
else if(TimeToLeapSecondEvent<-21600.0)
{
/* Scheduled leap second event is more than 6 hours in the past.
Adjust according to the leap second count subsequent to the
event. */
TodaysLeapSecs = 0;
PriorLeapSecs = ionoutc.dtlsf;
}
else
{
/* We are within 6 hours of the scheduled leap second event.
A dynamic adjustment will need to be made to accommodate the
transition period. */
TodaysLeapSecs = ionoutc.dtlsf - ionoutc.dtls;
PriorLeapSecs = ionoutc.dtls;
}
PROTECT--;
}
else
{
/* No UTC model, we know nothing about leap seconds. */
PriorLeapSecs = TodaysLeapSecs = 0;
}
/* Express UTC time as integer and fractional seconds since midnight
Jan 5/Jan 6, 1980. */
WholeUTCSecs = floor(gsec);
FractUTCSecs = gsec - WholeUTCSecs;
UTCSecNumber = 604800UL*gwk + WholeUTCSecs;
/* Express current GPS time as elapsed UTC days and seconds. */
UTCDayNumber = (UTCSecNumber-PriorLeapSecs) / 86400UL;
SecOfDay = UTCSecNumber - UTCDayNumber * 86400UL;
if(TodaysLeapSecs>0)
{
if(SecOfDay<TodaysLeapSecs)
{
/* Extend the designated UTC day by one or more leap seconds. */
UTCDayNumber--;
SecOfDay += 86400UL;
}
else if(SecOfDay<21600UL)
SecOfDay -= TodaysLeapSecs;
}
else if(TodaysLeapSecs<0)
{
/* Shorten the designated UTC day by one or more leap seconds. */
if(SecOfDay>=86400UL+TodaysLeapSecs)
{
UTCDayNumber++;
SecOfDay = SecOfDay % (86400UL+TodaysLeapSecs);
}
else if(SecOfDay<21600UL)
SecOfDay -= TodaysLeapSecs;
}
/* Determine the number of Gregorian leap days which have been
completed since midnight Jan 5/Jan 6, 1980:
1) Compute whole UTC days elapsed since midnight Feb 29/Mar 1,
1976 by adding 1406 to UTCDayNumber.
2) Divide by 1461. The integer quotient is the number of
completed leap days since midnight Jan 5/Jan 6, 1980. */
CompletedLeapDays = (int)((UTCDayNumber+1406) / 1461);
/* Determine the current UTC year:
1) Compute whole UTC days elapsed since midnight Dec 31, 1979/
Jan 1, 1980.
2) Subtract the cumulative completed UTC leap days. These extra
leap days have been used to make some of the past years, or
the current year, longer by one day.
3) The number of completed UTC years since midnight Dec 31, 1979/
Jan 1, 1980 is that difference divided by 365, the number of
days in a nominal UTC year. */
CompletedUTCYears = (int)((UTCDayNumber + 5 - CompletedLeapDays) / 365);
*y = 1980 + CompletedUTCYears;
/* Determine how many leap days have been completed in previous years
(not including the current year) */
PrevYearsLeapDays = (*y-1977) / 4;
/* Determine the day of the current UTC year:
1) From the whole UTC days since Jan1, 1980, subtract the following:
a) 365 days for each nominal UTC year elapsed in the past,
b) The cumulative number of leap days occuring in past years
(that is, do not subtract out any leap day which occurred
in the current year). */
DayOfUTCYear
= (int)(UTCDayNumber + 5 - 365*CompletedUTCYears - PrevYearsLeapDays);
/* Use the day of the UTC year to obtain the UTC date. */
if(*y%4)
{
/* Not a leap year. */
for(i=1;i<13;i++)
if(DayOfUTCYear<RegYearMonthTable[i])
break;
*m = i;
*d = DayOfUTCYear - RegYearMonthTable[*m-1] + 1;
}
else
{
/* A leap year. */
for(i=1; i<13; ++i)
if(DayOfUTCYear<LeapYearMonthTable[i])
break;
*m = i;
*d = DayOfUTCYear - LeapYearMonthTable[*m-1] + 1;
}
HourOfUTCDay = (int)(SecOfDay/3600);
if(HourOfUTCDay > 23)
HourOfUTCDay = 23;
MinuteOfUTCHour = (int)((SecOfDay - HourOfUTCDay*3600UL) / 60);
if(MinuteOfUTCHour > 59)
MinuteOfUTCHour = 59;
SecOfUTCMinute = SecOfDay - HourOfUTCDay*3600UL - MinuteOfUTCHour*60;
*hh = HourOfUTCDay;
*mm = MinuteOfUTCHour;
*ss = SecOfUTCMinute + FractUTCSecs;
}
/****************************************************************************
* Function: void UTCDateToGpsTime(int y, int m, int d, int hh, int mm,
* double ss, int *gwk, double *gsec)
*
* Converts from UTC date and time into GPS week number and seconds into week.
*
* Input: y - UTC year.
* m - UTC month.
* d - UTC day.
* hh - UTC hour.
* mm - UTC min.
* ss - UTC sec.
*
* Output: gwk - pointer to the GPS week number.
* gsec - pointer to the GPS seconds into the week.
*
* Return Value: None.
****************************************************************************/
void UTCDateToGpsTime(int y, int m, int d, int hh, int mm, double ss,
int *gwk, double *gsec)
{
int de;
int ye;
int lpdays;
int UTCRefWeek;
int SchedLeapSecEventWeek;
int PriorLeapSecs;
int TodaysLeapSecs;
unsigned long SecOfUTCDay;
double dt;
double TimeToLeapSecondEvent;
SecOfUTCDay = 3600UL*hh + 60*mm + floor(ss);
ye = y - 1980;
/* Compute # leap days since Jan 5/Jan 6, 1980. */
lpdays = ye/4 + 1;
if ((ye%4)==0 && m<=2)
lpdays--;
/* Compute # days elapsed since Jan 5/Jan 6, 1980. */
de = ye*365 + doy[m-1] + d + lpdays - 6;
/* Convert time to GPS weeks and seconds. */
*gwk = de / 7;
*gsec = (de%7)*SECONDS_IN_DAY + hh*SECONDS_IN_HOUR
+ mm*SECONDS_IN_MINUTE + ss;
/* Adjust GPS weeks/seconds to guarantee that seconds is in the
range 0-604800.0. */
while(*gsec<0.0)
{
*gwk -= 1;
*gsec += SECONDS_IN_WEEK;
}
while(*gsec>=SECONDS_IN_WEEK)
{
*gwk += 1;
*gsec -= SECONDS_IN_WEEK;
}
/* If a valid broadcast UTC model is available, do the following:
1) Pick up the cumulative prior leap seconds count.
2) Determine whether a leap second event is scheduled for the
end of the current day.
3) Use the UTC polynomial to convert from the UTC time base
to the GPS time base. */
if(ionoutc.vflg)
{
/* Convert from GPS time to UTC time, using the broadcast UTC model.
Notice that some of these calculations could feasibly be done at
the time the UTC model is stored, and the results could be stored
with the model. However, we are constrained to maintain
compatibility with earlier GPS Builder file formats, so that is
not done here. */
PROTECT++;
/* Unwrap the week parameters in the UTC model, assuming that the
difference between the untruncated week parameters and the current
GPS week does not exceed 127. */
UTCRefWeek = *gwk + (int)(ionoutc.wnt - (*gwk&0xFF));
if(*gwk-UTCRefWeek>127)
UTCRefWeek += 256;
else if(*gwk-UTCRefWeek<-127)
UTCRefWeek -= 256;
SchedLeapSecEventWeek = *gwk + (int)(ionoutc.wnlsf - (*gwk&0xFF));
if(*gwk-SchedLeapSecEventWeek>127)
SchedLeapSecEventWeek += 256;
else if(*gwk-SchedLeapSecEventWeek<-127)
SchedLeapSecEventWeek -= 256;
/* Change from UTC to GPS time reference. */
dt = SECONDS_IN_WEEK*(*gwk-UTCRefWeek) + (*gsec - ionoutc.tot);
*gsec += ionoutc.A0 + ionoutc.A1*dt + ionoutc.dtls;
if(*gsec>=SECONDS_IN_WEEK)
{
*gsec -= SECONDS_IN_WEEK;
*gwk += 1;
}
else if(*gsec<0.0)
{
*gsec += SECONDS_IN_WEEK;
*gwk -= 1;
}
/* If we are within 6 hours of a scheduled leap second event, pick
up the number of leap seconds to be inserted or deleted at the
end of that day. */
TimeToLeapSecondEvent = SECONDS_IN_WEEK*(SchedLeapSecEventWeek-*gwk)
+ ionoutc.dn*86400UL - *gsec;
if(TimeToLeapSecondEvent>21600.0)
{
/* Scheduled leap second event is more than 6 hours in the
future. Adjust according to the leap second count prior to
the event. */
TodaysLeapSecs = 0;
PriorLeapSecs = ionoutc.dtls;
}
else if(TimeToLeapSecondEvent<-21600)
{
/* Scheduled leap second event is more than 6 hours in the past.
Adjust according to the leap second count subsequent to the
event. */
TodaysLeapSecs = 0;
PriorLeapSecs = ionoutc.dtlsf;
}
else
{
/* We are within 6 hours of the scheduled leap second event.
A dynamic adjustment will need to be made to accommodate the
transition period. */
TodaysLeapSecs = ionoutc.dtlsf - ionoutc.dtls;
PriorLeapSecs = ionoutc.dtls;
}
PROTECT--;
}
else
{
/* No UTC model, we know nothing about leap seconds. */
PriorLeapSecs = TodaysLeapSecs = 0;
}
*gsec += PriorLeapSecs;
if(TodaysLeapSecs && (SecOfUTCDay<21600))
*gsec += TodaysLeapSecs;
if(*gsec>SECONDS_IN_WEEK)
{
*gsec -= SECONDS_IN_WEEK;
*gwk += 1;
}
else if(*gsec<0.0)
{
*gsec += SECONDS_IN_WEEK;
*gwk -= 1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -