lldate.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:7k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file lldate.cpp
  3.  * @author Phoenix
  4.  * @date 2006-02-05
  5.  * @brief Implementation of the date class
  6.  *
  7.  * $LicenseInfo:firstyear=2006&license=viewergpl$
  8.  * 
  9.  * Copyright (c) 2006-2010, Linden Research, Inc.
  10.  * 
  11.  * Second Life Viewer Source Code
  12.  * The source code in this file ("Source Code") is provided by Linden Lab
  13.  * to you under the terms of the GNU General Public License, version 2.0
  14.  * ("GPL"), unless you have obtained a separate licensing agreement
  15.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  16.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  17.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  18.  * 
  19.  * There are special exceptions to the terms and conditions of the GPL as
  20.  * it is applied to this Source Code. View the full text of the exception
  21.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  22.  * online at
  23.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  24.  * 
  25.  * By copying, modifying or distributing this software, you acknowledge
  26.  * that you have read and understood your obligations described above,
  27.  * and agree to abide by those obligations.
  28.  * 
  29.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  30.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  31.  * COMPLETENESS OR PERFORMANCE.
  32.  * $/LicenseInfo$
  33.  */
  34. #include "linden_common.h"
  35. #include "lldate.h"
  36. #include "apr_time.h"
  37. #include <time.h>
  38. #include <locale.h>
  39. #include <string>
  40. #include <iomanip>
  41. #include <sstream>
  42. #include "lltimer.h"
  43. #include "llstring.h"
  44. static const F64 DATE_EPOCH = 0.0;
  45. static const F64 LL_APR_USEC_PER_SEC = 1000000.0;
  46. // should be APR_USEC_PER_SEC, but that relies on INT64_C which
  47. // isn't defined in glib under our build set up for some reason
  48. LLDate::LLDate() : mSecondsSinceEpoch(DATE_EPOCH)
  49. {
  50. }
  51. LLDate::LLDate(const LLDate& date) :
  52. mSecondsSinceEpoch(date.mSecondsSinceEpoch)
  53. {
  54. }
  55. LLDate::LLDate(F64 seconds_since_epoch) :
  56. mSecondsSinceEpoch(seconds_since_epoch)
  57. {
  58. }
  59. LLDate::LLDate(const std::string& iso8601_date)
  60. {
  61. if(!fromString(iso8601_date))
  62. {
  63. llwarns << "date " << iso8601_date << " failed to parse; "
  64. << "ZEROING IT OUT" << llendl;
  65. mSecondsSinceEpoch = DATE_EPOCH;
  66. }
  67. }
  68. std::string LLDate::asString() const
  69. {
  70. std::ostringstream stream;
  71. toStream(stream);
  72. return stream.str();
  73. }
  74. //@ brief Converts time in seconds since EPOCH
  75. //        to RFC 1123 compliant date format
  76. //        E.g. 1184797044.037586 == Wednesday, 18 Jul 2007 22:17:24 GMT
  77. //        in RFC 1123. HTTP dates are always in GMT and RFC 1123
  78. //        is one of the standards used and the prefered format
  79. std::string LLDate::asRFC1123() const
  80. {
  81. return toHTTPDateString (std::string ("%A, %d %b %Y %H:%M:%S GMT"));
  82. }
  83. LLFastTimer::DeclareTimer FT_DATE_FORMAT("Date Format");
  84. std::string LLDate::toHTTPDateString (std::string fmt) const
  85. {
  86. LLFastTimer ft1(FT_DATE_FORMAT);
  87. time_t locSeconds = (time_t) mSecondsSinceEpoch;
  88. struct tm * gmt = gmtime (&locSeconds);
  89. return toHTTPDateString(gmt, fmt);
  90. }
  91. std::string LLDate::toHTTPDateString (tm * gmt, std::string fmt)
  92. {
  93. LLFastTimer ft1(FT_DATE_FORMAT);
  94. // avoid calling setlocale() unnecessarily - it's expensive.
  95. static std::string prev_locale = "";
  96. std::string this_locale = LLStringUtil::getLocale();
  97. if (this_locale != prev_locale)
  98. {
  99. setlocale(LC_TIME, this_locale.c_str());
  100. prev_locale = this_locale;
  101. }
  102. // use strftime() as it appears to be faster than std::time_put
  103. char buffer[128];
  104. strftime(buffer, 128, fmt.c_str(), gmt);
  105. return std::string(buffer);
  106. }
  107. void LLDate::toStream(std::ostream& s) const
  108. {
  109. apr_time_t time = (apr_time_t)(mSecondsSinceEpoch * LL_APR_USEC_PER_SEC);
  110. apr_time_exp_t exp_time;
  111. if (apr_time_exp_gmt(&exp_time, time) != APR_SUCCESS)
  112. {
  113. s << "1970-01-01T00:00:00Z";
  114. return;
  115. }
  116. s << std::dec << std::setfill('0');
  117. #if( LL_WINDOWS || __GNUC__ > 2)
  118. s << std::right;
  119. #else
  120. s.setf(ios::right);
  121. #endif
  122. s  << std::setw(4) << (exp_time.tm_year + 1900)
  123.   << '-' << std::setw(2) << (exp_time.tm_mon + 1)
  124.   << '-' << std::setw(2) << (exp_time.tm_mday)
  125.   << 'T' << std::setw(2) << (exp_time.tm_hour)
  126.   << ':' << std::setw(2) << (exp_time.tm_min)
  127.   << ':' << std::setw(2) << (exp_time.tm_sec);
  128. if (exp_time.tm_usec > 0)
  129. {
  130. s << '.' << std::setw(2)
  131.   << (int)(exp_time.tm_usec / (LL_APR_USEC_PER_SEC / 100));
  132. }
  133. s << 'Z'
  134.   << std::setfill(' ');
  135. }
  136. bool LLDate::split(S32 *year, S32 *month, S32 *day, S32 *hour, S32 *min, S32 *sec) const
  137. {
  138. apr_time_t time = (apr_time_t)(mSecondsSinceEpoch * LL_APR_USEC_PER_SEC);
  139. apr_time_exp_t exp_time;
  140. if (apr_time_exp_gmt(&exp_time, time) != APR_SUCCESS)
  141. {
  142. return false;
  143. }
  144. if (year)
  145. *year = exp_time.tm_year + 1900;
  146. if (month)
  147. *month = exp_time.tm_mon + 1;
  148. if (day)
  149. *day = exp_time.tm_mday;
  150. if (hour)
  151. *hour = exp_time.tm_hour;
  152. if (min)
  153. *min = exp_time.tm_min;
  154. if (sec)
  155. *sec = exp_time.tm_sec;
  156. return true;
  157. }
  158. bool LLDate::fromString(const std::string& iso8601_date)
  159. {
  160. std::istringstream stream(iso8601_date);
  161. return fromStream(stream);
  162. }
  163. bool LLDate::fromStream(std::istream& s)
  164. {
  165. struct apr_time_exp_t exp_time;
  166. apr_int32_t tm_part;
  167. int c;
  168. s >> tm_part;
  169. exp_time.tm_year = tm_part - 1900;
  170. c = s.get(); // skip the hypen
  171. if (c != '-') { return false; }
  172. s >> tm_part;
  173. exp_time.tm_mon = tm_part - 1;
  174. c = s.get(); // skip the hypen
  175. if (c != '-') { return false; }
  176. s >> tm_part;
  177. exp_time.tm_mday = tm_part;
  178. c = s.get(); // skip the T
  179. if (c != 'T') { return false; }
  180. s >> tm_part;
  181. exp_time.tm_hour = tm_part;
  182. c = s.get(); // skip the :
  183. if (c != ':') { return false; }
  184. s >> tm_part;
  185. exp_time.tm_min = tm_part;
  186. c = s.get(); // skip the :
  187. if (c != ':') { return false; }
  188. s >> tm_part;
  189. exp_time.tm_sec = tm_part;
  190. // zero out the unused fields
  191. exp_time.tm_usec = 0;
  192. exp_time.tm_wday = 0;
  193. exp_time.tm_yday = 0;
  194. exp_time.tm_isdst = 0;
  195. exp_time.tm_gmtoff = 0;
  196. // generate a time_t from that
  197. apr_time_t time;
  198. if (apr_time_exp_gmt_get(&time, &exp_time) != APR_SUCCESS)
  199. {
  200. return false;
  201. }
  202. F64 seconds_since_epoch = time / LL_APR_USEC_PER_SEC;
  203. // check for fractional
  204. c = s.peek();
  205. if(c == '.')
  206. {
  207. F64 fractional = 0.0;
  208. s >> fractional;
  209. seconds_since_epoch += fractional;
  210. }
  211. c = s.get(); // skip the Z
  212. if (c != 'Z') { return false; }
  213. mSecondsSinceEpoch = seconds_since_epoch;
  214. return true;
  215. }
  216. bool LLDate::fromYMDHMS(S32 year, S32 month, S32 day, S32 hour, S32 min, S32 sec)
  217. {
  218. struct apr_time_exp_t exp_time;
  219. exp_time.tm_year = year - 1900;
  220. exp_time.tm_mon = month - 1;
  221. exp_time.tm_mday = day;
  222. exp_time.tm_hour = hour;
  223. exp_time.tm_min = min;
  224. exp_time.tm_sec = sec;
  225. // zero out the unused fields
  226. exp_time.tm_usec = 0;
  227. exp_time.tm_wday = 0;
  228. exp_time.tm_yday = 0;
  229. exp_time.tm_isdst = 0;
  230. exp_time.tm_gmtoff = 0;
  231. // generate a time_t from that
  232. apr_time_t time;
  233. if (apr_time_exp_gmt_get(&time, &exp_time) != APR_SUCCESS)
  234. {
  235. return false;
  236. }
  237. mSecondsSinceEpoch = time / LL_APR_USEC_PER_SEC;
  238. return true;
  239. }
  240. F64 LLDate::secondsSinceEpoch() const
  241. {
  242. return mSecondsSinceEpoch;
  243. }
  244. void LLDate::secondsSinceEpoch(F64 seconds)
  245. {
  246. mSecondsSinceEpoch = seconds;
  247. }
  248. /* static */ LLDate LLDate::now()
  249. {
  250. // time() returns seconds, we want fractions of a second, which LLTimer provides --RN
  251. return LLDate(LLTimer::getTotalSeconds());
  252. }
  253. bool LLDate::operator<(const LLDate& rhs) const
  254. {
  255.     return mSecondsSinceEpoch < rhs.mSecondsSinceEpoch;
  256. }
  257. std::ostream& operator<<(std::ostream& s, const LLDate& date)
  258. {
  259. date.toStream(s);
  260. return s;
  261. }
  262. std::istream& operator>>(std::istream& s, LLDate& date)
  263. {
  264. date.fromStream(s);
  265. return s;
  266. }