File: timeutil.h

package info (click to toggle)
tinymux 2.10.1.14-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 6,212 kB
  • ctags: 8,535
  • sloc: cpp: 111,587; sh: 5,867; ansic: 141; makefile: 139
file content (223 lines) | stat: -rw-r--r-- 8,385 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/*! \file timeutil.h
 * \brief CLinearTimeAbsolute and CLinearTimeDelta modules.
 *
 * $Id: timeutil.h 3868 2008-09-10 14:43:47Z brazilofmux $
 *
 * Date/Time code based on algorithms presented in "Calendrical Calculations",
 * Cambridge Press, 1998.
 */

#ifndef TIMEUTIL_H
#define TIMEUTIL_H

typedef struct
{
             short iYear;       // 1900 would be stored as 1900.
    unsigned short iMonth;      // January is 1. December is 12.
    unsigned short iDayOfWeek;  // 0 is Sunday, 1 is Monday, etc.
    unsigned short iDayOfMonth; // Day of Month, 1..31
    unsigned short iDayOfYear;  // January 1st is 1, etc.
    unsigned short iHour;
    unsigned short iMinute;
    unsigned short iSecond;
    unsigned short iMillisecond; // Milliseconds less than a second.
    unsigned short iMicrosecond; // Microseconds less than a Millisecond.
    unsigned short iNanosecond;  // Nanoseconds less than a Microsecond.
} FIELDEDTIME;

class CLinearTimeDelta;

class CLinearTimeAbsolute
{
    friend class CLinearTimeDelta;
    friend bool operator<(const CLinearTimeAbsolute& lta, const CLinearTimeAbsolute& ltb);
    friend bool operator>(const CLinearTimeAbsolute& lta, const CLinearTimeAbsolute& ltb);
    friend bool operator==(const CLinearTimeAbsolute& lta, const CLinearTimeAbsolute& ltb);
    friend bool operator<=(const CLinearTimeAbsolute& lta, const CLinearTimeAbsolute& ltb);
    friend CLinearTimeAbsolute operator+(const CLinearTimeAbsolute& lta, const CLinearTimeDelta& ltd);
    friend CLinearTimeAbsolute operator-(const CLinearTimeAbsolute& lta, const CLinearTimeDelta& ltd);
    friend CLinearTimeDelta operator-(const CLinearTimeAbsolute& lta, const CLinearTimeAbsolute& ltb);

private:
    INT64  m_tAbsolute;
    static int m_nCount;
    static UTF8 m_Buffer[I64BUF_SIZE*2];

public:
    //CLinearTimeAbsolute(int tInitial);
    CLinearTimeAbsolute(void);
    CLinearTimeAbsolute(const CLinearTimeAbsolute& ltaOrigin, const CLinearTimeDelta& ltdOffset);
    CLinearTimeAbsolute(const CLinearTimeAbsolute& lta);
    void operator=(const CLinearTimeAbsolute& lta);
    void operator+=(const CLinearTimeDelta& ltdOffset);
    void operator-=(const CLinearTimeDelta& ltdOffset);

    void GetUTC(void);
    void GetLocal(void);

    void  ReturnUniqueString(UTF8 *buffer, size_t nBuffer);
    UTF8 *ReturnDateString(int nFracDigits = 0);
    bool  ReturnFields(FIELDEDTIME *arg_tStruct);
    INT64 ReturnSeconds(void);
    UTF8 *ReturnSecondsString(int nFracDigits = 0);
    INT64 Return100ns(void);

    void SetSeconds(INT64 arg_tSeconds);
    bool SetSecondsString(UTF8 *arg_szSeconds);
    bool SetFields(FIELDEDTIME *arg_tStruct);
    bool SetString(const UTF8 *arg_tBuffer);
    void Set100ns(INT64 arg_t100ns);

    void UTC2Local(void);
    void Local2UTC(void);
};

