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.meow-7.2.2
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