\r
CTime GitRev::ConverFromString(CString input)\r
{\r
+ // pick up date from string\r
CTime tm(_wtoi(input.Mid(0,4)),\r
_wtoi(input.Mid(5,2)),\r
_wtoi(input.Mid(8,2)),\r
_wtoi(input.Mid(11,2)),\r
_wtoi(input.Mid(14,2)),\r
_wtoi(input.Mid(17,2)),\r
- _wtoi(input.Mid(20,4)));\r
+ 0);\r
+ // pick up utc offset\r
+ CString sign = input.Mid(20,1); // + or -\r
+ int hoursOffset = _wtoi(input.Mid(21,2));\r
+ int minsOffset = _wtoi(input.Mid(23,2));\r
+ if ( sign == "-" )\r
+ {\r
+ hoursOffset = -hoursOffset;\r
+ minsOffset = -minsOffset;\r
+ }\r
+ // make a timespan object with this value\r
+ CTimeSpan offset( 0, hoursOffset, minsOffset, 0 );\r
+ // we have to subtract this from the time given to get UTC\r
+ tm -= offset;\r
+ // get local timezone\r
+ SYSTEMTIME sysTime;\r
+ tm.GetAsSystemTime( sysTime );\r
+ TIME_ZONE_INFORMATION timeZone;\r
+ if ( GetTimeZoneInformation( &timeZone ) == TIME_ZONE_ID_UNKNOWN )\r
+ {\r
+ ASSERT(false);\r
+ }\r
+ else\r
+ {\r
+ SYSTEMTIME local;\r
+ if ( SystemTimeToTzSpecificLocalTime( &timeZone, &sysTime, &local ) )\r
+ {\r
+ sysTime = local;\r
+ }\r
+ else\r
+ {\r
+ ASSERT(false);\r
+ }\r
+ }\r
+ tm = CTime( sysTime, 0 );\r
return tm;\r
}\r
\r
/**\r
* FUNCTION : FormatDateAndTime\r
* DESCRIPTION : Generates a displayable string from a CTime object in\r
- * system short or long format dependant on setting of option\r
- * as DATE_SHORTDATE or DATE_LONGDATE\r
+ * system short or long format or as a relative value\r
+ * cTime - the time\r
+ * option - DATE_SHORTDATE or DATE_LONGDATE\r
+ * bIncluedeTime - whether to show time as well as date\r
+ * bRelative - if true then relative time is shown if reasonable \r
* If HKCU\Software\TortoiseGit\UseSystemLocaleForDates is 0 then use fixed format\r
* rather than locale\r
* RETURN : CString containing date/time\r
*/\r
-CString CAppUtils::FormatDateAndTime( const CTime& cTime, DWORD option, bool bIncludeTime /*=true*/ )\r
+CString CAppUtils::FormatDateAndTime( const CTime& cTime, DWORD option, bool bIncludeTime /*=true*/,\r
+ bool bRelative /*=false*/)\r
{\r
CString datetime;\r
- // should we use the locale settings for formatting the date/time?\r
- if (CRegDWORD(_T("Software\\TortoiseGit\\UseSystemLocaleForDates"), TRUE))\r
+ if ( bRelative )\r
{\r
- // yes\r
- SYSTEMTIME sysTime;\r
- cTime.GetAsSystemTime( sysTime );\r
- \r
- TCHAR buf[100];\r
- \r
- GetDateFormat(LOCALE_USER_DEFAULT, option, &sysTime, NULL, buf, \r
- sizeof(buf)/sizeof(TCHAR)-1);\r
- datetime = buf;\r
- if ( bIncludeTime )\r
- {\r
- datetime += _T(" ");\r
- GetTimeFormat(LOCALE_USER_DEFAULT, 0, &sysTime, NULL, buf, sizeof(buf)/sizeof(TCHAR)-1);\r
- datetime += buf;\r
- }\r
+ datetime = ToRelativeTimeString( cTime );\r
}\r
else\r
{\r
- // no, so fixed format\r
- if ( bIncludeTime )\r
+ // should we use the locale settings for formatting the date/time?\r
+ if (CRegDWORD(_T("Software\\TortoiseGit\\UseSystemLocaleForDates"), TRUE))\r
{\r
- datetime = cTime.Format(_T("%Y-%m-%d %H:%M:%S"));\r
+ // yes\r
+ SYSTEMTIME sysTime;\r
+ cTime.GetAsSystemTime( sysTime );\r
+ \r
+ TCHAR buf[100];\r
+ \r
+ GetDateFormat(LOCALE_USER_DEFAULT, option, &sysTime, NULL, buf, \r
+ sizeof(buf)/sizeof(TCHAR)-1);\r
+ datetime = buf;\r
+ if ( bIncludeTime )\r
+ {\r
+ datetime += _T(" ");\r
+ GetTimeFormat(LOCALE_USER_DEFAULT, 0, &sysTime, NULL, buf, sizeof(buf)/sizeof(TCHAR)-1);\r
+ datetime += buf;\r
+ }\r
}\r
else\r
{\r
- datetime = cTime.Format(_T("%Y-%m-%d"));\r
+ // no, so fixed format\r
+ if ( bIncludeTime )\r
+ {\r
+ datetime = cTime.Format(_T("%Y-%m-%d %H:%M:%S"));\r
+ }\r
+ else\r
+ {\r
+ datetime = cTime.Format(_T("%Y-%m-%d"));\r
+ }\r
}\r
}\r
return datetime;\r
}\r
+\r
+/**\r
+ * Converts a given time to a relative display string (relative to current time)\r
+ * Given time must be in local timezone\r
+ * If more than a year ago or in the future then normal date/time is shown\r
+ */\r
+CString CAppUtils::ToRelativeTimeString(CTime time)\r
+{\r
+ CString answer;\r
+ // convert to COleDateTime\r
+ SYSTEMTIME sysTime;\r
+ time.GetAsSystemTime( sysTime );\r
+ COleDateTime oleTime( sysTime );\r
+ answer = ToRelativeTimeString(oleTime, COleDateTime::GetCurrentTime());\r
+ // change this to return answer when happy\r
+ return CAppUtils::FormatDateAndTime( time, DATE_SHORTDATE) + " " + answer;\r
+}\r
+\r
+/**\r
+ * Generates a display string showing the relative time between the two given times as COleDateTimes\r
+ * time must be earlier than RelativeTo\r
+ * If more than a year ago or time > RelativeTo then an empty string is returned\r
+ */\r
+CString CAppUtils::ToRelativeTimeString(COleDateTime time,COleDateTime RelativeTo)\r
+{\r
+ CString answer;\r
+ COleDateTimeSpan ts = RelativeTo - time;\r
+ //years\r
+ if(fabs(ts.GetTotalDays()) >= 3*365)\r
+ {\r
+ answer .FormatMessage(_T("%1!d! Years ago"), (int)(ts.GetTotalDays()/365));\r
+ }\r
+ //Months\r
+ if(fabs(ts.GetTotalDays()) >= 60)\r
+ {\r
+ answer.FormatMessage( _T("%1!d! Months ago"), (int)(ts.GetTotalDays()/30) );\r
+ return answer;\r
+ }\r
+ //Weeks\r
+ if(fabs(ts.GetTotalDays()) >= 14)\r
+ {\r
+ answer.FormatMessage(_T("%1!d! Weeks ago"), (int)(ts.GetTotalDays()/7) );\r
+ return answer;\r
+ }\r
+ //Days\r
+ if(fabs(ts.GetTotalDays()) >= 2)\r
+ {\r
+ answer.FormatMessage(_T("%1!d! Days ago"), (int)(ts.GetTotalDays()) );\r
+ return answer;\r
+ }\r
+ //hours\r
+ if(fabs(ts.GetTotalHours()) >= 2)\r
+ {\r
+ answer.FormatMessage(_T("%1!d! Hours ago"), (int)(ts.GetTotalHours()) );\r
+ return answer;\r
+ }\r
+ //minutes\r
+ if(fabs(ts.GetTotalMinutes()) >= 2)\r
+ {\r
+ answer.FormatMessage(_T("%1!d! Minutes ago"), (int)(ts.GetTotalMinutes()) );\r
+ return answer;\r
+ }\r
+ //seconds\r
+ answer.FormatMessage(_T("%1!d! Seconds ago"), (int)(ts.GetTotalSeconds()) );\r
+ return answer;\r
+}\r
+\r
* as DATE_SHORTDATE or DATE_LONGDATE. bIncludeTime (optional) includes time.\r
* RETURN : CString containing date/time\r
*/\r
- static CString FormatDateAndTime( const CTime& cTime, DWORD option, bool bIncludeTime=true );\r
+ static CString FormatDateAndTime( const CTime& cTime, DWORD option, bool bIncludeTime=true,\r
+ bool bRelative=false );\r
+ /**\r
+ * Converts a given time to a relative display string (relative to current time)\r
+ * Given time must be in local timezone\r
+ * If more than a year ago or in the future then normal date/time is shown\r
+ */\r
+ static CString ToRelativeTimeString(CTime time);\r
\r
\r
private:\r
static CString PickDiffTool(const CTGitPath& file1, const CTGitPath& file2);\r
static bool GetMimeType(const CTGitPath& file, CString& mimetype);\r
+ /**\r
+ * Generates a display string showing the relative time between the two given times as COleDateTimes\r
+ * time must be earlier than RelativeTo\r
+ * If more than a year ago or time > RelativeTo then an empty string is returned\r
+ */\r
+ static CString ToRelativeTimeString(COleDateTime time,COleDateTime RelativeTo);\r
};\r