source: trunk/lib/Date.cc @ 396

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

fixed bug in time output, fixes #222

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.9 KB
Line 
1// $Id: Date.cc 396 2007-06-27 15:47:29Z 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
30#include <iostream>
31
32namespace theplu {
33namespace svndigest {
34
35  static const char* wdays_[7] = {
36    "Sunday","Monday", "Tuesday", "Wednesday", "Thursday", "Friday", 
37    "Saturday" 
38  };
39
40   
41  static const char* month_[12] = {
42    "January", "February", "March", "April", "May", "June", "July", "August", 
43    "September", "October", "November", "December"
44  }; 
45
46
47  Date::Date(void)
48  {
49    std::time(&time_);
50  }
51
52
53  Date::Date(const Date& other)
54    : time_(other.time_)
55  {
56  }
57
58
59  Date::Date(std::string str)
60  {
61    std::time(&time_);
62    svntime(str);
63  }
64
65
66  std::string Date::difftime(const Date& other) const
67  {
68    std::stringstream ss;
69    time_t t0 = std::min(seconds(), other.seconds());
70    time_t t1 = std::max(seconds(), other.seconds());
71    struct tm* last = std::gmtime(&t1);
72
73    u_int year=0;
74    while (t0<=t1) {
75      ++year;
76      --last->tm_year;
77      t1=mktime(last);
78    }
79    --year;
80    ++last->tm_year;
81    t1=mktime(last);
82    if (year) {
83      ss << year << " year";
84      if (year>1)
85        ss << "s";
86      ss << " ";
87    }
88
89    u_int month=0;
90    while (t0<=t1) {
91      ++month;
92      --last->tm_mon;
93      t1=mktime(last);
94    }
95    --month;
96    ++last->tm_mon;
97    t1=mktime(last);
98    if (month || year) {
99      ss << month << " month";
100      if (month>1 || (year && !month))
101        ss << "s";
102      ss << " and ";
103    }
104   
105
106    u_int day = (t1-t0)/24/60/60;
107    ss << day << " day";
108    if (day!=1)
109      ss << "s";
110    ss << " ";
111
112    return ss.str();
113  }
114
115
116  void Date::svntime(std::string str)
117  {
118    std::stringstream sstream(str);
119    struct tm* timeinfo = std::localtime(&time_);
120
121    u_int year, month, day, hour, minute, second;
122    std::string tmp;
123    std::getline(sstream,tmp,'-');
124    year=atoi(tmp.c_str());
125    timeinfo->tm_year = year - 1900;
126
127    std::getline(sstream,tmp,'-');
128    month=atoi(tmp.c_str());
129    timeinfo->tm_mon = month - 1;
130
131    std::getline(sstream,tmp,'T');
132    day=atoi(tmp.c_str());
133    timeinfo->tm_mday = day;
134
135    std::getline(sstream,tmp,':');
136    hour=atoi(tmp.c_str());
137    timeinfo->tm_hour = hour;
138
139    std::getline(sstream,tmp,':');
140    minute=atoi(tmp.c_str());
141    timeinfo->tm_min = minute;
142
143    std::getline(sstream,tmp,'.');
144    second=atoi(tmp.c_str());
145    timeinfo->tm_sec = second;
146
147    time_ = mktime(timeinfo);
148    time_ += timeinfo->tm_gmtoff;
149  }
150
151
152  std::string Date::operator()(std::string format) const
153  {
154    std::stringstream ss;
155    struct tm* timeinfo = std::gmtime(&time_);
156    for (std::string::iterator i=format.begin(); i!=format.end(); ++i) {
157      if (*i == '%' && ++i !=format.end()) {
158        if (*i == 'a')
159          ss << std::string(wdays_[timeinfo->tm_wday]).substr(0,3);
160        else if (*i == 'A')
161          ss << wdays_[timeinfo->tm_wday];
162        else if (*i == 'b')
163          ss << std::string(month_[timeinfo->tm_mon]).substr(0,3);
164        else if (*i == 'B')
165          ss << month_[timeinfo->tm_mon];
166        else if (*i == 'd')
167          ss << timeinfo->tm_mday;
168        else if (*i == 'e') {
169          if (timeinfo->tm_mday<10)
170            ss << "0";
171          ss << timeinfo->tm_mday;
172        }
173        else if (*i == 'H') {
174          if (timeinfo->tm_hour<10)
175            ss << "0";
176          ss << timeinfo->tm_hour;
177        }
178        else if (*i == 'I') {
179          int tmp = (timeinfo->tm_hour + 11) % 12 + 1;
180          if (tmp<10)
181            ss << "0";
182          ss << tmp;
183        }
184        else if (*i == 'j')
185          ss << timeinfo->tm_yday+1;
186        else if (*i == 'm') {
187          if (timeinfo->tm_mon<9)
188            ss << "0";
189          ss << timeinfo->tm_mon+1;
190        }
191        else if (*i == 'M') {
192          if (timeinfo->tm_min<10)
193            ss << "0";
194          ss << timeinfo->tm_min;
195        }
196        else if (*i == 'P')
197          if (timeinfo->tm_hour<12)
198            ss << "AM";
199          else
200            ss << "PM";
201        else if (*i == 'S') {
202          if (timeinfo->tm_sec<10)
203            ss << "0";
204          ss << timeinfo->tm_sec;
205        }
206        else if (*i == 'w')
207          if (timeinfo->tm_wday==0)
208            ss << "7";
209          else
210            ss << timeinfo->tm_wday;
211        else if (*i == 'y') {
212          int y(timeinfo->tm_year % 100);
213          if (y<10)
214            ss << "0";
215          ss << y;
216        }
217        else if (*i == 'Y')
218          ss << timeinfo->tm_year+1900;
219        else if (*i == 'Z')
220          ss << timeinfo->tm_zone;
221        else {
222          ss << '%';
223          --i;
224        }
225      }
226      else
227        ss << *i;
228    }
229
230    return ss.str();
231  }
232
233
234  const Date& Date::operator=(const Date& rhs) 
235  {
236    time_ = rhs.time_;
237    return *this;
238  }
239
240
241}}
Note: See TracBrowser for help on using the repository browser.