PageRenderTime 23ms CodeModel.GetById 1ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 0ms

/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
 26#include "llviewerprecompiledheaders.h"
 27
 28#include "lldateutil.h"
 29
 30#include <boost/date_time/gregorian/gregorian.hpp>
 31#include <boost/date_time/posix_time/ptime.hpp>
 32
 33// Linden libraries
 34#include "lltrans.h"
 35#include "llui.h"
 36
 37using namespace boost::gregorian;
 38using namespace boost::posix_time;
 39
 40static S32 DAYS_PER_MONTH_NOLEAP[] =
 41	{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
 42static S32 DAYS_PER_MONTH_LEAP[] =
 43	{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
 44
 45static S32 days_from_month(S32 year, S32 month)
 46{
 47	llassert_always(1 <= month);
 48	llassert_always(month <= 12);
 49
 50	if (year % 4 == 0 
 51		&& year % 100 != 0)
 52	{
 53		// leap year
 54		return DAYS_PER_MONTH_LEAP[month - 1];
 55	}
 56	else
 57	{
 58		return DAYS_PER_MONTH_NOLEAP[month - 1];
 59	}
 60}
 61
 62bool LLDateUtil::dateFromPDTString(LLDate& date, const std::string& str)
 63{
 64	S32 month, day, year;
 65	S32 matched = sscanf(str.c_str(), "%d/%d/%d", &month, &day, &year);
 66	if (matched != 3) return false;
 67	date.fromYMDHMS(year, month, day);
 68	F64 secs_since_epoch = date.secondsSinceEpoch();
 69	// Correct for the fact that specified date is in Pacific time, == UTC - 8
 70	secs_since_epoch += 8.0 * 60.0 * 60.0;
 71	date.secondsSinceEpoch(secs_since_epoch);
 72	return true;
 73}
 74
 75std::string LLDateUtil::ageFromDate(const LLDate& born_date, const LLDate& now)
 76{
 77	S32 born_month, born_day, born_year;
 78	// explode out to month/day/year again
 79	born_date.split(&born_year, &born_month, &born_day);
 80
 81	S32 now_year, now_month, now_day;
 82	now.split(&now_year, &now_month, &now_day);
 83
 84	// Do grade-school subtraction, from right-to-left, borrowing from the left
 85	// when things go negative
 86	S32 age_days = (now_day - born_day);
 87	if (age_days < 0)
 88	{
 89		now_month -= 1;
 90		if (now_month == 0)
 91		{
 92			now_year -= 1;
 93			now_month = 12;
 94		}
 95		age_days += days_from_month(now_year, now_month);
 96	}
 97	S32 age_months = (now_month - born_month);
 98	if (age_months < 0)
 99	{
100		now_year -= 1;
101		age_months += 12;
102	}
103	S32 age_years = (now_year - born_year);
104
105	// Noun pluralization depends on language
106	std::string lang = LLUI::getLanguage();
107
108	// Try for age in round number of years
109	LLStringUtil::format_map_t args;
110
111	if (age_months > 0 || age_years > 0)
112	{
113		args["[AGEYEARS]"] =
114			LLTrans::getCountString(lang, "AgeYears", age_years);
115		args["[AGEMONTHS]"] =
116			LLTrans::getCountString(lang, "AgeMonths", age_months);
117
118		// We want to display times like:
119		// 2 year 2 months
120		// 2 years (implicitly 0 months)
121		// 11 months
122		if (age_years > 0)
123		{
124			if (age_months > 0)
125			{
126				return LLTrans::getString("YearsMonthsOld", args);
127			}
128			else
129			{
130				return LLTrans::getString("YearsOld", args);
131			}
132		}
133		else // age_years == 0
134		{
135			return LLTrans::getString("MonthsOld", args);
136		}
137	}
138	// you're 0 months old, display in weeks or days
139
140	// Now for age in weeks
141	S32 age_weeks = age_days / 7;
142	age_days = age_days % 7;
143	if (age_weeks > 0)
144	{
145		args["[AGEWEEKS]"] = 
146			LLTrans::getCountString(lang, "AgeWeeks", age_weeks);
147		return LLTrans::getString("WeeksOld", args);
148	}
149
150	// Down to days now
151	if (age_days > 0)
152	{
153		args["[AGEDAYS]"] =
154			LLTrans::getCountString(lang, "AgeDays", age_days);
155		return LLTrans::getString("DaysOld", args);
156	}
157
158	return LLTrans::getString("TodayOld");
159}
160
161std::string LLDateUtil::ageFromDate(const std::string& date_string, const LLDate& now)
162{
163	LLDate born_date;
164
165	if (!dateFromPDTString(born_date, date_string))
166		return "???";
167
168	return ageFromDate(born_date, now);
169}
170
171std::string LLDateUtil::ageFromDate(const std::string& date_string)
172{
173	return ageFromDate(date_string, LLDate::now());
174}
175
176//std::string LLDateUtil::ageFromDateISO(const std::string& date_string,
177//									   const LLDate& now)
178//{
179//	S32 born_month, born_day, born_year;
180//	S32 matched = sscanf(date_string.c_str(), "%d-%d-%d",
181//			&born_year, &born_month, &born_day);
182//	if (matched != 3) return "???";
183//	date.fromYMDHMS(year, month, day);
184//	F64 secs_since_epoch = date.secondsSinceEpoch();
185//	// Correct for the fact that specified date is in Pacific time, == UTC - 8
186//	secs_since_epoch += 8.0 * 60.0 * 60.0;
187//	date.secondsSinceEpoch(secs_since_epoch);
188//	return ageFromDate(born_year, born_month, born_day, now);
189//}
190//
191//std::string LLDateUtil::ageFromDateISO(const std::string& date_string)
192//{
193//	return ageFromDateISO(date_string, LLDate::now());
194//}
195
196S32 LLDateUtil::secondsSinceEpochFromString(const std::string& format, const std::string& str)
197{
198	date_input_facet *facet = new date_input_facet(format);
199
200	std::stringstream ss;
201	ss << str;
202	ss.imbue(std::locale(ss.getloc(), facet));
203
204	date d;
205	ss >> d;
206
207	ptime time_t_date(d);
208	ptime time_t_epoch(date(1970,1,1));
209
210	// We assume that the date defined by str is in UTC, so the difference
211	// is calculated with no time zone corrections.
212	time_duration diff = time_t_date - time_t_epoch;
213
214	return diff.total_seconds();
215}