/** * @file XTPCalendarUtils.h * * @copyright * (c) 1998-2025 Codejock Software, All Rights Reserved. * * This source file is the property of Codejock Software and must not be * redistributed by any means without the explicit written permission of * Codejock Software. * * The use of this source code is governed by the terms and conditions specified * in the Toolkit Pro license agreement. Codejock Software grants you, as a * single software developer, the limited right to use this software on one * computer only. * * Contact Information: * support@codejock.com * http://www.codejock.com * */ #if !defined(__XTPCALENDARUTILS_H_) # define __XTPCALENDARUTILS_H_ # if _MSC_VER > 1000 # pragma once # endif // _MSC_VER > 1000 # include "Common/Base/Diagnostic/XTPDisableNoisyWarnings.h" /** * @details * Half a second, expressed in days. * * @see COleDateTime overview */ # define XTP_HALF_SECOND (1.0 / 172800.0) /** * @brief * Defines a lower bound of the time frame for the Calendar control. * @return A COLeDateTime const * @see xtpCalendarDateTime_max */ static const COleDateTime xtpCalendarDateTime_min(100, 1, 1, 0, 0, 0); /** * @brief * Defines an upper bound of the time frame for the Calendar control. * @return A COLeDateTime const * @see xtpCalendarDateTime_min */ static const COleDateTime xtpCalendarDateTime_max(9999, 12, 31, 0, 0, 0); class CXTPCalendarEvent; /** * @brief * Interface for overriding the GetCurrentTime() function in calendar control. * Allows a custom date-time to be set for calendar */ class ITimeProvider { public: // Handles object destruction virtual ~ITimeProvider() { } virtual COleDateTime GetCurrentTime() = 0; }; ////////////////////////////////////////////////////////////////////////// /** * @brief * This template function is used to compare operands using operator > * for the operands type and return compare result from the set: {-1, 0, 1}. * * @param e1 First operand to compare. * @param e2 Second operand to compare. * * @return 0 if e1 == e2; 1 if e1 > e2; -1 if e1 \< e2. */ template AFX_INLINE int XTPCompare(_Type e1, _Type e2) { if (e1 > e2) return 1; if (e2 > e1) return -1; return 0; } /** * @brief * Helper class with static member functions to perform common * tasks with dates, events and other objects. */ class _XTP_EXT_CLASS CXTPCalendarUtils { private: /** * @brief * Default constructor * * @details * Do not create an instance of this class. * Use CXTPCalendarUtils::MemberFunction form. */ CXTPCalendarUtils(); public: /** * @brief * This member function is used to retrieve information about a locale. * * @param LCType An LCTYPE that specifies the type of locale information to * retrieve. (for the LOCALE_USER_DEFAULT) * * @return Integer value that contains the information about the locale. * * @see GetLocaleInfo */ static int AFX_CDECL GetLocaleLong(LCTYPE LCType); /** * @brief * This member function is used to retrieve information about a locale. * * @param LCType An LCTYPE that specifies the type of locale information to * retrieve. (for the LOCALE_USER_DEFAULT) * @param nMaxLength An int that contains the maximum string size to * allocate for the corresponding buffer. * * @return String value. * * @see GetLocaleInfo */ static CString AFX_CDECL GetLocaleString(LCTYPE LCType, int nMaxLength = 128); /** * @brief * This member function is used to format a date as a date string * for a LOCALE_USER_DEFAULT locale. * * @param lpDate Pointer to a SYSTEMTIME structure that contains * the date information to be formatted. If this * pointer is NULL, the function uses the current * local system date. * @param lpFormat Pointer to a format picture string that is used * to form the date string. The format picture * string must be zero terminated. If lpFormat is * NULL, the function uses the date format of the * specified locale. * * @details * The function formats either a specified date or the local system date. * * @return A CString that contains the formatted date string. * * @see GetDateFormat */ static CString AFX_CDECL GetDateFormat(CONST SYSTEMTIME* lpDate, LPCTSTR lpFormat); /** * @brief * This member function is used to format a date as a date string * for a LOCALE_USER_DEFAULT locale. * * @param dtDate A date to be formatted. * @param lpFormat Pointer to a format picture string that is used * to form the date string. The format picture * string must be zero terminated. If lpFormat is * NULL, the function uses the date format of the * specified locale. * * @details * The function formats either a specified date or the local system date. * * @return A CString that contains the formatted date string. * * @see GetDateFormat */ static CString AFX_CDECL GetDateFormat(CONST COleDateTime& dtDate, LPCTSTR lpFormat); /** * @brief * This member function is used to format a time as a time string for * a LOCALE_USER_DEFAULT locale. * * @param lpTime Pointer to a SYSTEMTIME structure that contains the time * information to be formatted. If this pointer is NULL, the * function uses the current local system time. * @param lpFormat Pointer to a format picture string that is used to form the * time string. The format picture string must be zero * terminated. If lpFormat is NULL, the function uses the time * format of the specified locale. * * @details * The function formats either a specified time or the local system * time. * * @return A CString that contains the formatted time string. * * @see GetTimeFormat */ static CString AFX_CDECL GetTimeFormat(CONST SYSTEMTIME* lpTime, LPCTSTR lpFormat); /** * @brief * This member function is used to format a time as a time string for * a LOCALE_USER_DEFAULT locale. * * @param dtTime A time to be formatted. * @param lpFormat A pointer to a format picture string that is used to form the * time string. The format picture string must be zero * terminated. If lpFormat is NULL, the function uses the time * format of the specified locale. * * @details * The function formats either a specified time or the local system * time. * * @return A CString that contains the formatted time string. * * @see GetTimeFormat */ static CString AFX_CDECL GetTimeFormat(CONST COleDateTime& dtTime, LPCTSTR lpFormat); /** * @brief * This member function is used to format a time as a time string for * a LOCALE_USER_DEFAULT locale. * * @param nHour Hour of time to be formatted. * @param nMinutes Minutes of time to be formatted. * @param lpFormat Pointer to a format picture string that is used to form the * time string. The format picture string must be zero * terminated. If lpFormat is NULL, the function uses the time * format of the specified locale. * * @details * The function formats either a specified time or the local system * time. * * @return A CString that contains the formatted time string. * * @see GetTimeFormat // */ static CString AFX_CDECL GetTimeFormat(int nHour, int nMinutes, LPCTSTR lpFormat); /** * @brief * This member function is used to calculate the maximum month * day number for a specified Year and Month in the dtDate parameter. * * @param dtDate A COleDateTime date value. * * @return An int that contains the maximum month day number. (30, 31, 28, 29) */ static int AFX_CDECL GetMaxMonthDay(COleDateTime dtDate); /** * @brief * This member function is used to shift the specified date for * the specified number of months. * * @param refDate A reference to the COleDateTime object to shift * the date on. * @param nMonthCount An int that contains the number of months shifted. * Can be both positive and negative numbers. * * @details * This is a utility function that is used to shift the specified date * for the specific number of months. * * @return A BOOL. TRUE if the value of this COleDateTime object was set * successfully. FALSE otherwise. * * @see COleDateTime overview */ static BOOL AFX_CDECL ShiftDate_Month(COleDateTime& refDate, int nMonthCount); /** * @brief * This member function is used to shift the specified date for * the specified number of months. * * @param refDate A reference to the COleDateTime object to shift * the date on. * @param nMonthCount An int that contains the number of months shifted. * Can be both positive and negative numbers. * @param nMonthDay An int that contains the day of the month to set * for a resulting date. If nMonthDay is greater then the * maximum month day in the result month, then the maximum * possible day is set. * * @details * This is a utility function that is used to shift the specified date * for the specific number of months. * * @return A BOOL. TRUE if the value of this COleDateTime object was set * successfully. FALSE otherwise. * * @see COleDateTime overview */ static BOOL AFX_CDECL ShiftDate_Month(COleDateTime& refDate, int nMonthCount, int nMonthDay); /** * @brief * This member function is used to shift the specified date for the * specified number of years. * * @param refDate Reference to the COleDateTime object to shift the date on. * @param nYearCount An int that contains the number of years to shift. Can be both * positive and negative numbers. * * @details * This is a utility function that is used to shift the specified date * the specified number of years. * * @return A BOOL. TRUE if the value of this COleDateTime object is set * successfully. FALSE otherwise. * * @see COleDateTime overview */ static BOOL AFX_CDECL ShiftDate_Year(COleDateTime& refDate, int nYearCount); /** * @brief * This member function is used to shift the specified date for the * specified number of years. * * @param refDate Reference to the COleDateTime object to shift the date on. * @param nYearCount An int that contains the number of years to shift. Can be both * positive and negative numbers. * @param nMonthDay An int that contains the day of the month to set * for the resulting date. If nMonthDay is greater * then the maximum month day in the result month, * then the maximum possible day is set. * * @details * This is a utility function that is used to shift the specified date * the specified number of years. * * @return A BOOL. TRUE if the value of this COleDateTime object is set * successfully. FALSE otherwise. * * @see COleDateTime overview */ static BOOL AFX_CDECL ShiftDate_Year(COleDateTime& refDate, int nYearCount, int nMonthDay); /** * @brief * This member function is used to determine the number of minutes * between two DateTime objects. * * @param dtStart A COleDateTime object that contains the beginning * date. * @param dtEnd A COleDateTime object that contains the end date. * @param bAllDayEvent Calculate duration for all day event. * * @details * This is a utility function that is used to retrieve the number of * minutes between two COleDateTime objects. * * @return An int that contains the number of minutes between two DateTime * objects. */ static int AFX_CDECL GetDurationMinutes(const COleDateTime& dtStart, const COleDateTime& dtEnd, BOOL bAllDayEvent); /** * @brief * This member function is used to safely update a month day in * the specified date. * * @param refDate Reference to the COleDateTime object to shift * the date on. * @param nMonthDay An int that contains the day of the month to set * for the resulting date. * If nMonthDay is greater then the maximum month day in * the result month, then the maximum possible day is * set. * * @details * This is utility function is used to update the month day in the * specified date. * * @return A BOOL. TRUE if the value of this COleDateTime object was set * successfully. FALSE otherwise. * * @see COleDateTime overview */ static BOOL AFX_CDECL UpdateMonthDay(COleDateTime& refDate, int nMonthDay); /** * @brief * This member function is used to update the time part for the * specified DateTime value. * * @param dtDate A COleDateTime object that contains the value that * is used to update the time part. * @param nHour An int that contains the new Hour in the time part. * @param nMinutes An int that contains the new Minutes in the time part. * @param nSeconds An int that contains the new Seconds in the time part. * * @return A COleDateTime object that contains the updated time part. * * @see COleDateTime overview */ static const COleDateTime AFX_CDECL UpdateTime(const COleDateTime& dtDate, int nHour, int nMinutes, int nSeconds); /** * @brief * This member function is used to update the time part for the * specified DateTime value. * * @param dtDate A COleDateTime object that contains the value used * to update the time part. * @param dtTime A COleDateTime object that contains the new time part value. * * @return A COleDateTime object that contains the updated time part. * * @see COleDateTime overview */ static const COleDateTime AFX_CDECL UpdateTime(const COleDateTime& dtDate, const COleDateTime& dtTime); /** * @brief * This member function is used to update the time part to 23:59. * * @param dtDateTime A COleDateTime object that contains the value used * to update the time part. * * @return A COleDateTime object that contains the updated time part. * * @see COleDateTime overview */ static const COleDateTime AFX_CDECL SetTime_235959(const COleDateTime& dtDateTime); /** * @brief * This member function is used to update the date part of the * specified DateTime value. * * @param dtTime A COleDateTime object that contains the value used * to update the date part. * @param dtDate A COleDateTime object that contains the new date part. * * @return A COleDateTime object that contains the updated date part. * * @see COleDateTime overview */ static const COleDateTime AFX_CDECL UpdateDate(const COleDateTime& dtTime, const COleDateTime& dtDate); /** * @brief * This member function is used to update the date part of the * specified DateTime value. * * @param dtTime A COleDateTime object that contains the value used * to update the date part. * @param nYear An int that contains the new Year used in the date part. * @param nMonth An int that contains the new Minutes used in the the date part. * @param nDay An int that contains the new Day used in the date part. * * @return * A COleDateTime object that contains the updated date part. * * @see * COleDateTime overview */ static const COleDateTime AFX_CDECL UpdateDate(const COleDateTime& dtTime, int nYear, int nMonth, int nDay); /** * @brief * This member function is used to reset (set to zero) the time * part for the specified DateTime value. * * @param dtDateTime A COleDateTime object that contains the time value to reset. * * @return A COleDateTime object with the time part set equal to zero. * * @see COleDateTime overview */ static const COleDateTime AFX_CDECL ResetTime(const COleDateTime& dtDateTime); /** * @brief * This member function is used to reset (set to zero) the time * part for the specified DateTime value. * * @param dtDateTime A DATE object that contains the time value to reset. * * @return A COleDateTime object with the time part set equal to zero. * * @see COleDateTime overview */ static const COleDateTime AFX_CDECL ResetTime(const DATE dtDateTime); /** * @brief * This member function is used to reset (set to zero) the date * part for the specified DateTime value. * * @param dtDateTime A COleDateTime DateTime value that contains the * DateTime value to reset. * * @return A COleDateTime object with the date part set equal to zero. * * @see COleDateTime overview */ static const COleDateTime AFX_CDECL ResetDate(const COleDateTime& dtDateTime); /** * @brief * This member function is used to compare two dates (and times). * * @param dt1 A COleDateTime object that contains the first * DateTime value. * @param dt2 A COleDateTime object that contains the second * DateTime value. * @param bOneSecTimeDiff A BOOL. Used to set the precision of the compare operation. * If TRUE, then one second precision is used. * If FALSE, then half a second precision is used. * * @return A BOOL. TRUE if the dates differ by less than or equal to the specified * precision. FALSE otherwise. * * @see COleDateTime overview */ static BOOL AFX_CDECL IsEqual(const COleDateTime& dt1, const COleDateTime& dt2, BOOL bOneSecTimeDiff = FALSE); /** * @brief * This member function is used to determine if the time part is * equal to zero. * * @param dtDateTime A COleDateTime object that contains the value to check. * * @return A BOOL. TRUE if the time part is equal to zero. FALSE otherwise. * * @see COleDateTime overview */ static BOOL AFX_CDECL IsZeroTime(const COleDateTime& dtDateTime); /** * @brief * This member function is used to calculate differences between 2 dates * in months. * * @param dt1 A COleDateTime object that contains the first * DateTime value. * @param dt2 A COleDateTime object that contains the second * DateTime value. * * @return Months difference for dt1 - dt2. * * @see COleDateTime overview */ static int AFX_CDECL GetDiff_Months(const COleDateTime& dt1, const COleDateTime& dt2); /** * @brief * Get event end date (date part only) value. * * @param pEvent Event object. * * @details * Useful when end DateTime has a zero time part and/or event * start equal end. * * @return Date part of the event end DateTime. * * @see COleDateTime overview */ static COleDateTime AFX_CDECL RetriveEventEndDate(const CXTPCalendarEvent* pEvent); /** * @brief * Get event end date (date part only) value. * * @param dtStart Event start time. * @param dtEnd Event end time. * * @details * Useful when end DateTime has a zero time part and/or event * start equal end. * * @return Date part of the event end DateTime. * * @see COleDateTime overview */ static COleDateTime AFX_CDECL RetriveEventEndDate(const COleDateTime& dtStart, const COleDateTime& dtEnd); /** * @brief * Call this member function to get an event duration as a number * of days. * * @param dtStart Event start time. * @param dtEnd Event end time. * * @return Integer value of an event duration in days. * * @see CXTPCalendarEvent::GetDurationMinutes() * @see CXTPCalendarEvent::GetDuration() */ static int AFX_CDECL GetEventPeriodDays(const COleDateTime& dtStart, const COleDateTime& dtEnd); /** * @brief * This member function is used to calculate the day of the month * from the provided COleDateTime object. * * @param rdtDate A COleDateTime object that contains the date to * update with the valid year and month parts. * @param nWhichDay An int that contains the value from the enum * XTPCalendarWeek. This parameter specifies * the sequential number of the day. For example: * First Friday. * @param nWhichDayMask An int that contains the combination of values * from the enums XTPCalendarWeekDay or the * XTPCalendarWeekDay. This parameter, together * with the nWhichDay parameter are used to * specify the following logical values: * Which Day of Month, Which WeekDay, * Which WeekEndDay, Which day of week * Su, Mo, ..., St. For example: Last day of Month, * Second WeekEndDay, Fourth Monday. * * @return A BOOL. TRUE if the value of this COleDateTime object was set * successfully. FALSE otherwise. */ static BOOL AFX_CDECL CalcDayOfMonth(COleDateTime& rdtDate, int nWhichDay, int nWhichDayMask); /** * @brief * This member function is used to convert a sequential week day * number (from 1 to 7) to a value from the enum XTPCalendarWeekDay. * * @param nWeekDay An int that contains the sequential week day number. * 1-Sunday, 2-Monday, ... * * @return An int that contains the corresponding value from the enum * XTPCalendarWeekDay. * * @see GetDayOfWeekIndex * @see XTPCalendarWeekDay * enum */ static int AFX_CDECL GetDayOfWeekMask(int nWeekDay); /** * @brief * This member function is used to convert an XTPCalendarWeekDay * enum value to a sequential week day number (from 1 to 7). * * @param nDayOfWeekMask An int that contains the value from the enum * XTPCalendarWeekDay. * * @return An int that contains the sequential week day number. * 1-Sunday, 2-Monday, ... * * @see GetDayOfWeekMask * @see XTPCalendarWeekDay * enum */ static int AFX_CDECL GetDayOfWeekIndex(int nDayOfWeekMask); /** * @brief * This member function is used to count the bits in the specified * bit mask. * * @param nDayOfWeekMask An int that contains the mask from the enum * XTPCalendarWeekDay. * * @return An int that contains the integer value of the day of the week * contained in the bit mask. * * @see GetDayOfWeekMask * @see XTPCalendarWeekDay * enum */ static int AFX_CDECL GetDayOfWeekCount(int nDayOfWeekMask); /** * @brief * Obtains locale string ID for a week day specified. * * @param nWeekDay An int that contains the sequential week day number. * 1-Sunday, 2-Monday, ... * * @return Locale string ID for a week day specified. * * @see GetDayOfWeekIndex * @see XTPCalendarWeekDay * enum */ static int AFX_CDECL GetDayOfWeekLocaleStringId(int nWeekDay); /** * @brief * This member function is used to make the days mask from Monday * until the specified day. * * @param nEndWDay An int that contains the sequential week day number. * 1-Sunday, 2-Monday, ... * * @return An int that contains the values set from the enum XTPCalendarWeekDay. * * @see GetDayOfWeekIndex * @see XTPCalendarWeekDay * enum */ static int AFX_CDECL MakeDaysOfWeekMask_Mo_(int nEndWDay); /** * @brief * This member function is used to shift the specified date to * the beginning of the week. * * @param dtDate A COleDateTime object that contains the value * to shift to the beginning of the week. * @param nFirstDayOfWeekIndex Index of the first day of week. Default value 1. * 1-Sunday, 2-Monday, ... * * @return * A COleDateTime object that contains the date of the first day of week * before the specified date. * * @see COleDateTime overview */ static COleDateTime AFX_CDECL ShiftDateToWeekBegin(COleDateTime dtDate, int nFirstDayOfWeekIndex = 1); /** * @brief * This member function is used to calculate a week number of year. * * @param dtDate A COleDateTime object that contains the date * to calculate the week of year. * @param nFirstDayOfWeekIndex Index of the first day of week. Default value 1. * 1-Sunday, 2-Monday, ... * * @return A week number of year for the specified date. * * @see COleDateTime overview */ static int AFX_CDECL GetWeekOfYear(COleDateTime dtDate, int nFirstDayOfWeekIndex = 1); /** * @brief * The SystemTimeToTzSpecificLocalTime function converts a time in * Coordinated Universal Time (UTC) to a specified time zone's * corresponding local time. * * @param pTZI [in] Pointer to a TIME_ZONE_INFORMATION structure * that specifies the time zone of interest. * @param pUTime [in] Pointer to a SYSTEMTIME structure that specifies * a UTC. The function converts this universal time to * the specified time zone's corresponding local time. * @param pTzTime [out] Pointer to a SYSTEMTIME structure that receives * the local time information. * * @return If the function succeeds, the return value is nonzero, * and the function sets the members of the SYSTEMTIME structure * pointed to by pTzTime to the appropriate local time values. * * @see SystemTimeToTzSpecificLocalTime() * windows API function. */ static BOOL AFX_CDECL SystemTimeToTzSpecificLocalTime(const TIME_ZONE_INFORMATION* pTZI, const SYSTEMTIME* pUTime, SYSTEMTIME* pTzTime); /** * @brief * This function is used to determine if the program is running on * Windows 9x operation system family. * * @return TRUE for Windows 9x operation system, otherwise FALSE. */ static BOOL AFX_CDECL IsWin9x(); /** * @brief * Converts a number of minutes into its corresponding COleDateTimeSpan * object. * * @param nMinutes A number of minutes in the time span. * * @return Calculated COleDateTimeSpan object. */ static COleDateTimeSpan AFX_CDECL Minutes2Span(int nMinutes); private: static ITimeProvider* g_TimeProviderOverride; public: /** * @brief * Returns current local time. * * @return COleDateTime object with the calculated local time value. */ static COleDateTime AFX_CDECL GetCurrentTime(); /** * @brief * Overrides the local time provider with the custom provider. The date-time returned * by the custom provider will be used as the current time for calendar control. * All calls to CXTPCalendarUtils::GetCurrentTime() from within calendar control will be * routed to custom provider. * @param pTimeProvider A new time provider interface pointer. * * @return A pointer to an instance of custom time provider. The instance must remain until the * time provider is reset by a ResetTimeProvider() call. The caller should free provider * instance memory after a ResetTimeProvider() call. */ static void AFX_CDECL OverrideTimeProvider(ITimeProvider* pTimeProvider); /** * @brief * Resets time provider to default which will use the current machine date time. * @return void */ static void AFX_CDECL ResetTimeProvider(); /** * @brief * Returns current time format string for hours and minutes. * * @return A time format string like: 'HH:mm', 'hh:mm tt', 'h:m t', ... */ static CString AFX_CDECL GetTimeFormatString_HrMin(); /** * @brief * Parse a time string like "18:20" or "7:15 pm" and returns time * as total minutes. Active locale setting are used. * * @param pcszTime_HrMin time string like "18:20" or "7:15 pm". * * @return Time as total minutes. */ static int AFX_CDECL ParceTimeString_min(LPCTSTR pcszTime_HrMin); /** * @brief * Format time duration like "3 minutes" or "1 week". * Active locale setting are used. * @param nMinutes Duration in minutes. * @param bRoundly If TRUE duration will be rounded to biggest scale, * like 65 minutes will be formatted as "1 hour". * If False duration will formatted exactly: * 65 minutes as "65 minutes; 120 minutes as "2 hours". * @return Time duration as string like "5 minutes", "2 hours", "1 day", "3 weeks". */ static CString AFX_CDECL FormatTimeDuration(int nMinutes, BOOL bRoundly); /** * @brief * Parse a time duration string like "5 minutes", "2 hours", "1 day" * or "3 weeks" and returns duration as total minutes. * Active locale setting are used. * * @param pcszTimeDuration time duration string like "5 minutes", "2 hours". * * @return Time duration as total minutes. */ static int AFX_CDECL ParceTimeDuration_min(LPCTSTR pcszTimeDuration); /** * @brief * Loads string using XTPResourceManager. * * @param nIDResource ID of the string in the resource. * * @return Loaded string or an empty string. */ static CString AFX_CDECL LoadString(UINT nIDResource); /** * @brief * Loads string using XTPResourceManager. * * @param nIDResource ID of the string in resource. * @param rstrString [out] Reference to CString object to load string to. * * @details * If string with such ID is not present in the resource - rstrString * is not changed. * * @return TRUE if string loaded, FALSE otherwise. */ static BOOL AFX_CDECL LoadString2(CString& rstrString, UINT nIDResource); /** * @brief * Prepares a string for single line display. * * @param rstrString [out] Reference to CString object to update. * * @details * Removes from the string not visible characters which are valid * for multiline display, but not valid for singleline. * Examples: '\n'. * @return void * * @see DT_SINGLELINE */ static void AFX_CDECL TextPrepareSingleline(CString& rstrString); /** * @brief * Returns active locale ID (current user locale or resource file locale). * * @return LOCALE_USER_DEFAULT or resource file locale ID. * * @see CXTPResourceManager::GetResourcesLangID * @see LOCALE_USER_DEFAULT */ static LCID AFX_CDECL GetActiveLCID(); /** * @brief * This function is used to determine a font with maximum symbols height * in an array of fonts. * * @param arFonts [in] A reference to an array of fonts. * @param pDC [in] A pointer to a valid device context or NULL. * @param pnMaxHeight [out] A pointer to an int variable to store maximum font * height or NULL. * * @details * If pDC is not NULL - the font height in device logical units is used. * Otherwise the LOGFONT.lfHeight member is used as font height. * * @return A font from the provided array with maximum symbols height. */ static CFont* AFX_CDECL GetMaxHeightFont(CArray& arFonts, CDC* pDC, int* pnMaxHeight = NULL); /** * @brief * Call this function to check if a character is a format character * (Mm Dd Yy). * * @param t character. * * @return TRUE if the input character is a format character, FALSE otherwise. */ static BOOL AFX_CDECL IsFormatChar(TCHAR t); /** * @brief * Call this function to remove a portion from the time format part (Mm Dd Yy). * * @param strFormat The format string. * @param lpszRemove String to remove. * * @return The new string. */ static CString AFX_CDECL RemoveFormatPart(CString strFormat, LPCTSTR lpszRemove); /** * @brief * Call this function to remove a character from the time format part (Mm Dd Yy). * * @param strFormat The format string. * @param cRemove TRUE to remove. * * @return The new string. */ static CString AFX_CDECL RemoveFormatPart(CString strFormat, TCHAR cRemove); /** * @brief * This function removes a fixed number of characters from the format * string, starting at a particular index. * * @param strFormat The format string. * @param nIndex Starting index. * @param nRemove The number of characters to remove. * @return void */ static void AFX_CDECL StripFormat(CString& strFormat, int nIndex, int nRemove); // {{AFX_CODEJOCK_PRIVATE _XTP_DEPRECATED_MSG("Resource file locale is enforced to use by default") static BOOL AFX_CDECL IsUseResourceFileLocale(); _XTP_DEPRECATED_MSG("Resource file locale is enforced to use by default") static void AFX_CDECL SetUseResourceFileLocale(BOOL bUseResourceFileLocale); // }}AFX_CODEJOCK_PRIVATE private: static BOOL AFX_CDECL IsInDst(const TIME_ZONE_INFORMATION* pTZI, COleDateTime dtTime); struct CXTPTimesResourceIDs { typedef CMap CMapInt2UINT; CMapInt2UINT s_mapMinutes; CMapInt2UINT s_mapHours; CMapInt2UINT s_mapDays; CMapInt2UINT s_mapWeeks; CXTPTimesResourceIDs(); }; public: /** * @brief * This function is used to round date time values by adding (or subtracting) * a half-second double value. * * @param dblDT [in] A date time value in COLEDateTime double representation. * * @return Rounded date time value in COLEDateTime double representation. */ static double AFX_CDECL _RoundDateTime_dbl(double dblDT); /** * @brief * This function is used to reset the time part. * * @param dblDT [in] A date time value in COLEDateTime double representation. * * @return Date value (with zero time) in COLEDateTime double representation. */ static double AFX_CDECL _ResetTime_dbl(double dblDT); /** * @brief * This function used is to reset the date part. * * @param dblDT [in] A date time value in COLEDateTime double representation. * * @return Time value (with zero date) in COLEDateTime double representation. */ static double AFX_CDECL _ResetDate_dbl(double dblDT); public: /** * @brief * The TrackMouseEvent function posts messages when the mouse pointer leaves a window or * hovers over a window for a specified amount of time. * * @param dwFlags Specifies the services requested. * @param hwndTrack Specifies a handle to the window to track. * @param dwHoverTime Specifies the hover time-out (if TME_HOVER was specified in dwFlags), * in milliseconds. * Can be HOVER_DEFAULT, which means to use the system default hover * time-out. * * @return If the function succeeds, the return value is nonzero. */ static BOOL AFX_CDECL TrackMouseEvent(DWORD dwFlags, HWND hwndTrack, DWORD dwHoverTime = HOVER_DEFAULT); /** * @brief * This function return number of days of the new year in the first week of this year. * * @return Number of days of the new year in the first week of this year. */ static int AFX_CDECL GetFirstWeekOfYearDays(); public: static BOOL AFX_CDECL GetAsSystemTime(const COleDateTime& dtTime, SYSTEMTIME& sysTime); static LONG AFX_CDECL GetTotalDays(const COleDateTimeSpan& spSpan); static LONG AFX_CDECL GetTotalHours(const COleDateTimeSpan& spSpan); static LONG AFX_CDECL GetTotalMinutes(const COleDateTimeSpan& spSpan); static LONG AFX_CDECL GetTotalSeconds(const COleDateTimeSpan& spSpan); static LONG AFX_CDECL _DoubleToLONG(double dValue); }; AFX_INLINE BOOL AFX_CDECL CXTPCalendarUtils::IsUseResourceFileLocale() { return TRUE; } AFX_INLINE void AFX_CDECL CXTPCalendarUtils::SetUseResourceFileLocale(BOOL bUseResourceFileLocale) { UNREFERENCED_PARAMETER(bUseResourceFileLocale); } //=========================================================================== /** * @brief * Helper class template provides functionality to temporary set some * to variable and reset to initial or other value on destroy. * Can be useful to lock some data or actions via flags and unlock * automatically. */ template class CXTPAutoResetValue { _TValue m_valReset; _TValue& m_rData; public: /** * @brief * Object constructor. * * @param rData A reference to the managing variable. * * @details * The original value of rData is stored in a separate member and it * will be restored on destroy. */ CXTPAutoResetValue(_TValue& rData) : m_rData(rData) { m_valReset = rData; } /** * @brief * Object constructor. * * @param rData A reference to the managing variable. * @param valReset A value to set when destroyed. * * @details * The original value of rData is ignored. * The valReset value will be used on destroy. */ CXTPAutoResetValue(_TValue& rData, const _TValue& valReset) : m_rData(rData) { m_valReset = valReset; } /** * @brief * Object destructor. * * @details * The managing variable value will be restored to its original value or to * a value specified as the second constructor parameter. */ virtual ~CXTPAutoResetValue() { m_rData = m_valReset; } /** * @brief * This member operator is used to access the managing variable. * * @return Managing variable reference. */ operator _TValue&() { return m_rData; } /** * @brief * This member function overloads the assignment operator for the * CXTPAutoResetValue class. * * @param rSrc A new value. * * @return A reference to this object. */ const _TValue& operator=(const _TValue& rSrc) { return m_rData = rSrc; } }; ///////////////////////////////////////////////////////////////////////////// AFX_INLINE double CXTPCalendarUtils::_RoundDateTime_dbl(double dblDT) { return (dblDT >= 0 ? dblDT + XTP_HALF_SECOND : dblDT - XTP_HALF_SECOND); } AFX_INLINE double CXTPCalendarUtils::_ResetTime_dbl(double dblDT) { return (double)((LONGLONG)_RoundDateTime_dbl(dblDT)); } AFX_INLINE double CXTPCalendarUtils::_ResetDate_dbl(double dblDT) { double dblDate = _ResetTime_dbl(dblDT); double dblResult = dblDT > dblDate ? (dblDT - dblDate) : (dblDate - dblDT); double dblDate_raw = (double)((LONGLONG)dblDT); if (dblDate_raw != dblDate) { dblResult = _RoundDateTime_dbl(dblResult); } return dblResult; } AFX_INLINE const COleDateTime CXTPCalendarUtils::ResetTime(const COleDateTime& dtDateTime) { return (DATE)_ResetTime_dbl((double)dtDateTime); } AFX_INLINE const COleDateTime CXTPCalendarUtils::ResetTime(const DATE dtDateTime) { return (DATE)_ResetTime_dbl((double)dtDateTime); } AFX_INLINE const COleDateTime CXTPCalendarUtils::ResetDate(const COleDateTime& dtDateTime) { return (DATE)_ResetDate_dbl((double)dtDateTime); } AFX_INLINE const COleDateTime CXTPCalendarUtils::SetTime_235959(const COleDateTime& dtDateTime) { double dDate = _ResetTime_dbl((double)dtDateTime); return (DATE)(dDate + 1 - XTP_HALF_SECOND * 2); } AFX_INLINE int CXTPCalendarUtils::GetDayOfWeekMask(int nWeekDay) { _ASSERTE(nWeekDay >= 1 && nWeekDay <= 7); int nRes = 1 << (nWeekDay - 1); return nRes; } // return 1 = Sunday, 2 = Monday ... AFX_INLINE int CXTPCalendarUtils::GetDayOfWeekIndex(int nDayOfWeekMask) { // int nTestMask[7]; // for (int i = 1; i <= 7; i++) //{ // nTestMask[i - 1] = 1 << (i-1); //} // this loop fill array {1,2,4,8,16,32,64} // by enum XTPCalendarWeekDay // xtpCalendarDaySunday = 0x001, // Sunday // xtpCalendarDayMonday = 0x002, // Monday // xtpCalendarDayTuesday = 0x004, // Tuesday // xtpCalendarDayWednesday = 0x008, // Wednesday // xtpCalendarDayThursday = 0x010, // Thursday // xtpCalendarDayFriday = 0x020, // Friday // xtpCalendarDaySaturday = 0x040, // Saturday for (int i = 1; i <= 7; i++) { // if (nTestMask[i-1] == nDayOfWeekMask) int nTestMask = 1 << (i - 1); if (nTestMask == nDayOfWeekMask) { return i; } } _ASSERTE(FALSE); return 0; } AFX_INLINE int CXTPCalendarUtils::GetMaxMonthDay(COleDateTime dtDate) { SYSTEMTIME sysDate; if (!CXTPCalendarUtils::GetAsSystemTime(dtDate, sysDate)) return 0; // days per month - _ jan feb mar apr may jun jul aug sep oct nov dec static int arDays[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; if (sysDate.wMonth == 2 && sysDate.wYear % 4 == 0) { if (sysDate.wYear % 100 != 0 || sysDate.wYear % 400 == 0) return 29; else return 28; } else { return arDays[sysDate.wMonth]; } } AFX_INLINE BOOL CXTPCalendarUtils::UpdateMonthDay(COleDateTime& refDate, int nMonthDay) { if (nMonthDay > 28) { int nMaxDay = GetMaxMonthDay(refDate); if (!nMaxDay) { return FALSE; } nMonthDay = min(nMonthDay, nMaxDay); } SYSTEMTIME sysDate; if (!CXTPCalendarUtils::GetAsSystemTime(refDate, sysDate)) return FALSE; int nRes = refDate.SetDate(sysDate.wYear, sysDate.wMonth, nMonthDay); return nRes == 0; } /* AFX_INLINE BOOL CXTPCalendarUtils::ShiftDate_Month(COleDateTime &refDate, int nMonthCount) { int nYearOld = refDate.GetYear(); int nMonthOld = refDate.GetMonth(); int nYearNew = nYearOld + (-12 + nMonthOld + nMonthCount) / 12; int nMonthCalc = nMonthOld + nMonthCount - 1; if (nMonthCalc < 0) nMonthCalc = 12 * (-nMonthCalc) + nMonthCalc; int nMonthNew = 1 + nMonthCalc % 12; return COleDateTime::valid == refDate.SetDate(nYearNew, nMonthNew, 1); } */ AFX_INLINE BOOL CXTPCalendarUtils::ShiftDate_Month(COleDateTime& refDate, int nMonthCount) { SYSTEMTIME sysDate; if (!CXTPCalendarUtils::GetAsSystemTime(refDate, sysDate)) return FALSE; int nYearNew = sysDate.wYear + nMonthCount / 12; int nMonthNew = sysDate.wMonth + nMonthCount % 12; if (nMonthNew > 12) { nMonthNew -= 12 * (nMonthCount / abs(nMonthCount)); nYearNew++; } else if (nMonthNew <= 0) { nYearNew--; nMonthNew += 12; _ASSERTE(nMonthNew >= 1 && nMonthNew <= 12); } return COleDateTime::valid == refDate.SetDate(nYearNew, nMonthNew, 1); } AFX_INLINE BOOL CXTPCalendarUtils::ShiftDate_Month(COleDateTime& refDate, int nMonthCount, int nMonthDay) { if (ShiftDate_Month(refDate, nMonthCount)) { BOOL bRes = UpdateMonthDay(refDate, nMonthDay); return bRes; } return FALSE; } AFX_INLINE BOOL CXTPCalendarUtils::ShiftDate_Year(COleDateTime& refDate, int nYearCount) { SYSTEMTIME sysDate; if (!CXTPCalendarUtils::GetAsSystemTime(refDate, sysDate)) { return FALSE; } int nYearNew = sysDate.wYear + nYearCount; return COleDateTime::valid == refDate.SetDate(nYearNew, sysDate.wMonth, 1); } AFX_INLINE BOOL CXTPCalendarUtils::ShiftDate_Year(COleDateTime& refDate, int nYearCount, int nMonthDay) { if (ShiftDate_Year(refDate, nYearCount)) { BOOL bRes = UpdateMonthDay(refDate, nMonthDay); return bRes; } return FALSE; } AFX_INLINE int CXTPCalendarUtils::GetDiff_Months(const COleDateTime& dt1, const COleDateTime& dt2) { int nYear1 = dt1.GetYear(); int nMonth1 = dt1.GetMonth(); int nYear2 = dt2.GetYear(); int nMonth2 = dt2.GetMonth(); int nYearDiff = nYear1 - nYear2; int nMonthDiff = nYearDiff * 12; nMonthDiff += nMonth1 - nMonth2; return nMonthDiff; } AFX_INLINE int CXTPCalendarUtils::GetDurationMinutes(const COleDateTime& dtStart, const COleDateTime& dtEnd, BOOL bAllDayEvent) { COleDateTimeSpan spDuration; if (bAllDayEvent) { spDuration = SetTime_235959(dtEnd) - ResetTime(dtStart); } else { spDuration = dtEnd - dtStart; } return (int)CXTPCalendarUtils::GetTotalMinutes(spDuration); } AFX_INLINE const COleDateTime CXTPCalendarUtils::UpdateTime(const COleDateTime& dtDate, int nHour, int nMinutes, int nSeconds) { SYSTEMTIME stResult; if (!CXTPCalendarUtils::GetAsSystemTime(dtDate, stResult)) { _ASSERTE(FALSE); return dtDate; } stResult.wHour = (WORD)nHour; stResult.wMinute = (WORD)nMinutes; stResult.wSecond = (WORD)nSeconds; return COleDateTime(stResult); } AFX_INLINE const COleDateTime CXTPCalendarUtils::UpdateTime(const COleDateTime& dtDate, const COleDateTime& dtTime) { double dDate = _ResetTime_dbl((double)dtDate); double dTime = _ResetDate_dbl((double)dtTime); return (DATE)(dDate + dTime); } AFX_INLINE const COleDateTime CXTPCalendarUtils::UpdateDate(const COleDateTime& dtTime, int nYear, int nMonth, int nDay) { SYSTEMTIME stResult; if (!CXTPCalendarUtils::GetAsSystemTime(dtTime, stResult)) { _ASSERTE(FALSE); return dtTime; } stResult.wYear = (WORD)nYear; stResult.wMonth = (WORD)nMonth; stResult.wDay = (WORD)nDay; return COleDateTime(stResult); } AFX_INLINE const COleDateTime CXTPCalendarUtils::UpdateDate(const COleDateTime& dtTime, const COleDateTime& dtDate) { double dDate = _ResetTime_dbl((double)dtDate); double dTime = _ResetDate_dbl((double)dtTime); return (DATE)(dDate + dTime); } AFX_INLINE COleDateTime CXTPCalendarUtils::RetriveEventEndDate(const COleDateTime& dtStart, const COleDateTime& dtEnd) { COleDateTime dtEndDay = ResetTime(dtEnd); if (IsZeroTime(dtEnd)) { COleDateTime dtStartDay = ResetTime(dtStart); if (dtStartDay < dtEndDay) { const COleDateTimeSpan spDay(1, 0, 0, 0); dtEndDay -= spDay; } } return dtEndDay; } AFX_INLINE int CXTPCalendarUtils::GetEventPeriodDays(const COleDateTime& dtStart, const COleDateTime& dtEnd) { COleDateTime dtStartDay = ResetTime(dtStart); COleDateTime dtEndDay = RetriveEventEndDate(dtStart, dtEnd); COleDateTimeSpan spDuration = dtEndDay - dtStartDay; int nDays = (int)CXTPCalendarUtils::GetTotalDays(spDuration) + 1; return nDays; } AFX_INLINE COleDateTimeSpan CXTPCalendarUtils::Minutes2Span(int nMunutes) { double dblSpan = ((double)nMunutes) / (24 * 60); return COleDateTimeSpan(dblSpan); } AFX_INLINE COleDateTime CXTPCalendarUtils::ShiftDateToWeekBegin(COleDateTime dtDate, int nFirstDayOfWeekIndex) { dtDate = CXTPCalendarUtils::ResetTime(dtDate); int nShift = (dtDate.GetDayOfWeek() - nFirstDayOfWeekIndex + 7) % 7; if (nShift) { COleDateTimeSpan spShift(nShift, 0, 0, 0); dtDate -= spShift; } return dtDate; } AFX_INLINE int CXTPCalendarUtils::GetDayOfWeekCount(int nDayOfWeekMask) { int nCount = 0; for (int i = 1; i <= 7; i++) { int nTestMask = 1 << (i - 1); if (nTestMask & nDayOfWeekMask) { nCount++; } } return nCount; } AFX_INLINE int CXTPCalendarUtils::MakeDaysOfWeekMask_Mo_(int nEndWDay) { int nMask = 0; for (int i = 1; i < nEndWDay; i++) { int nWDMask = CXTPCalendarUtils::GetDayOfWeekMask(i); nMask |= nWDMask; } return nMask; } AFX_INLINE BOOL CXTPCalendarUtils::GetAsSystemTime(const COleDateTime& dtTime, SYSTEMTIME& sysTime) { ::ZeroMemory(&sysTime, sizeof(sysTime)); return dtTime.GetAsSystemTime(sysTime); } AFX_INLINE LONG CXTPCalendarUtils::GetTotalDays(const COleDateTimeSpan& spSpan) { return (LONG)spSpan.GetTotalDays(); } AFX_INLINE LONG CXTPCalendarUtils::GetTotalHours(const COleDateTimeSpan& spSpan) { return (LONG)spSpan.GetTotalHours(); } AFX_INLINE LONG CXTPCalendarUtils::_DoubleToLONG(double dValue) { return LONG(dValue > 0 ? min(dValue, double(LONG_MAX)) : max(dValue, double(LONG_MIN))); } AFX_INLINE LONG CXTPCalendarUtils::GetTotalMinutes(const COleDateTimeSpan& spSpan) { double dSpan = _RoundDateTime_dbl(spSpan); double dMinutes = dSpan * 24 * 60; LONG nMinutes = _DoubleToLONG(dMinutes); return nMinutes; } AFX_INLINE LONG CXTPCalendarUtils::GetTotalSeconds(const COleDateTimeSpan& spSpan) { double dSpan = _RoundDateTime_dbl(spSpan); double dSeconds = dSpan * 24 * 60 * 60; LONG nSeconds = _DoubleToLONG(dSeconds); return nSeconds; } ///////////////////////////////////////////////////////////////////////////// # include "Common/Base/Diagnostic/XTPEnableNoisyWarnings.h" #endif // !defined(__XTPCALENDARUTILS_H_)