fork download
  1. #include <cstdlib>
  2. #include <ctime>
  3. #include <stdexcept>
  4. #include <algorithm>
  5. #include <iterator>
  6. #include <iostream>
  7. #include <iomanip>
  8. #include <sstream>
  9. #include <string>
  10. #include <chrono>
  11. #include <vector>
  12. #include <system_error>
  13.  
  14. using namespace std;
  15. using namespace std::chrono;
  16.  
  17. namespace utils {
  18. //文字列を指定したデリミタで分割する
  19. inline vector<string> split(const string& s, char delim) {
  20. vector<string> r;
  21. istringstream istr(s);
  22. for(string p; istr && getline(istr, p, delim); r.push_back(p));
  23. return r;
  24. }
  25. //文字列を整数に変換する
  26. inline int to_int(const string& s) {
  27. auto r = atoi(s.c_str());
  28. return (errno == 0) ? r : throw system_error();
  29. }
  30. //不完全なtime_tを返す
  31. inline time_t to_time_t(int year, int month, int day, int hour, int minute, int second) {
  32. tm tm;
  33. tm.tm_year = year - 1900;
  34. tm.tm_mon = month - 1;
  35. tm.tm_mday = day;
  36. tm.tm_hour = hour;
  37. tm.tm_min = minute;
  38. tm.tm_sec = second;
  39. return mktime(&tm);
  40. }
  41. //tmを正規化する
  42. inline tm normalize(tm* tm) {
  43. auto tt = mktime(tm);
  44. return *localtime(&tt);
  45. }
  46. //tmを正規化する
  47. inline tm normalize(tm& tm) {
  48. return normalize(&tm);
  49. }
  50. }
  51.  
  52. //日時エラー
  53. class DateTimeError : public range_error {
  54. public:
  55. //エラーメッセージを指定して初期化する
  56. DateTimeError(const string& msg) : range_error(msg) {}
  57. };
  58.  
  59. //日時クラスにオペレータを実装するテンプレートクラス
  60. template<class T> class DateTimeOperators {
  61. public:
  62. bool operator<(const T& other) const { return static_cast<const T*>(this)->to_time_t() < other.to_time_t(); }
  63. bool operator>(const T& other) const { return static_cast<const T*>(this)->to_time_t() > other.to_time_t(); }
  64. bool operator<=(const T& other) const { return static_cast<const T*>(this)->to_time_t() <= other.to_time_t(); }
  65. bool operator>=(const T& other) const { return static_cast<const T*>(this)->to_time_t() >= other.to_time_t(); }
  66. bool operator==(const T& other) const { return static_cast<const T*>(this)->to_time_t() == other.to_time_t(); }
  67. bool operator!=(const T& other) const { return static_cast<const T*>(this)->to_time_t() != other.to_time_t(); }
  68. };
  69.  
  70. //年月日を表すクラス
  71. class Date : public DateTimeOperators<Date> {
  72. int m_year;
  73. int m_month;
  74. int m_day;
  75. public:
  76. //1900/01/01で初期化する
  77. Date() : Date(1900, 1, 1) {}
  78. //struct tmから初期化する
  79. Date(const tm* tm) : Date(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday) {}
  80. //年月日を指定して初期化する
  81. Date(int year, int month, int day) {
  82. set_year(year);
  83. set_month(month);
  84. set_day(day);
  85. }
  86. //年を返す
  87. int get_year() const { return m_year; }
  88. //月を返す
  89. int get_month() const { return m_month; }
  90. //日を返す
  91. int get_day() const { return m_day; }
  92. //年を設定する
  93. void set_year(int year) {
  94. if(year < 1900) throw DateTimeError("1900 <= year");
  95. m_year = year;
  96. }
  97. //月を設定する
  98. void set_month(int month) {
  99. if(month <= 0 || 12 < month) throw DateTimeError("0 < month <= 12");
  100. m_month = month;
  101. }
  102. //日を設定する
  103. void set_day(int day) {
  104. if(day <= 0 || 31 < day) throw DateTimeError("0 < day <= 31");
  105. m_day = day;
  106. }
  107. //この年月日をtime_tで返す
  108. time_t to_time_t() const { return utils::to_time_t(m_year, m_month, m_day, 0, 0, 0); }
  109. };
  110.  
  111. //時分秒を表すクラス
  112. class Time : public DateTimeOperators<Time> {
  113. int m_hour;
  114. int m_minute;
  115. int m_second;
  116. public:
  117. //00:00:00で初期化する
  118. Time() : Time(0, 0, 0) {}
  119. //struct tmから初期化する
  120. Time(const tm* tm) : Time(tm->tm_hour, tm->tm_min, tm->tm_sec) {}
  121. //時分秒を指定して初期化する
  122. Time(int hour, int minute, int second) {
  123. set_hour(hour);
  124. set_minute(minute);
  125. set_second(second);
  126. }
  127. //時を返す
  128. int get_hour() const { return m_hour; }
  129. //分を返す
  130. int get_minute() const { return m_minute; }
  131. //秒を返す
  132. int get_second() const { return m_second; }
  133. //時を設定する
  134. void set_hour(int hour) {
  135. if(hour < 0 || 24 <= hour) throw DateTimeError("0 <= hour < 24");
  136. m_hour = hour;
  137. }
  138. //分を設定する
  139. void set_minute(int minute) {
  140. if(minute < 0 || 60 <= minute) throw DateTimeError("0 <= minute < 60");
  141. m_minute = minute;
  142. }
  143. //秒を設定する
  144. void set_second(int second) {
  145. if(second < 0 || 60 <= second) throw DateTimeError("0 <= second < 60");
  146. m_second = second;
  147. }
  148. //この時分秒をtime_tで返す
  149. time_t to_time_t() const { return utils::to_time_t(1900, 1, 1, m_hour, m_minute, m_second); }
  150. };
  151.  
  152. //日時クラス
  153. class DateTime : public DateTimeOperators<DateTime> {
  154. Date m_date;
  155. Time m_time;
  156. public:
  157. //1900/01/01 00:00:00で初期化する
  158. DateTime() = default;
  159. //struct tmから初期化する
  160. DateTime(tm* tm) : m_date(tm), m_time(tm) {}
  161. //Date, Timeから初期化する
  162. DateTime(const Date& date, const Time& time) : m_date(date), m_time(time) {}
  163. //年月日時分秒を指定して初期化する
  164. DateTime(int year, int month, int day, int hour, int minute, int second) : m_date(year, month, day), m_time(hour, minute, second) {}
  165. //年月日を返す
  166. const Date& get_date() const { return m_date; }
  167. //時分秒を返す
  168. const Time& get_time() const { return m_time; }
  169. //年月日を設定する
  170. void set_date(const Date& date) { m_date = date; }
  171. //時分秒を設定する
  172. void set_time(const Time& time) { m_time = time; }
  173. //この日時を書式に従って文字列に変換する
  174. string strftime(const string& format) const{
  175. auto tt = to_time_t();
  176. auto tm = localtime(&tt);
  177. char buf[100];
  178. return (std::strftime(buf, 100, format.c_str(), tm) != 0) ? buf : throw DateTimeError("strftime()");
  179. }
  180. //この日時をtime_tで返す
  181. time_t to_time_t() const {
  182. return utils::to_time_t(
  183. m_date.get_year(), m_date.get_month(), m_date.get_day(),
  184. m_time.get_hour(), m_time.get_minute(), m_time.get_second());
  185. }
  186. //この日時をsystem_clock::time_pointで返す
  187. system_clock::time_point to_point() const { return system_clock::from_time_t(to_time_t()); }
  188. //system_clock::time_pointからDateTimeを作成する
  189. static DateTime from_point(const system_clock::time_point& point) {
  190. auto tt = system_clock::to_time_t(point);
  191. auto tm = localtime(&tt);
  192. return tm;
  193. }
  194. //ローカルタイムからDateTimeを作成する
  195. static DateTime local() { return from_point(system_clock::now()); }
  196. };
  197.  
  198. inline ostream& operator<<(ostream& ostr, const Date& date) {
  199. ostr
  200. << setw(4) << setfill('0') << date.get_year() << "/"
  201. << setw(2) << setfill('0') << date.get_month() << "/"
  202. << setw(2) << setfill('0') << date.get_day();
  203. return ostr;
  204. }
  205. inline istream& operator>>(istream& istr, Date& date) {
  206. vector<int> nums;
  207. {
  208. string in;
  209. istr >> in;
  210. auto strs = utils::split(in, '/');
  211. transform(strs.begin(), strs.end(), back_inserter(nums), utils::to_int);
  212. if(nums.size() != 3) throw DateTimeError("nums.size() != 3");
  213. }
  214. auto it = nums.begin();
  215. date.set_year(*it++);
  216. date.set_month(*it++);
  217. date.set_day(*it++);
  218. return istr;
  219. }
  220. inline ostream& operator<<(ostream& ostr, const Time& time) {
  221. ostr
  222. << setw(2) << setfill('0') << time.get_hour() << ":"
  223. << setw(2) << setfill('0') << time.get_minute() << ":"
  224. << setw(2) << setfill('0') << time.get_second();
  225. return ostr;
  226. }
  227. inline istream& operator>>(istream& istr, Time& time) {
  228. vector<int> nums;
  229. {
  230. string in;
  231. istr >> in;
  232. auto strs = utils::split(in, ':');
  233. transform(strs.begin(), strs.end(), back_inserter(nums), utils::to_int);
  234. if(nums.size() != 3) throw DateTimeError("nums.size() != 3");
  235. }
  236. auto it = nums.begin();
  237. time.set_hour(*it++);
  238. time.set_minute(*it++);
  239. time.set_second(*it++);
  240. return istr;
  241. }
  242. inline ostream& operator<<(ostream& ostr, const DateTime& datetime) {
  243. ostr
  244. << datetime.get_date() << " "
  245. << datetime.get_time();
  246. return ostr;
  247. }
  248. inline istream& operator>>(istream& istr, DateTime& datetime) {
  249. Date date;
  250. Time time;
  251. istr >> date;
  252. istr >> time;
  253. datetime.set_date(date);
  254. datetime.set_time(time);
  255. return istr;
  256. }
  257.  
  258. void test1() {
  259. DateTime datetime;
  260. cin >> datetime;
  261. cout << __FUNCTION__ << " : " << datetime << endl;
  262. }
  263. void test2() {
  264. auto datetime = DateTime::local();
  265. cout << __FUNCTION__ << " : " << datetime << endl;
  266. }
  267. void test3() {
  268. auto datetime = DateTime::local();
  269. datetime = DateTime::from_point(datetime.to_point());
  270. cout << __FUNCTION__ << " : " << datetime << endl;
  271. }
  272. void test4() {
  273. auto datetime = DateTime::local();
  274. cout << __FUNCTION__ << " : " << datetime.strftime("%Y/%m/%d %H:%M:%S (%%c='%c')") << endl;
  275. }
  276. void test5() {
  277. vector<DateTime> datetimes = {
  278. {1995, 11, 11, 5, 50, 22},
  279. {2004, 12, 20, 3, 48, 16},
  280. {2011, 9, 7, 21, 24, 32},
  281. {2011, 9, 7, 21, 24, 31},
  282. {2014, 3, 19, 18, 10, 20},
  283. {2005, 7, 25, 13, 31, 12}};
  284. sort(datetimes.begin(), datetimes.end());
  285. cout << __FUNCTION__ << endl;
  286. for(auto& datetime : datetimes) cout << datetime << endl;
  287. }
  288.  
  289. int main()
  290. try {
  291. test1();
  292. test2();
  293. test3();
  294. test4();
  295. test5();
  296. return 0;
  297. } catch(const exception& err) {
  298. //cerr << err.what() << endl;
  299. cout << "ERROR " << err.what() << endl;
  300. return 1;
  301. }
Success #stdin #stdout 0s 3500KB
stdin
2014/03/19 08:59:30
stdout
test1 : 2014/03/19 08:59:30
test2 : 2014/03/19 02:52:21
test3 : 2014/03/19 02:52:21
test4 : 2014/03/19 02:52:21 (%c='Wed Mar 19 02:52:21 2014')
test5
1995/11/11 05:50:22
2004/12/20 03:48:16
2005/07/25 13:31:12
2011/09/07 21:24:31
2011/09/07 21:24:32
2014/03/19 18:10:20