libi2ncommon: (gerd) add WEEK class to handle weekday-bitsets
[libi2ncommon] / src / timefunc.cpp
1 /***************************************************************************
2                           timecvt.cpp  -  description
3                              -------------------
4     begin                : Fri May 11 2001
5     copyright            : (C) 2001 by STYLETEC
6     email                : info@styletec.de
7  ***************************************************************************/
8
9 #include <string>
10 #include <sstream>
11 #include <iostream>
12 #include <iomanip>
13 #include <bitset>
14 #include <stdexcept>
15
16 #include <time.h>
17 #include <sys/timeb.h>
18
19 #include <timefunc.hxx>
20 #include <i18n.h>
21
22 using namespace std;
23
24 double prec_time(void)
25 {
26     struct timeb tb;
27     double ret;
28
29     ftime(&tb);
30
31     ret=tb.time+(static_cast<float>(tb.millitm)/1000);
32
33     return ret;
34 }
35
36 // converts ISO-DATE: 2003-06-13
37 int date_to_seconds(const std::string &date)
38 {
39     int rtn = -1, year = -1, month = -1, day = -1;
40     
41     string::size_type pos = date.find("-");
42     if (pos == string::npos)
43         return rtn;
44     
45     istringstream in(string(date,0,pos));
46     in >> year;
47     year -= 1900;
48         
49     string dstr(date, pos+1);
50     if ((pos = dstr.find("-")) == string::npos)
51         return rtn;
52     
53     in.clear();
54     in.str(string(dstr, 0, pos));
55     in >> month;
56     month -= 1;
57         
58     in.clear();
59     in.str(string(dstr, pos+1));
60     in >> day;
61     
62     if (year < 0 || month == -1 || day == -1)
63         return rtn;
64     
65     struct tm tm_struct;
66     bzero (&tm_struct, sizeof(struct tm));
67     tm_struct.tm_year = year;
68     tm_struct.tm_mon = month;
69     tm_struct.tm_mday = day;
70     tm_struct.tm_isdst = -1;
71     
72     rtn = mktime (&tm_struct);
73     return rtn;
74 }
75
76 string make_nice_time(int seconds)
77 {
78     ostringstream out;
79
80     int days=seconds/86400;
81     seconds%=86400;
82
83     int hours=seconds/3600;
84     seconds%=3600;
85
86     int minutes=seconds/60;
87     seconds%=60;
88
89     if (days==1)
90         out << i18n("1 day") << ", ";
91     else if (days>1)
92         out << days << ' ' << i18n("days") << ", ";
93
94     out << setfill('0');
95     out << setw(2) << hours << ':' << setw(2) << minutes << ':' << setw(2) << seconds;
96
97     return out.str();
98 }
99
100 string format_full_time(int seconds)
101 {
102     char buf[50];
103     memset (buf, 0, 50);
104     struct tm *ta = localtime ((time_t *)&seconds);
105
106     strftime (buf, 49, "%d.%m.%Y %H:%M", ta);
107     return string(buf);
108 }
109
110 WEEK::WEEK(const std::string& daystring)
111 {
112     int len=daystring.length();
113     for (int p=0; p < len; p++)
114     {
115         char nr=daystring[p];
116         istringstream c(&nr);
117         int wnr=-1;
118         if (!(c >> wnr) || wnr<0 || wnr >6)
119             throw out_of_range("illegal weekday in "+daystring);
120             
121         days.set(wnr);
122     }
123 }
124
125 std::string WEEK::get_daystring() const
126 {
127     ostringstream out;
128     for (int i = 0; i < 7; i++)
129         if (days[i])
130             out << i;
131
132     return out.str();
133 }
134
135 std::string WEEK::get_displaystring() const
136 {
137     string weekdays_str;
138
139     // From Monday to Saturday
140     int j;
141     for (int i = 1; i < 7; i++)
142     {
143         if (days[i])
144         {
145             if (!weekdays_str.empty())
146                 weekdays_str += ", ";
147
148             weekdays_str += get_day_display(static_cast<WEEKDAY>(i));
149
150             // check if we can group two or more days
151             j = i;
152             while (days[j] && j < 7)
153                 j++;
154             j--;
155
156             // Sunday end of week? j -> 7
157             if (j-i > 0 && j == 6 && days[0])
158                 j++;
159
160             if (j-i > 1) 
161             {
162                 if (j == 7)
163                     weekdays_str += "-" + get_day_display(SU);
164                 else
165                     weekdays_str += "-" + get_day_display(static_cast<WEEKDAY>(j));
166
167                 i = j;
168             }
169         }
170     }
171
172     // special: sunday
173     if (days[0] && j != 7) 
174     {
175         if (!weekdays_str.empty())
176             weekdays_str += ", ";
177
178         weekdays_str += get_day_display(SU);
179     }
180
181     return weekdays_str;
182 }
183
184 std::string WEEK::get_netfilterstring() const
185 {
186     string out;
187     for (int i = 0; i < 7; i++)
188         if (days[i])
189         {
190             if (!out.empty())
191                 out+=","; 
192             out+=get_english_display(static_cast<WEEKDAY>(i));;
193         }
194             
195     return out;
196 }
197
198 std::string WEEK::get_day_display(WEEKDAY day)
199 {
200     string weekday_str;
201
202     switch (day) {
203         case MO:
204             weekday_str = i18n("Mon");
205             break;
206         case TU:
207             weekday_str = i18n("Tue");
208             break;
209         case WE:
210             weekday_str = i18n("Wed");
211             break;
212         case TH:
213             weekday_str = i18n("Thu");
214             break;
215         case FR:
216             weekday_str = i18n("Fri");
217             break;
218         case SA:
219             weekday_str = i18n("Sat");
220             break;
221         case SU:
222             weekday_str = i18n("Sun");
223             break;
224         default:
225             break;
226     }
227
228     return weekday_str;
229 }
230
231 std::string WEEK::get_english_display(WEEKDAY day)
232 {
233     string weekday_str;
234
235     switch (day) {
236         case MO:
237             weekday_str = "Mon";
238             break;
239         case TU:
240             weekday_str = "Tue";
241             break;
242         case WE:
243             weekday_str = "Wed";
244             break;
245         case TH:
246             weekday_str = "Thu";
247             break;
248         case FR:
249             weekday_str = "Fri";
250             break;
251         case SA:
252             weekday_str = "Sat";
253             break;
254         case SU:
255             weekday_str = "Sun";
256             break;
257         default:
258             break;
259     }
260
261     return weekday_str;
262 }