source: trunk/lib/Date.cc @ 274

Last change on this file since 274 was 274, checked in by Peter Johansson, 14 years ago

support for Trac. Fixes #125. Also added a config file.

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