source: trunk/lib/Date.cc @ 235

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

added Date class
changed date format on first page
fixed plotting only once (fixes #113)
changed interface to anchor class
more anchors to users
removed anchor to '../' in author summary in dirs
anchors are filtered through HtmlStream?
log messages are truncated and newlines are replaced with spaces

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.9 KB
Line 
1// $Id: Date.cc 235 2007-04-21 13:39:50Z 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          ss << timeinfo->tm_year % 100;
212        else if (*i == 'Y')
213          ss << timeinfo->tm_year+1900;
214        else if (*i == 'Z')
215          ss << timeinfo->tm_zone;
216        else {
217          ss << '%';
218          --i;
219        }
220      }
221      else
222        ss << *i;
223    }
224
225    return ss.str();
226  }
227
228
229  const Date& Date::operator=(const Date& rhs) 
230  {
231    time_ = rhs.time_;
232    return *this;
233  }
234
235
236}}
Note: See TracBrowser for help on using the repository browser.