bool FieldedTimeToLinearTime(FIELDEDTIME *ft, INT64 *plt);
bool LinearTimeToFieldedTime(INT64 lt, FIELDEDTIME *ft);

class CLinearTimeDelta
{
    friend class CLinearTimeAbsolute;
    friend bool operator<(const CLinearTimeDelta& lta, const CLinearTimeDelta& ltb);
    friend bool operator>(const CLinearTimeDelta& lta, const CLinearTimeDelta& ltb);
    friend bool operator==(const CLinearTimeDelta& lta, const CLinearTimeDelta& ltb);
    friend bool operator<=(const CLinearTimeDelta& lta, const CLinearTimeDelta& ltb);
    friend bool operator!=(const CLinearTimeDelta& lta, const CLinearTimeDelta& ltb);
    friend CLinearTimeDelta operator-(const CLinearTimeAbsolute& lta, const CLinearTimeAbsolute& ltb);
    friend CLinearTimeDelta operator-(const CLinearTimeDelta& lta, const CLinearTimeDelta& ltb);
    friend int operator/(const CLinearTimeDelta& ltdA, const CLinearTimeDelta& ltdB);
    friend CLinearTimeDelta operator*(const CLinearTimeDelta& ltdA, int nScaler);
    friend CLinearTimeAbsolute operator+(const CLinearTimeAbsolute& ltdA, const CLinearTimeDelta& ltdB);
    friend CLinearTimeAbsolute operator-(const CLinearTimeAbsolute& lta, const CLinearTimeDelta& ltd);

private:
    INT64 m_tDelta;
    static UTF8 m_Buffer[I64BUF_SIZE*2];

public:
    CLinearTimeDelta(void);
    CLinearTimeDelta(INT64 arg_t100ns);
    CLinearTimeDelta(CLinearTimeAbsolute, CLinearTimeAbsolute);

    void ReturnTimeValueStruct(struct timeval *tv);
#ifdef HAVE_NANOSLEEP
    void ReturnTimeSpecStruct(struct timespec *ts);
#endif
    long ReturnMilliseconds(void);
    INT64 ReturnMicroseconds(void);
    long ReturnDays(void);
    long ReturnSeconds(void);
    UTF8 *ReturnSecondsString(int nFracDigits = 0);
    INT64 Return100ns(void);

    void SetTimeValueStruct(struct timeval *tv);
    void SetMilliseconds(unsigned long arg_dwMilliseconds);
    void SetSeconds(INT64 arg_tSeconds);
    void SetSecondsString(UTF8 *arg_szSeconds);
    void Set100ns(INT64 arg_t100ns);

    void operator+=(const CLinearTimeDelta& ltd);
};

class CMuxAlarm
{
private:
    bool bAlarmSet;
#if defined(WINDOWS_THREADS)
    HANDLE hThread;
static DWORD WINAPI AlarmProc(LPVOID lpParameter);
#endif // WINDOWS_THREADS

public:
    bool bAlarmed;

#if defined(WINDOWS_THREADS)
    volatile HANDLE hSemAlarm;
    volatile DWORD  dwWait;
    ~CMuxAlarm();
#endif // WINDOWS_THREADS

    CMuxAlarm(void);
    void Sleep(CLinearTimeDelta ltd);
    void SurrenderSlice(void);

    void Set(CLinearTimeDelta ltdDeadline);
    void Clear(void);

#if defined(UNIX_SIGNALS)
    void Signal(void);
#endif // UNIX_SIGNALS
};

extern CMuxAlarm MuxAlarm;

