source: trunk/lib/Date.cc @ 745

Last change on this file since 745 was 693, checked in by Jari Häkkinen, 13 years ago

Fixes #339. Change to GPLv3.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.9 KB
Line 
1// $Id: Date.cc 693 2008-09-11 20:42:56Z jari $
2
3/*
4  Copyright (C) 2007 Peter Johansson
5  Copyright (C) 2008 Jari Häkkinen
6
7  This file is part of svndigest, http://dev.thep.lu.se/svndigest
8
9  svndigest is free software; you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 3 of the License, or
12  (at your option) any later version.
13
14  svndigest is distributed in the hope that it will be useful, but
15  WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  General Public License for more details.
18
19  You should have received a copy of the GNU General Public License
20  along with svndigest. If not, see <http://www.gnu.org/licenses/>.
21*/
22
23#include "Date.h"
24
25#include <algorithm>
26#include <sstream>
27#include <string>
28
29namespace theplu {
30namespace svndigest {
31
32  static const char* wdays_[7] = {
33    "Sunday","Monday", "Tuesday", "Wednesday", "Thursday", "Friday", 
34    "Saturday" 
35  };
36
37   
38  static const char* month_[12] = {
39    "January", "February", "March", "April", "May", "June", "July", "August", 
40    "September", "October", "November", "December"
41  }; 
42
43
44  Date::Date(void)
45  {
46    std::time(&time_);
47  }
48
49
50  Date::Date(const Date& other)
51    : time_(other.time_)
52  {
53  }
54
55
56  Date::Date(std::string str)
57  {
58    std::time(&time_);
59    svntime(str);
60  }
61
62
63  std::string Date::difftime(const Date& other) const
64  {
65    std::stringstream ss;
66    time_t t0 = std::min(seconds(), other.seconds());
67    time_t t1 = std::max(seconds(), other.seconds());
68    struct tm* last = std::gmtime(&t1);
69
70    unsigned int year=0;
71    while (t0<=t1) {
72      ++year;
73      --last->tm_year;
74      t1=mktime(last);
75    }
76    --year;
77    ++last->tm_year;
78    t1=mktime(last);
79    if (year) {
80      ss << year << " year";
81      if (year>1)
82        ss << "s";
83      ss << " ";
84    }
85
86    unsigned int month=0;
87    while (t0<=t1) {
88      ++month;
89      --last->tm_mon;
90      t1=mktime(last);
91    }
92    --month;
93    ++last->tm_mon;
94    t1=mktime(last);
95    if (month || year) {
96      ss << month << " month";
97      if (month>1 || (year && !month))
98        ss << "s";
99      ss << " and ";
100    }
101   
102
103    unsigned int day = (t1-t0)/24/60/60;
104    ss << day << " day";
105    if (day!=1)
106      ss << "s";
107    ss << " ";
108
109    return ss.str();
110  }
111
112
113  void Date::svntime(std::string str)
114  {
115    std::stringstream sstream(str);
116    struct tm* timeinfo = std::localtime(&time_);
117    time_t timezone_correction = timeinfo->tm_gmtoff;
118
119    unsigned int year, month, day, hour, minute, second;
120    std::string tmp;
121    std::getline(sstream,tmp,'-');
122    year=atoi(tmp.c_str());
123    timeinfo->tm_year = year - 1900;
124
125    std::getline(sstream,tmp,'-');
126    month=atoi(tmp.c_str());
127    timeinfo->tm_mon = month - 1;
128
129    std::getline(sstream,tmp,'T');
130    day=atoi(tmp.c_str());
131    timeinfo->tm_mday = day;
132
133    std::getline(sstream,tmp,':');
134    hour=atoi(tmp.c_str());
135    timeinfo->tm_hour = hour;
136
137    std::getline(sstream,tmp,':');
138    minute=atoi(tmp.c_str());
139    timeinfo->tm_min = minute;
140
141    std::getline(sstream,tmp,'.');
142    second=atoi(tmp.c_str());
143    timeinfo->tm_sec = second;
144
145    time_ = mktime(timeinfo);
146    time_ += timezone_correction;
147  }
148
149
150  std::string Date::operator()(std::string format) const
151  {
152    std::stringstream ss;
153    struct tm* timeinfo = std::gmtime(&time_);
154    for (std::string::iterator i=format.begin(); i!=format.end(); ++i) {
155      if (*i == '%' && ++i !=format.end()) {
156        if (*i == 'a')
157          ss << std::string(wdays_[timeinfo->tm_wday]).substr(0,3);
158        else if (*i == 'A')
159          ss << wdays_[timeinfo->tm_wday];
160        else if (*i == 'b')
161          ss << std::string(month_[timeinfo->tm_mon]).substr(0,3);
162        else if (*i == 'B')
163          ss << month_[timeinfo->tm_mon];
164        else if (*i == 'd')
165          ss << timeinfo->tm_mday;
166        else if (*i == 'e') {
167          if (timeinfo->tm_mday<10)
168            ss << "0";
169          ss << timeinfo->tm_mday;
170        }
171        else if (*i == 'H') {
172          if (timeinfo->tm_hour<10)
173            ss << "0";
174          ss << timeinfo->tm_hour;
175        }
176        else if (*i == 'I') {
177          int tmp = (timeinfo->tm_hour + 11) % 12 + 1;
178          if (tmp<10)
179            ss << "0";
180          ss << tmp;
181        }
182        else if (*i == 'j')
183          ss << timeinfo->tm_yday+1;
184        else if (*i == 'm') {
185          if (timeinfo->tm_mon<9)
186            ss << "0";
187          ss << timeinfo->tm_mon+1;
188        }
189        else if (*i == 'M') {
190          if (timeinfo->tm_min<10)
191            ss << "0";
192          ss << timeinfo->tm_min;
193        }
194        else if (*i == 'P')
195          if (timeinfo->tm_hour<12)
196            ss << "AM";
197          else
198            ss << "PM";
199        else if (*i == 'S') {
200          if (timeinfo->tm_sec<10)
201            ss << "0";
202          ss << timeinfo->tm_sec;
203        }
204        else if (*i == 'w')
205          if (timeinfo->tm_wday==0)
206            ss << "7";
207          else
208            ss << timeinfo->tm_wday;
209        else if (*i == 'y') {
210          int y(timeinfo->tm_year % 100);
211          if (y<10)
212            ss << "0";
213          ss << y;
214        }
215        else if (*i == 'Y')
216          ss << timeinfo->tm_year+1900;
217        else if (*i == 'Z')
218          ss << timeinfo->tm_zone;
219        else {
220          ss << '%';
221          --i;
222        }
223      }
224      else
225        ss << *i;
226    }
227
228    return ss.str();
229  }
230
231
232  const Date& Date::operator=(const Date& rhs) 
233  {
234    time_ = rhs.time_;
235    return *this;
236  }
237
238
239}}
Note: See TracBrowser for help on using the repository browser.