From 05626c3371395d76b1f2e6b7fcbe64ef12f7d974 Mon Sep 17 00:00:00 2001
From: Yuri Chebotarev <ychebotarev@productengine.com>
Date: Fri, 28 May 2010 20:13:18 +0300
Subject: [PATCH] EXT-7013 FIX time formatting function didn't work for some
 parameters for Japanise (like weekdays).

reviewed by Vadim Savchuk https://codereview.productengine.com/secondlife/r/457/

--HG--
branch : product-engine
---
 indra/llcommon/llstring.cpp                   | 103 +++++++++++++++++-
 indra/llcommon/llstring.h                     |  18 +++
 indra/newview/llappviewer.cpp                 |  11 +-
 .../newview/skins/default/xui/en/strings.xml  |  15 +++
 .../newview/skins/default/xui/ja/strings.xml  |  20 +++-
 5 files changed, 164 insertions(+), 3 deletions(-)

diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index b5a73ec1d13..8197e3e642a 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -676,6 +676,17 @@ long LLStringOps::sLocalTimeOffset = 0;
 bool LLStringOps::sPacificDaylightTime = 0;
 std::map<std::string, std::string> LLStringOps::datetimeToCodes;
 
+std::vector<std::string> LLStringOps::sWeekDayList;
+std::vector<std::string> LLStringOps::sWeekDayShortList;
+std::vector<std::string> LLStringOps::sMonthList;
+std::vector<std::string> LLStringOps::sMonthShortList;
+
+
+std::string LLStringOps::sDayFormat;
+std::string LLStringOps::sAM;
+std::string LLStringOps::sPM;
+
+
 S32	LLStringOps::collate(const llwchar* a, const llwchar* b)
 { 
 	#if LL_WINDOWS
@@ -724,6 +735,50 @@ void LLStringOps::setupDatetimeInfo (bool daylight)
 	datetimeToCodes["timezone"]	= "%Z";		// PST
 }
 
+void tokenizeStringToArray(const std::string& data, std::vector<std::string>& output)
+{
+	output.clear();
+	size_t length = data.size();
+	
+	// tokenize it and put it in the array
+	std::string cur_word;
+	for(size_t i = 0; i < length; ++i)
+	{
+		if(data[i] == ':')
+		{
+			output.push_back(cur_word);
+			cur_word.clear();
+		}
+		else
+		{
+			cur_word.append(1, data[i]);
+		}
+	}
+	output.push_back(cur_word);
+}
+
+void LLStringOps::setupWeekDaysNames(const std::string& data)
+{
+	tokenizeStringToArray(data,sWeekDayList);
+}
+void LLStringOps::setupWeekDaysShortNames(const std::string& data)
+{
+	tokenizeStringToArray(data,sWeekDayShortList);
+}
+void LLStringOps::setupMonthNames(const std::string& data)
+{
+	tokenizeStringToArray(data,sMonthList);
+}
+void LLStringOps::setupMonthShortNames(const std::string& data)
+{
+	tokenizeStringToArray(data,sMonthShortList);
+}
+void LLStringOps::setupDayFormat(const std::string& data)
+{
+	sDayFormat = data;
+}
+
+
 std::string LLStringOps::getDatetimeCode (std::string key)
 {
 	std::map<std::string, std::string>::iterator iter;
@@ -998,7 +1053,53 @@ bool LLStringUtil::formatDatetime(std::string& replacement, std::string token,
 		}
 		return true;
 	}
-	replacement = datetime.toHTTPDateString(code);
+
+	//EXT-7013
+	//few codes are not suppotred by strtime function (example - weekdays for Japanise)
+	//so use predefined ones
+	
+	//if sWeekDayList is not empty than current locale doesn't support
+        //weekday name.
+	time_t loc_seconds = (time_t) secFromEpoch;
+	if(LLStringOps::sWeekDayList.size() == 7 && code == "%A")
+	{
+		struct tm * gmt = gmtime (&loc_seconds);
+		replacement = LLStringOps::sWeekDayList[gmt->tm_wday];
+	}
+	else if(LLStringOps::sWeekDayShortList.size() == 7 && code == "%a")
+	{
+		struct tm * gmt = gmtime (&loc_seconds);
+		replacement = LLStringOps::sWeekDayShortList[gmt->tm_wday];
+	}
+	else if(LLStringOps::sMonthList.size() == 12 && code == "%B")
+	{
+		struct tm * gmt = gmtime (&loc_seconds);
+		replacement = LLStringOps::sWeekDayList[gmt->tm_mon];
+	}
+	else if( !LLStringOps::sDayFormat.empty() && code == "%d" )
+	{
+		struct tm * gmt = gmtime (&loc_seconds);
+		LLStringUtil::format_map_t args;
+		args["[MDAY]"] = llformat ("%d", gmt->tm_mday);
+		replacement = LLStringOps::sDayFormat;
+		LLStringUtil::format(replacement, args);
+	}
+	else if( !LLStringOps::sAM.empty() && !LLStringOps::sPM.empty() && code == "%p" )
+	{
+		struct tm * gmt = gmtime (&loc_seconds);
+		if(gmt->tm_hour<12)
+		{
+			replacement = LLStringOps::sAM;
+		}
+		else
+		{
+			replacement = LLStringOps::sPM;
+		}
+	}
+	else
+	{
+		replacement = datetime.toHTTPDateString(code);
+	}
 
 	// *HACK: delete leading zero from hour string in case 'hour12' (code = %I) time format
 	// to show time without leading zero, e.g. 08:16 -> 8:16 (EXT-2738).
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 96588b29b94..ad8f8632a27 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -154,9 +154,19 @@ class LL_COMMON_API LLStringOps
 	static long sPacificTimeOffset;
 	static long sLocalTimeOffset;
 	static bool sPacificDaylightTime;
