/indra/newview/lldateutil.cpp

https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 215 lines · 125 code · 30 blank · 60 comment · 18 complexity · 8b05da765fcdf678946557b334315849 MD5 · raw file

  1. /**
  2. * @file lldateutil.cpp
  3. *
  4. * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  5. * Second Life Viewer Source Code
  6. * Copyright (C) 2010, Linden Research, Inc.
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation;
  11. * version 2.1 of the License only.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. *
  22. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  23. * $/LicenseInfo$
  24. */
  25. #include "llviewerprecompiledheaders.h"
  26. #include "lldateutil.h"
  27. #include <boost/date_time/gregorian/gregorian.hpp>
  28. #include <boost/date_time/posix_time/ptime.hpp>
  29. // Linden libraries
  30. #include "lltrans.h"
  31. #include "llui.h"
  32. using namespace boost::gregorian;
  33. using namespace boost::posix_time;
  34. static S32 DAYS_PER_MONTH_NOLEAP[] =
  35. { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  36. static S32 DAYS_PER_MONTH_LEAP[] =
  37. { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  38. static S32 days_from_month(S32 year, S32 month)
  39. {
  40. llassert_always(1 <= month);
  41. llassert_always(month <= 12);
  42. if (year % 4 == 0
  43. && year % 100 != 0)
  44. {
  45. // leap year
  46. return DAYS_PER_MONTH_LEAP[month - 1];
  47. }
  48. else
  49. {
  50. return DAYS_PER_MONTH_NOLEAP[month - 1];
  51. }
  52. }
  53. bool LLDateUtil::dateFromPDTString(LLDate& date, const std::string& str)
  54. {
  55. S32 month, day, year;
  56. S32 matched = sscanf(str.c_str(), "%d/%d/%d", &month, &day, &year);
  57. if (matched != 3) return false;
  58. date.fromYMDHMS(year, month, day);
  59. F64 secs_since_epoch = date.secondsSinceEpoch();
  60. // Correct for the fact that specified date is in Pacific time, == UTC - 8
  61. secs_since_epoch += 8.0 * 60.0 * 60.0;
  62. date.secondsSinceEpoch(secs_since_epoch);
  63. return true;
  64. }
  65. std::string LLDateUtil::ageFromDate(const LLDate& born_date, const LLDate& now)
  66. {
  67. S32 born_month, born_day, born_year;
  68. // explode out to month/day/year again
  69. born_date.split(&born_year, &born_month, &born_day);
  70. S32 now_year, now_month, now_day;
  71. now.split(&now_year, &now_month, &now_day);
  72. // Do grade-school subtraction, from right-to-left, borrowing from the left
  73. // when things go negative
  74. S32 age_days = (now_day - born_day);
  75. if (age_days < 0)
  76. {
  77. now_month -= 1;
  78. if (now_month == 0)
  79. {
  80. now_year -= 1;
  81. now_month = 12;
  82. }
  83. age_days += days_from_month(now_year, now_month);
  84. }
  85. S32 age_months = (now_month - born_month);
  86. if (age_months < 0)
  87. {
  88. now_year -= 1;
  89. age_months += 12;
  90. }
  91. S32 age_years = (now_year - born_year);
  92. // Noun pluralization depends on language
  93. std::string lang = LLUI::getLanguage();
  94. // Try for age in round number of years
  95. LLStringUtil::format_map_t args;
  96. if (age_months > 0 || age_years > 0)
  97. {
  98. args["[AGEYEARS]"] =
  99. LLTrans::getCountString(lang, "AgeYears", age_years);
  100. args["[AGEMONTHS]"] =
  101. LLTrans::getCountString(lang, "AgeMonths", age_months);
  102. // We want to display times like:
  103. // 2 year 2 months
  104. // 2 years (implicitly 0 months)
  105. // 11 months
  106. if (age_years > 0)
  107. {
  108. if (age_months > 0)
  109. {
  110. return LLTrans::getString("YearsMonthsOld", args);
  111. }
  112. else
  113. {
  114. return LLTrans::getString("YearsOld", args);
  115. }
  116. }
  117. else // age_years == 0
  118. {
  119. return LLTrans::getString("MonthsOld", args);
  120. }
  121. }
  122. // you're 0 months old, display in weeks or days
  123. // Now for age in weeks
  124. S32 age_weeks = age_days / 7;
  125. age_days = age_days % 7;
  126. if (age_weeks > 0)
  127. {
  128. args["[AGEWEEKS]"] =
  129. LLTrans::getCountString(lang, "AgeWeeks", age_weeks);
  130. return LLTrans::getString("WeeksOld", args);
  131. }
  132. // Down to days now
  133. if (age_days > 0)
  134. {
  135. args["[AGEDAYS]"] =
  136. LLTrans::getCountString(lang, "AgeDays", age_days);
  137. return LLTrans::getString("DaysOld", args);
  138. }
  139. return LLTrans::getString("TodayOld");
  140. }
  141. std::string LLDateUtil::ageFromDate(const std::string& date_string, const LLDate& now)
  142. {
  143. LLDate born_date;
  144. if (!dateFromPDTString(born_date, date_string))
  145. return "???";
  146. return ageFromDate(born_date, now);
  147. }
  148. std::string LLDateUtil::ageFromDate(const std::string& date_string)
  149. {
  150. return ageFromDate(date_string, LLDate::now());
  151. }
  152. //std::string LLDateUtil::ageFromDateISO(const std::string& date_string,
  153. // const LLDate& now)
  154. //{
  155. // S32 born_month, born_day, born_year;
  156. // S32 matched = sscanf(date_string.c_str(), "%d-%d-%d",
  157. // &born_year, &born_month, &born_day);
  158. // if (matched != 3) return "???";
  159. // date.fromYMDHMS(year, month, day);
  160. // F64 secs_since_epoch = date.secondsSinceEpoch();
  161. // // Correct for the fact that specified date is in Pacific time, == UTC - 8
  162. // secs_since_epoch += 8.0 * 60.0 * 60.0;
  163. // date.secondsSinceEpoch(secs_since_epoch);
  164. // return ageFromDate(born_year, born_month, born_day, now);
  165. //}
  166. //
  167. //std::string LLDateUtil::ageFromDateISO(const std::string& date_string)
  168. //{
  169. // return ageFromDateISO(date_string, LLDate::now());
  170. //}
  171. S32 LLDateUtil::secondsSinceEpochFromString(const std::string& format, const std::string& str)
  172. {
  173. date_input_facet *facet = new date_input_facet(format);
  174. std::stringstream ss;
  175. ss << str;
  176. ss.imbue(std::locale(ss.getloc(), facet));
  177. date d;
  178. ss >> d;
  179. ptime time_t_date(d);
  180. ptime time_t_epoch(date(1970,1,1));
  181. // We assume that the date defined by str is in UTC, so the difference
  182. // is calculated with no time zone corrections.
  183. time_duration diff = time_t_date - time_t_epoch;
  184. return diff.total_seconds();
  185. }