summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorJames Cook <james@lindenlab.com>2009-11-18 19:21:09 -0800
committerJames Cook <james@lindenlab.com>2009-11-18 19:21:09 -0800
commit7ab6dc37f8bcc348ecbdaddce4a32d068e344670 (patch)
tree009ca4fcd332e682bc9af57c28282fe5030f97b5 /indra
parent81eca4a7823f7fa06327b8185b6603d1f3c9ac9a (diff)
EXT-1743 People inspectors should show Age, not Date born, fixed date math
Changed date math to correctly account for month lengths and leap years. Extended unit test. Review pending.
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/lldateutil.cpp71
-rw-r--r--indra/newview/llinspectavatar.cpp3
-rw-r--r--indra/newview/tests/lldateutil_test.cpp26
3 files changed, 90 insertions, 10 deletions
diff --git a/indra/newview/lldateutil.cpp b/indra/newview/lldateutil.cpp
index 040fad3c4a..1fe1715995 100644
--- a/indra/newview/lldateutil.cpp
+++ b/indra/newview/lldateutil.cpp
@@ -66,23 +66,82 @@ static S32 age_days_from_date(const std::string& date_string,
return age_days;
}
+static S32 DAYS_PER_MONTH_NOLEAP[] =
+ { 31, 28, 21, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+static S32 DAYS_PER_MONTH_LEAP[] =
+ { 31, 29, 21, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+static S32 days_from_month(S32 year, S32 month)
+{
+ if (year % 4 == 0
+ && year % 100 != 0)
+ {
+ // leap year
+ return DAYS_PER_MONTH_LEAP[month];
+ }
+ else
+ {
+ return DAYS_PER_MONTH_NOLEAP[month];
+ }
+}
+
std::string LLDateUtil::ageFromDate(const std::string& date_string,
const LLDate& now)
{
+#define BAD_DATE_MATH 0
+#if BAD_DATE_MATH
S32 age_days = age_days_from_date(date_string, now);
if (age_days == S32_MIN) return "???";
-
- // Noun pluralization depends on language
- std::string lang = LLUI::getLanguage();
-
- // Try for age in round number of years
- LLStringUtil::format_map_t args;
S32 age_years = age_days / 365;
age_days = age_days % 365;
// *NOTE: This is wrong. Not all months have 30 days, but we don't have a library
// for relative date arithmetic. :-( JC
S32 age_months = age_days / 30;
age_days = age_days % 30;
+#else
+ S32 born_month, born_day, born_year;
+ S32 matched = sscanf(date_string.c_str(), "%d/%d/%d", &born_month, &born_day, &born_year);
+ if (matched != 3) return "???";
+ LLDate born_date;
+ born_date.fromYMDHMS(born_year, born_month, born_day);
+ F64 born_date_secs_since_epoch = born_date.secondsSinceEpoch();
+ // Correct for the fact that account creation dates are in Pacific time,
+ // == UTC - 8
+ born_date_secs_since_epoch += 8.0 * 60.0 * 60.0;
+ born_date.secondsSinceEpoch(born_date_secs_since_epoch);
+ // explode out to month/day/year again
+ born_date.split(&born_year, &born_month, &born_day);
+
+ S32 now_year, now_month, now_day;
+ now.split(&now_year, &now_month, &now_day);
+
+ // Do grade-school subtraction, from right-to-left, borrowing from the left
+ // when things go negative
+ S32 age_days = (now_day - born_day);
+ if (age_days < 0)
+ {
+ now_month -= 1;
+ if (now_month == 0)
+ {
+ now_year -= 1;
+ now_month = 12;
+ }
+ age_days += days_from_month(now_year, now_month);
+ }
+ S32 age_months = (now_month - born_month);
+ if (age_months < 0)
+ {
+ now_year -= 1;
+ age_months += 12;
+ }
+ S32 age_years = (now_year - born_year);
+#endif
+
+ // Noun pluralization depends on language
+ std::string lang = LLUI::getLanguage();
+
+ // Try for age in round number of years
+ LLStringUtil::format_map_t args;
if (age_months > 0 || age_years > 0)
{
diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index baddd90d46..866669f326 100644
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -39,6 +39,7 @@
#include "llavataractions.h"
#include "llavatarpropertiesprocessor.h"
#include "llcallingcard.h"
+#include "lldateutil.h"
#include "llfloaterreporter.h"
#include "llfloaterworldmap.h"
#include "llinspect.h"
@@ -351,7 +352,7 @@ void LLInspectAvatar::processAvatarData(LLAvatarData* data)
{
LLStringUtil::format_map_t args;
args["[BORN_ON]"] = data->born_on;
- args["[AGE]"] = data->born_on;
+ args["[AGE]"] = LLDateUtil::ageFromDate(data->born_on, LLDate::now());
args["[SL_PROFILE]"] = data->about_text;
args["[RW_PROFILE"] = data->fl_about_text;
args["[ACCTTYPE]"] = LLAvatarPropertiesProcessor::accountType(data);
diff --git a/indra/newview/tests/lldateutil_test.cpp b/indra/newview/tests/lldateutil_test.cpp
index ed753b6ff7..142a5eb5e6 100644
--- a/indra/newview/tests/lldateutil_test.cpp
+++ b/indra/newview/tests/lldateutil_test.cpp
@@ -60,6 +60,11 @@ std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::
std::string LLTrans::getCountString(const std::string& language, const std::string& xml_desc, S32 count)
{
+ count_string_t key(xml_desc, count);
+ if (gCountString.find(key) == gCountString.end())
+ {
+ return std::string("Couldn't find ") + xml_desc;
+ }
return gCountString[ count_string_t(xml_desc, count) ];
}
@@ -91,8 +96,11 @@ namespace tut
gCountString[ count_string_t("AgeYears", 2) ] = "2 years";
gCountString[ count_string_t("AgeMonths", 1) ] = "1 month";
gCountString[ count_string_t("AgeMonths", 2) ] = "2 months";
+ gCountString[ count_string_t("AgeMonths", 11) ]= "11 months";
gCountString[ count_string_t("AgeWeeks", 1) ] = "1 week";
gCountString[ count_string_t("AgeWeeks", 2) ] = "2 weeks";
+ gCountString[ count_string_t("AgeWeeks", 3) ] = "3 weeks";
+ gCountString[ count_string_t("AgeWeeks", 4) ] = "4 weeks";
gCountString[ count_string_t("AgeDays", 1) ] = "1 day";
gCountString[ count_string_t("AgeDays", 2) ] = "2 days";
}
@@ -113,12 +121,18 @@ namespace tut
ensure_equals("years",
LLDateUtil::ageFromDate("12/31/2007", mNow),
"2 years old" );
- ensure_equals("single year",
- LLDateUtil::ageFromDate("12/31/2008", mNow),
- "1 year old" );
+ ensure_equals("years",
+ LLDateUtil::ageFromDate("1/1/2008", mNow),
+ "1 year 11 months old" );
+ ensure_equals("single year + one month",
+ LLDateUtil::ageFromDate("11/30/2008", mNow),
+ "1 year 1 month old" );
ensure_equals("single year + a bit",
LLDateUtil::ageFromDate("12/12/2008", mNow),
"1 year old" );
+ ensure_equals("single year",
+ LLDateUtil::ageFromDate("12/31/2008", mNow),
+ "1 year old" );
}
template<> template<>
@@ -128,6 +142,9 @@ namespace tut
ensure_equals("months",
LLDateUtil::ageFromDate("10/30/2009", mNow),
"2 months old" );
+ ensure_equals("months 2",
+ LLDateUtil::ageFromDate("10/31/2009", mNow),
+ "2 months old" );
ensure_equals("single month",
LLDateUtil::ageFromDate("11/30/2009", mNow),
"1 month old" );
@@ -137,6 +154,9 @@ namespace tut
void dateutil_object_t::test<3>()
{
set_test_name("Weeks");
+ ensure_equals("4 weeks",
+ LLDateUtil::ageFromDate("12/1/2009", mNow),
+ "4 weeks old" );
ensure_equals("weeks",
LLDateUtil::ageFromDate("12/17/2009", mNow),
"2 weeks old" );