#define FACTOR_NANOSECONDS_PER_100NS 100
#define FACTOR_100NS_PER_MICROSECOND 10
#define FACTOR_100NS_PER_MILLISECOND 10000
#define EPOCH_OFFSET              INT64_C(116444736000000000)
#define EARLIEST_VALID_DATE       INT64_C(-9106391088000000000)
#define LATEST_VALID_DATE         INT64_C(9222834959999999999)
#define TIMEUTIL_TIME_T_MIN_VALUE INT64_C(-922283539200)
#define TIMEUTIL_TIME_T_MAX_VALUE INT64_C(910638979199)
extern const INT64 FACTOR_MS_PER_SECOND;
extern const INT64 FACTOR_US_PER_SECOND;
extern const INT64 FACTOR_100NS_PER_SECOND;
extern const INT64 FACTOR_100NS_PER_MINUTE;
extern const INT64 FACTOR_100NS_PER_HOUR;
extern const INT64 FACTOR_100NS_PER_DAY;
extern const INT64 FACTOR_100NS_PER_WEEK;

const CLinearTimeDelta time_200us = 200*FACTOR_100NS_PER_MICROSECOND;
const CLinearTimeDelta time_5ms   = 5*FACTOR_100NS_PER_MILLISECOND;
const CLinearTimeDelta time_250ms = 250*FACTOR_100NS_PER_MILLISECOND;
const CLinearTimeDelta time_1s    = FACTOR_100NS_PER_SECOND;
const CLinearTimeDelta time_5s    = 5*FACTOR_100NS_PER_SECOND;
const CLinearTimeDelta time_15s   = 15*FACTOR_100NS_PER_SECOND;
const CLinearTimeDelta time_30s   = 30*FACTOR_100NS_PER_SECOND;
const CLinearTimeDelta time_45s   = 45*FACTOR_100NS_PER_SECOND;
const CLinearTimeDelta time_15m   = 15*FACTOR_100NS_PER_MINUTE;
const CLinearTimeDelta time_30m   = 30*FACTOR_100NS_PER_MINUTE;
const CLinearTimeDelta time_1w    = FACTOR_100NS_PER_WEEK;

void TIME_Initialize(void);

#ifdef SMALLEST_INT_GTE_NEG_QUOTIENT
INT64 i64Mod(INT64 x, INT64 y);
INT64 i64FloorDivision(INT64 x, INT64 y);
inline INT64 i64Division(INT64 x, INT64 y) { return x / y; }
inline INT64 i64Remainder(INT64 x, INT64 y) { return x % y; }
int iFloorDivisionMod(int x, int y, int *piMod);
#else // SMALLEST_INT_GTE_NEG_QUOTIENT
inline INT64 i64Mod(INT64 x, INT64 y) { return x % y; }
inline INT64 i64FloorDivision(INT64 x, INT64 y) { return x / y; }
INT64 i64Division(INT64 x, INT64 y);
INT64 i64Remainder(INT64 x, INT64 y);
inline int iFloorDivisionMod(int x, int y, int *piMod) \
{                   \
    *piMod = x % y; \
    return x / y;   \
}
#endif // SMALLEST_INT_GTE_NEG_QUOTIENT

int iMod(int x, int y);
int iFloorDivision(int x, int y);
INT64 i64FloorDivisionMod(INT64 x, INT64 y, INT64 *piMod);
bool ParseDate(CLinearTimeAbsolute &lta, UTF8 *pDateString, bool *pbZoneSpecified);
void ParseDecimalSeconds(size_t n, const UTF8 *p, unsigned short *iMilli,
                         unsigned short *iMicro, unsigned short *iNano);
bool isLeapYear(long iYear);
void ConvertToSecondsString(UTF8 *buffer, INT64 n64, int nFracDigits);
bool ParseFractionalSecondsString(INT64 &i64, UTF8 *str);
void GetUTCLinearTime(INT64 *plt);
bool do_convtime(const UTF8 *str, FIELDEDTIME *ft);
CLinearTimeDelta QueryLocalOffsetAtUTC
(
    const CLinearTimeAbsolute &lta,
    bool *pisDST
);

extern const UTF8 *monthtab[12];
extern const char daystab[12];
extern const UTF8 *DayOfWeekString[7];

#endif // TIMEUTIL_H