libi2ncommon: (gerd) improve time output function
[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 void seconds_to_hour_minute(int seconds, int *hour, int *minute)
111 {
112     if (hour != NULL) {
113         *hour = 0;
114         while (seconds >= 3600) {
115             seconds-=3600;
116             (*hour)++;
117         }
118     }
119
120     if (minute != NULL) {
121         *minute = 0;
122         while (seconds >= 60) {
123             seconds-=60;
124             (*minute)++;
125         }
126     }
127 }
128
129 std::string output_hour_minute(int hour, int minute, bool h_for_00)
130 {
131     ostringstream out;
132     
133     if (hour >= 0 && hour < 10)
134         out << '0';
135     out << hour;
136     
137     if (!h_for_00 || minute != 0)
138     {
139         out << ':';
140         if (minute > 0 && minute < 10)
141             out << '0';
142         out << minute;
143     }
144     else
145         out << 'h';
146
147     return out.str();
148 }
149
150 WEEK::WEEK(const std::string& daystring)
151 {
152     int len=daystring.length();
153     for (int p=0; p < len; p++)
154     {
155         char nr=daystring[p];
156         istringstream c(&nr);
157         int wnr=-1;
158         if (!(c >> wnr) || wnr<0 || wnr >6)
159             throw out_of_range("illegal weekday in "+daystring);
160             
161         days.set(wnr);
162     }
163 }
164
165 std::string WEEK::get_daystring() const
166 {
167     ostringstream out;
168     for (int i = 0; i < 7; i++)
169         if (days[i])
170             out << i;
171
172     return out.str();
173 }
174
175 std::string WEEK::get_displaystring() const
176 {
177     string weekdays_str;
178
179     // From Monday to Saturday
180     int j;
181     for (int i = 1; i < 7; i++)
182     {
183         if (days[i])
184         {
185             if (!weekdays_str.empty())
186                 weekdays_str += ", ";
187
188             weekdays_str += get_day_display(static_cast<WEEKDAY>(i));
189
190             // check if we can group two or more days
191             j = i;
192             while (days[j] && j < 7)
193                 j++;
194             j--;
195
196             // Sunday end of week? j -> 7
197             if (j-i > 0 && j == 6 && days[0])
198                 j++;
199
200             if (j-i > 1) 
201             {
202                 if (j == 7)
203                     weekdays_str += "-" + get_day_display(SU);
204                 else
205                     weekdays_str += "-" + get_day_display(static_cast<WEEKDAY>(j));
206
207                 i = j;
208             }
209         }
210     }
211
212     // special: sunday
213     if (days[0] && j != 7) 
214     {
215         if (!weekdays_str.empty())
216             weekdays_str += ", ";
217
218         weekdays_str += get_day_display(SU);
219     }
220
221     return weekdays_str;
222 }
223
224 std::string WEEK::get_netfilterstring() const
225 {
226     string out;
227     for (int i = 0; i < 7; i++)
228         if (days[i])
229         {
230             if (!out.empty())
231                 out+=","; 
232             out+=get_english_display(static_cast<WEEKDAY>(i));;
233         }
234             
235     return out;
236 }
237
238 std::string WEEK::get_day_display(WEEKDAY day)
239 {
240     string weekday_str;
241
242     switch (day) {
243         case MO:
244             weekday_str = i18n("Mon");
245             break;
246         case TU:
247             weekday_str = i18n("Tue");
248             break;
249         case WE:
250             weekday_str = i18n("Wed");
251             break;
252         case TH:
253             weekday_str = i18n("Thu");
254             break;
255         case FR:
256             weekday_str = i18n("Fri");
257             break;
258         case SA:
259             weekday_str = i18n("Sat");
260             break;
261         case SU:
262             weekday_str = i18n("Sun");
263             break;
264         default:
265             break;
266     }
267
268     return weekday_str;
269 }
270
271 std::string WEEK::get_english_display(WEEKDAY day)
272 {
273     string weekday_str;
274
275     switch (day) {
276         case MO:
277             weekday_str = "Mon";
278             break;
279         case TU:
280             weekday_str = "Tue";
281             break;
282         case WE:
283             weekday_str = "Wed";
284             break;
285         case TH:
286             weekday_str = "Thu";
287             break;
288         case FR:
289             weekday_str = "Fri";
290             break;
291         case SA:
292             weekday_str = "Sat";
293             break;
294         case SU:
295             weekday_str = "Sun";
296             break;
297         default:
298             break;
299     }
300
301     return weekday_str;
302 }