+
 	static std::map<std::string, std::string> datetimeToCodes;
 
 public:
+	static std::vector<std::string> sWeekDayList;
+	static std::vector<std::string> sWeekDayShortList;
+	static std::vector<std::string> sMonthList;
+	static std::vector<std::string> sMonthShortList;
+	static std::string sDayFormat;
+
+	static std::string sAM;
+	static std::string sPM;
+
 	static char toUpper(char elem) { return toupper((unsigned char)elem); }
 	static llwchar toUpper(llwchar elem) { return towupper(elem); }
 	
@@ -185,6 +195,14 @@ class LL_COMMON_API LLStringOps
 	static S32	collate(const llwchar* a, const llwchar* b);
 
 	static void setupDatetimeInfo(bool pacific_daylight_time);
+
+	static void setupWeekDaysNames(const std::string& data);
+	static void setupWeekDaysShortNames(const std::string& data);
+	static void setupMonthNames(const std::string& data);
+	static void setupMonthShortNames(const std::string& data);
+	static void setupDayFormat(const std::string& data);
+
+
 	static long getPacificTimeOffset(void) { return sPacificTimeOffset;}
 	static long getLocalTimeOffset(void) { return sLocalTimeOffset;}
 	// Is the Pacific time zone (aka server time zone)
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index f7f7cb599e9..7b17933b5c3 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -890,7 +890,16 @@ bool LLAppViewer::init()
 	}
 	
 	LLViewerMedia::initClass();
-	
+
+	LLStringOps::setupWeekDaysNames(LLTrans::getString("dateTimeWeekdaysNames"));
+	LLStringOps::setupWeekDaysShortNames(LLTrans::getString("dateTimeWeekdaysShortNames"));
+	LLStringOps::setupMonthNames(LLTrans::getString("dateTimeMonthNames"));
+	LLStringOps::setupMonthShortNames(LLTrans::getString("dateTimeMonthShortNames"));
+	LLStringOps::setupDayFormat(LLTrans::getString("dateTimeDayFormat"));
+
+	LLStringOps::sAM = LLTrans::getString("dateTimeAM");
+	LLStringOps::sPM = LLTrans::getString("dateTimePM");
+
 	return true;
 }
 
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index e57b30185d8..9247e3f74ce 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3183,4 +3183,19 @@ Abuse Report</string>
 	Please check secondlife.com/status to see if there is a known problem with the service.
   </string>
 
+  <!-- overriding datetime formating. 
+	leave emtpy in for current localization this is not needed 
+	list of values should be separated with ':'
+        example:
+	<string name="dateTimeWeekdaysShortNames">
+	Son:Mon:Tue:Wed:Thu:Fri:Sat
+	</string>  	
+  -->
+  <string name="dateTimeWeekdaysNames"></string>
+  <string name="dateTimeWeekdaysShortNames"></string>
+  <string name="dateTimeMonthNames"></string>
+  <string name="dateTimeMonthShortNames"></string>
+  <string name="dateTimeDayFormat"></string>
+  <string name="dateTimeAM"></string>
+  <string name="dateTimePM"></string>
   </strings>
diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml
index 57120ff7ecb..a06dcc54e4f 100644
--- a/indra/newview/skins/default/xui/ja/strings.xml
+++ b/indra/newview/skins/default/xui/ja/strings.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <!-- This file contains strings that used to be hardcoded in the source.
      It is only for those strings which do not belong in a floater.
      For example, the strings used in avatar chat bubbles, and strings
@@ -3614,4 +3614,22 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ
 	<string name="texture_load_dimensions_error">
 		[WIDTH]*[HEIGHT] 以上の画像は読み込めません
 	</string>
+	<!-- overriding datetime formating. leave emtpy in for current localization this is not needed -->
+	<string name="dateTimeWeekdaysNames">
+	Sunday:Monday:Tuesday:Wednesday:Thursday:Friday:Saturday
+	</string>
+	<string name="dateTimeWeekdaysShortNames">
+	Son:Mon:Tue:Wed:Thu:Fri:Sat
+	</string>
+	<string name="dateTimeMonthNames">
+	January:February:March:April:May:June:July:August:September:October:November:December
+	</string>
+	<string name="dateTimeMonthNames">
+	Jan:Feb:Mar:Apr:May:Jun:Jul:Aug:Sep:Oct:Nov:Dec
+	</string>
+	<string name="dateTimeDayFormat">
+		[MDAY] D
+	</string>
+        <string name="dateTimeAM">AM</string>
+        <string name="dateTimePM">PM</string>
 </strings>
-- 
GitLab