TZ-Lib  $VERSION$
tzhelp.h
Go to the documentation of this file.
1 //
2 // C++ Interface: TZ Data Helper functions
3 //
4 // Description: some calculator inlines
5 //
6 //
7 // Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2010
8 //
9 // Copyright: See README/COPYING files that come with this distribution
10 //
11 //
12 
13 #ifndef TIMEZONE_INLINE_HELPERS_H
14 #define TIMEZONE_INLINE_HELPERS_H
15 
16 #include <QtGlobal>
17 #include <QByteArray>
18 
19 namespace TimeZoneLib {
20 
22 static const qint64 SecondsPerDay=86400;
23 
27 inline qint64 decodeInt(const QByteArray&a,int s=4)
28 {
29  if(a.size()<s)return 0;
30  qint64 r=0;
31  if(((signed char)a[0])<0)r=-1;
32  for(int i=0;i<s;i++){
33  r<<=8;
34  r|=(unsigned char)a[i];
35  }
36  return r;
37 }
38 
40 inline qint64 decodeInt64(const QByteArray&a){return decodeInt(a,8);}
41 
43 inline bool isLeapYear(int year)
44 {
45  if((year%400)==0)return true;//every 400th is leapy
46  if((year%100)==0)return false;//every 100th is not
47  if((year%4)==0)return true;//every fourth is leapy
48  return false;//all others are not leapy
49 }
50 
56 inline qint64 daysSinceEpoch(int year,int month=1,int day=1)
57 {
58  qint64 ret=0;
59  //calculate jan 1st
60  if(year>=1970){
61  for(int y=1970;y<year;y++)
62  if(isLeapYear(y))ret+=366;
63  else ret+=365;
64  }else{
65  for(int y=1969;y>=year;y--)
66  if(isLeapYear(y))ret-=366;
67  else ret-=365;
68  }
69  //calculate 1st of month
70  // for each month: add the days of the previous one, and the previous, ...
71  switch(month){
72  case 12:ret+=30;//nov
73  case 11:ret+=31;//oct
74  case 10:ret+=30;//sep
75  case 9:ret+=31;//aug
76  case 8:ret+=31;//jul
77  case 7:ret+=30;//jun
78  case 6:ret+=31;//may
79  case 5:ret+=30;//apr
80  case 4:ret+=31;//mar
81  case 3:ret+=28;if(isLeapYear(year))ret++;//feb
82  case 2:ret+=31;//jan
83  default:break;
84  }
85  //add day
86  ret+=day-1;
87 
88  return ret;
89 }
90 
92 inline int pmod(qint64 num,int mod)
93 {
94  num%=mod;
95  while(num<0)num+=mod;
96  return num;
97 }
98 
100 inline qint64 fdiv(qint64 num,qint64 div)
101 {
102  if(div<0){
103  div*=-1;num*=-1;
104  }
105  if(num>0)return num/div;
106  qint64 m=num%div;
107  num/=div;if(m)num--;
108  return num;
109 }
110 
116 inline int weekDayOf(int year,int month=1,int day=1)
117 {
118  return pmod(daysSinceEpoch(year,month,day)+4,7);
119 }
120 
123 inline int weekDaySinceEpoch(qint64 daySinceEpoch)
124 {
125  return pmod(daySinceEpoch+4,7);
126 }
127 
130 inline qint64 firstWeekDayOf(int year,int month,int wday)
131 {
132  wday=pmod(wday,7);
133  qint64 day=daysSinceEpoch(year,month);
134  do{
135  if(weekDaySinceEpoch(day)==wday)return day;
136  day++;
137  }while(true);
138 }
139 
142 inline qint64 lastWeekDayOf(int year,int month,int wday)
143 {
144  wday=pmod(wday,7);
145  if(month>=12){
146  month=1;
147  year++;
148  }else month++;
149  qint64 day=daysSinceEpoch(year,month);day--;
150  do{
151  if(weekDaySinceEpoch(day)==wday)return day;
152  day--;
153  }while(true);
154 }
155 
157 inline void stamp2Time(qint64 stamp,quint8&h,quint8&m,quint8&s)
158 {
159  stamp=pmod(stamp,SecondsPerDay);
160  s=stamp%60;
161  m=(stamp/60)%60;
162  h=stamp/3600;
163 }
164 
166 inline void offset2Date(qint64 off,qint16&y,quint8&m,quint8&d)
167 {
168  //try to find the year
169  y=1970;
170  if(off>0){
171  while(off>366){
172  off-=365;
173  if(isLeapYear(y))off--;
174  y++;
175  }
176  }else{
177  while(off<0){
178  off+=365;
179  y--;
180  if(isLeapYear(y))off++;
181  }
182  }
183  //find month
184  if(off<31){m=1;d=off+1;return;}else off-=31;
185  if(off<28){m=2;d=off+1;return;}else off-=28;
186  if(isLeapYear(y)){
187  if(off)off--;
188  else{m=2;d=29;return;}
189  }
190  if(off<31){m=3;d=off+1;return;}else off-=31;
191  if(off<30){m=4;d=off+1;return;}else off-=30;
192  if(off<31){m=5;d=off+1;return;}else off-=31;
193  if(off<30){m=6;d=off+1;return;}else off-=30;
194  if(off<31){m=7;d=off+1;return;}else off-=31;
195  if(off<31){m=8;d=off+1;return;}else off-=31;
196  if(off<30){m=9;d=off+1;return;}else off-=30;
197  if(off<31){m=10;d=off+1;return;}else off-=31;
198  if(off<30){m=11;d=off+1;return;}else off-=30;
199  if(off<31){m=12;d=off+1;return;}else off-=31;
200  //something left over, move to next year
201  y++;m=1;d=off+1;
202 }
203 
205 inline void stamp2Date(qint64 off,qint16&y,quint8&m,quint8&d)
206 {
207  qint64 de=fdiv(off,SecondsPerDay);
208  offset2Date(de,y,m,d);
209 }
210 
215 inline qint64 dateTime2stamp(qint64 days,quint8 h,quint8 m,quint8 s)
216 {
217  qint64 r=days*SecondsPerDay;
218  r+=h*3600 + m*60 + s;
219  return r;
220 }
221 
228 inline qint64 dateTime2stamp(int y,quint8 mon,quint8 day,quint8 hr,quint8 min,quint8 s)
229 {
230  return dateTime2stamp(daysSinceEpoch(y,mon,day),hr,min,s);
231 }
232 
233 //end of namespace
234 }
235 
236 #endif
Definition: tzdata.h:29
int pmod(qint64 num, int mod)
Definition: tzhelp.h:92
bool isLeapYear(int year)
Definition: tzhelp.h:43
qint64 daysSinceEpoch(int year, int month=1, int day=1)
Definition: tzhelp.h:56
qint64 fdiv(qint64 num, qint64 div)
Definition: tzhelp.h:100
qint64 firstWeekDayOf(int year, int month, int wday)
Definition: tzhelp.h:130
static const qint64 SecondsPerDay
Definition: tzhelp.h:22
int weekDaySinceEpoch(qint64 daySinceEpoch)
Definition: tzhelp.h:123
void offset2Date(qint64 off, qint16 &y, quint8 &m, quint8 &d)
Definition: tzhelp.h:166
void stamp2Date(qint64 off, qint16 &y, quint8 &m, quint8 &d)
Definition: tzhelp.h:205
qint64 dateTime2stamp(qint64 days, quint8 h, quint8 m, quint8 s)
Definition: tzhelp.h:215
qint64 lastWeekDayOf(int year, int month, int wday)
Definition: tzhelp.h:142
qint64 decodeInt(const QByteArray &a, int s=4)
Definition: tzhelp.h:27
qint64 decodeInt64(const QByteArray &a)
Definition: tzhelp.h:40
int weekDayOf(int year, int month=1, int day=1)
Definition: tzhelp.h:116
void stamp2Time(qint64 stamp, quint8 &h, quint8 &m, quint8 &s)
Definition: tzhelp.h:157