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.master
parent
81eca4a782
commit
7ab6dc37f8
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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" );
|
||||
|
|
|
|||
Loading…
Reference in New Issue