plistdate.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. //
  2. // PlistDate class appropriate for Apple Property Lists (plists). Part of
  3. // the PlistCpp Apple Property List (plist) serialization and parsing
  4. // library.
  5. //
  6. // https://github.com/animetrics/PlistCpp
  7. //
  8. // Copyright (c) 2011 Animetrics Inc. (marc@animetrics.com)
  9. //
  10. // Permission is hereby granted, free of charge, to any person obtaining a copy
  11. // of this software and associated documentation files (the "Software"), to deal
  12. // in the Software without restriction, including without limitation the rights
  13. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  14. // copies of the Software, and to permit persons to whom the Software is
  15. // furnished to do so, subject to the following conditions:
  16. //
  17. // The above copyright notice and this permission notice shall be included in
  18. // all copies or substantial portions of the Software.
  19. //
  20. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  23. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  26. // THE SOFTWARE.
  27. #include "plisthpp/PlistDate.hpp"
  28. #include "plisthpp/Plist.hpp" // Plist::Error
  29. #include <stdexcept>
  30. #include <stdio.h>
  31. namespace Plist {
  32. Date::Date()
  33. {
  34. setToCurrentTime();
  35. }
  36. Date::Date(int month, int day, int year, int hour24, int minute, int second, bool UTC)
  37. {
  38. set(month, day, year, hour24, minute, second, UTC);
  39. }
  40. void Date::set(int month, int day, int year, int hour24, int minute, int second, bool UTC)
  41. {
  42. struct tm tmTime;
  43. tmTime.tm_hour = hour24;
  44. tmTime.tm_mday = day;
  45. tmTime.tm_year = year - 1900;
  46. tmTime.tm_sec = second;
  47. tmTime.tm_mon = month - 1;
  48. tmTime.tm_min = minute;
  49. //get proper day light savings.
  50. time_t loc = time(NULL);
  51. struct tm tmLoc = *localtime(&loc);
  52. //std::cout<<"tmLoc.tm_isdst = "<<tmLoc.tm_isdst<<std::endl;
  53. tmTime.tm_isdst = tmLoc.tm_isdst;
  54. if(UTC)
  55. {
  56. //_time = timegm(&tmTime);
  57. tmTime.tm_isdst = 0;
  58. _time = mktime(&tmTime);
  59. if(_time < -1)
  60. throw Error("Plist::Date::set() date invalid");
  61. // don't have timegm for all systems so here's a portable way to do it.
  62. struct tm tmTimeTemp;
  63. #if defined(_WIN32) || defined(_WIN64)
  64. gmtime_s(&tmTimeTemp, &_time);
  65. #else
  66. gmtime_r(&_time, &tmTimeTemp);
  67. #endif
  68. time_t timeTemp = mktime(&tmTimeTemp);
  69. time_t diff = _time - timeTemp;
  70. _time += diff;
  71. }
  72. else
  73. {
  74. _time = mktime(&tmTime);
  75. if(_time < -1)
  76. throw Error("Plist::Date::set() date invalid");
  77. }
  78. }
  79. void Date::setToCurrentTime()
  80. {
  81. _time = time(NULL);
  82. }
  83. time_t Date::secondsSinceDate(const Date& startDate) const
  84. {
  85. return _time - startDate.timeAsEpoch();
  86. }
  87. // returns -1 : first < second
  88. // 0 : first = second
  89. // 1 : first > second
  90. int Date::compare(const Date& first, const Date& second)
  91. {
  92. if(first.timeAsEpoch() < second.timeAsEpoch())
  93. return -1;
  94. else if (first.timeAsEpoch() == second.timeAsEpoch())
  95. return 0;
  96. else
  97. return 1;
  98. }
  99. bool Date::operator > (const Date& rhs) const
  100. {
  101. if(compare(*this, rhs) == 1)
  102. return true;
  103. else
  104. return false;
  105. }
  106. bool Date::operator < (const Date& rhs) const
  107. {
  108. if(compare(*this, rhs) == -1)
  109. return true;
  110. else
  111. return false;
  112. }
  113. bool Date::operator == (const Date& rhs) const
  114. {
  115. if(compare(*this, rhs) == 0)
  116. return true;
  117. else
  118. return false;
  119. }
  120. // iso 8601 date string convention
  121. std::string Date::timeAsXMLConvention() const
  122. {
  123. char result[21];
  124. struct tm tmTime;
  125. // use thread safe versions here. Notice that arguments
  126. // are reversed for windows version
  127. #if defined(_WIN32) || defined(_WIN64)
  128. gmtime_s(&tmTime, &_time);
  129. #else
  130. gmtime_r(&_time, &tmTime);
  131. #endif
  132. // %F and %T not portable so using %Y-%m-%d and %H:%M:%S instead
  133. strftime(&result[0], 21, "%Y-%m-%dT%H:%M:%SZ", &tmTime);
  134. return std::string(&result[0]);
  135. }
  136. // iso 8601 date string convention
  137. void Date::setTimeFromXMLConvention(const std::string& timeString)
  138. {
  139. int month, day, year, hour24, minute, second;
  140. // parse date string. E.g. 2011-09-25T02:31:04Z
  141. sscanf(timeString.c_str(), "%4d-%2d-%2dT%2d:%2d:%2dZ", &year, &month, &day, &hour24, &minute, &second);
  142. set(month, day, year, hour24, minute, second, true);
  143. }
  144. // Apple epoch is # of seconds since 01-01-2001. So we need to add the
  145. // number of seconds since 01-01-1970 which is proper unix epoch
  146. void Date::setTimeFromAppleEpoch(double appleTime)
  147. {
  148. _time = time_t(978307200 + appleTime);
  149. }
  150. time_t Date::timeAsEpoch() const
  151. {
  152. return _time;
  153. }
  154. // We need to subtract the number of seconds between 01-01-2001 and
  155. // 01-01-1970 to get Apple epoch from unix epoch
  156. double Date::timeAsAppleEpoch() const
  157. {
  158. return ((double) _time - 978307200);
  159. }
  160. }