mux/src/timeutil.cpp File Reference

#include "copyright.h"
#include "autoconf.h"
#include "config.h"
#include "externs.h"
#include <time.h>
#include "timeutil.h"
#include "stringutil.h"

Include dependency graph for timeutil.cpp:

Go to the source code of this file.

Data Structures

struct  OffsetEntry
struct  tag_pd_node
struct  tag_pd_breakdown
struct  tag_AllFields
struct  tag_pd_numeric_valid
struct  PD_TEXT_ENTRY
struct  tag_pd_cantbe

Defines

#define PFSS_PRECISION   7
#define MAX_OFFSETS   50
#define PDTT_SYMBOL   1
#define PDTT_NUMERIC_UNSIGNED   2
#define PDTT_SPACES   3
#define PDTT_TEXT   4
#define PDTT_NUMERIC_SIGNED   5
#define PDCB_NOTHING   0x00000000
#define PDCB_TIME_FIELD_SEPARATOR   0x00000001
#define PDCB_DATE_FIELD_SEPARATOR   0x00000002
#define PDCB_WHITESPACE   0x00000004
#define PDCB_DAY_OF_MONTH_SUFFIX   0x00000008
#define PDCB_SIGN   0x00000010
#define PDCB_SECONDS_DECIMAL   0x00000020
#define PDCB_REMOVEABLE   0x00000040
#define PDCB_YEAR   0x00000080
#define PDCB_MONTH   0x00000100
#define PDCB_DAY_OF_MONTH   0x00000200
#define PDCB_DAY_OF_WEEK   0x00000400
#define PDCB_WEEK_OF_YEAR   0x00000800
#define PDCB_DAY_OF_YEAR   0x00001000
#define PDCB_YD   0x00002000
#define PDCB_YMD   0x00004000
#define PDCB_MDY   0x00008000
#define PDCB_DMY   0x00010000
#define PDCB_DATE_TIME_SEPARATOR   0x00020000
#define PDCB_TIMEZONE   0x00040000
#define PDCB_WEEK_OF_YEAR_PREFIX   0x00080000
#define PDCB_MERIDIAN   0x00100000
#define PDCB_MINUTE   0x00200000
#define PDCB_SECOND   0x00400000
#define PDCB_SUBSECOND   0x00800000
#define PDCB_HOUR_TIME   0x01000000
#define PDCB_HMS_TIME   0x02000000
#define PDCB_HOUR_TIMEZONE   0x04000000
#define PDCB_HMS_TIMEZONE   0x08000000
#define NOT_PRESENT   -9999999
#define PD_LEX_INVALID   0
#define PD_LEX_SYMBOL   1
#define PD_LEX_DIGIT   2
#define PD_LEX_SPACE   3
#define PD_LEX_ALPHA   4
#define PD_LEX_EOS   5
#define MAX_NODES   200
#define PDCB_SEPS   (PDCB_YEAR|PDCB_MONTH|PDCB_DAY_OF_MONTH|PDCB_DAY_OF_YEAR|PDCB_WEEK_OF_YEAR|PDCB_DAY_OF_WEEK)
#define PDCB_SIGNABLES_POS   (PDCB_HMS_TIME|PDCB_HMS_TIMEZONE)
#define PDCB_SIGNABLES_NEG   (PDCB_YEAR|PDCB_YD|PDCB_SIGNABLES_POS|PDCB_YMD)

Typedefs

typedef tag_pd_node PD_Node
typedef void BREAK_DOWN_FUNC (PD_Node *pNode)
typedef tag_pd_breakdown PD_BREAKDOWN
typedef tag_AllFields ALLFIELDS
typedef bool PVALIDFUNC (size_t nStr, char *pStr, int iValue)
typedef tag_pd_numeric_valid NUMERIC_VALID_RECORD
typedef tag_pd_cantbe PD_CANTBE

Functions

int iMod (int x, int y)
INT64 i64Mod (INT64 x, INT64 y)
DCL_INLINE int iRemainder (int x, int y)
DCL_INLINE int iDivision (int x, int y)
static int iFloorDivision (int x, int y)
INT64 i64FloorDivision (INT64 x, INT64 y)
int iFloorDivisionMod (int x, int y, int *piMod)
static INT64 i64FloorDivisionMod (INT64 x, INT64 y, INT64 *piMod)
static void GetUTCLinearTime (INT64 *plt)
bool operator< (const CLinearTimeAbsolute &lta, const CLinearTimeAbsolute &ltb)
bool operator> (const CLinearTimeAbsolute &lta, const CLinearTimeAbsolute &ltb)
bool operator== (const CLinearTimeAbsolute &lta, const CLinearTimeAbsolute &ltb)
bool operator== (const CLinearTimeDelta &lta, const CLinearTimeDelta &ltb)
bool operator!= (const CLinearTimeDelta &lta, const CLinearTimeDelta &ltb)
bool operator<= (const CLinearTimeDelta &lta, const CLinearTimeDelta &ltb)
bool operator<= (const CLinearTimeAbsolute &lta, const CLinearTimeAbsolute &ltb)
CLinearTimeAbsolute operator- (const CLinearTimeAbsolute &lta, const CLinearTimeDelta &ltd)
static bool ParseFractionalSecondsString (INT64 &i64, char *str)
static void ConvertToSecondsString (char *buffer, INT64 n64, int nFracDigits)
bool isLeapYear (long iYear)
static bool isValidDate (int iYear, int iMonth, int iDay)
static int FixedFromGregorian (int iYear, int iMonth, int iDay)
static int FixedFromGregorian_Adjusted (int iYear, int iMonth, int iDay)
static void GregorianFromFixed (int iFixedDay, int &iYear, int &iMonth, int &iDayOfYear, int &iDayOfMonth, int &iDayOfWeek)
static void GregorianFromFixed_Adjusted (int iFixedDay, int &iYear, int &iMonth, int &iDayOfYear, int &iDayOfMonth, int &iDayOfWeek)
static bool ParseThreeLetters (const char **pp, int *piHash)
static void ParseDecimalSeconds (size_t n, const char *p, unsigned short *iMilli, unsigned short *iMicro, unsigned short *iNano)
static bool do_convtime (const char *str, FIELDEDTIME *ft)
CLinearTimeDelta operator- (const CLinearTimeAbsolute &ltaA, const CLinearTimeAbsolute &ltaB)
CLinearTimeDelta operator- (const CLinearTimeDelta &lta, const CLinearTimeDelta &ltb)
CLinearTimeAbsolute operator+ (const CLinearTimeAbsolute &ltaA, const CLinearTimeDelta &ltdB)
CLinearTimeDelta operator * (const CLinearTimeDelta &ltd, int Scale)
int operator/ (const CLinearTimeDelta &ltdA, const CLinearTimeDelta &ltdB)
bool operator< (const CLinearTimeDelta &ltdA, const CLinearTimeDelta &ltdB)
bool operator> (const CLinearTimeDelta &ltdA, const CLinearTimeDelta &ltdB)
static void SetStructTm (FIELDEDTIME *ft, struct tm *ptm)
bool FieldedTimeToLinearTime (FIELDEDTIME *ft, INT64 *plt)
bool LinearTimeToFieldedTime (INT64 lt, FIELDEDTIME *ft)
static int YearType (int iYear)
static time_t time_t_midpoint (time_t tLower, time_t tUpper)
static time_t time_t_largest (void)
static time_t time_t_smallest (void)
static void test_time_t (void)
void TIME_Initialize (void)
static int FindOffsetEntry (const CLinearTimeAbsolute &lta)
static bool QueryOffsetTable (CLinearTimeAbsolute lta, CLinearTimeDelta *pltdOffset, bool *pisDST, int *piEntry)
static void UpdateOffsetTable (CLinearTimeAbsolute &lta, CLinearTimeDelta ltdOffset, bool isDST, int i)
static CLinearTimeDelta QueryLocalOffsetAt_Internal (CLinearTimeAbsolute lta, bool *pisDST, int iEntry)
static CLinearTimeDelta QueryLocalOffsetAtUTC (const CLinearTimeAbsolute &lta, bool *pisDST)
static PD_NodePD_NewNode (void)
static void PD_AppendNode (PD_Node *pNode)
static void PD_InsertAfter (PD_Node *pWhere, PD_Node *pNode)
static bool isValidYear (size_t nStr, char *pStr, int iValue)
static bool isValidMonth (size_t nStr, char *pStr, int iValue)
static bool isValidDayOfMonth (size_t nStr, char *pStr, int iValue)
static bool isValidDayOfWeek (size_t nStr, char *pStr, int iValue)
static bool isValidDayOfYear (size_t nStr, char *pStr, int iValue)
static bool isValidWeekOfYear (size_t nStr, char *pStr, int iValue)
static bool isValidHour (size_t nStr, char *pStr, int iValue)
static bool isValidMinute (size_t nStr, char *pStr, int iValue)
static bool isValidSecond (size_t nStr, char *pStr, int iValue)
static bool isValidSubSecond (size_t nStr, char *pStr, int iValue)
static bool isValidHMS (size_t nStr, char *pStr, int iValue)
static void SplitLastTwoDigits (PD_Node *pNode, unsigned mask)
static void SplitLastThreeDigits (PD_Node *pNode, unsigned mask)
static void BreakDownHMS (PD_Node *pNode)
static bool isValidYMD (size_t nStr, char *pStr, int iValue)
static void BreakDownYMD (PD_Node *pNode)
static bool isValidMDY (size_t nStr, char *pStr, int iValue)
static void BreakDownMDY (PD_Node *pNode)
static bool isValidDMY (size_t nStr, char *pStr, int iValue)
static void BreakDownDMY (PD_Node *pNode)
static bool isValidYD (size_t nStr, char *pStr, int iValue)
static void BreakDownYD (PD_Node *pNode)
static void ClassifyNumericToken (PD_Node *pNode)
static void PD_Reset (void)
static PD_NodePD_FirstNode (void)
static PD_NodePD_NextNode (PD_Node *pNode)
static PD_NodePD_PrevNode (PD_Node *pNode)
static void PD_RemoveNode (PD_Node *pNode)
static PD_NodePD_ScanNextToken (char **ppString)
static void PD_Pass2 (void)
static void PD_Deduction (void)
static void PD_BreakItDown (void)
static void PD_Pass5 (void)
static void PD_Pass6 (void)
static bool PD_GetFields (ALLFIELDS *paf)
static bool ConvertAllFieldsToLinearTime (CLinearTimeAbsolute &lta, ALLFIELDS *paf)
bool ParseDate (CLinearTimeAbsolute &lt, char *pDateString, bool *pbZoneSpecified)

Variables

CMuxAlarm MuxAlarm
const INT64 FACTOR_100NS_PER_SECOND = 10000000ull
const INT64 FACTOR_100NS_PER_MINUTE = FACTOR_100NS_PER_SECOND*60
const INT64 FACTOR_100NS_PER_HOUR = FACTOR_100NS_PER_MINUTE*60
const INT64 FACTOR_100NS_PER_DAY = FACTOR_100NS_PER_HOUR*24
const INT64 FACTOR_100NS_PER_WEEK = FACTOR_100NS_PER_DAY*7
char * DayOfWeekString [7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }
static const char daystab [] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
const char * monthtab []
static int MonthTabHash [12]
static CLinearTimeAbsolute ltaLowerBound
static CLinearTimeAbsolute ltaUpperBound
static CLinearTimeDelta ltdTimeZoneStandard
static int NearestYearOfType [15]
static CLinearTimeDelta ltdIntervalMinimum
static bool bTimeInitialized = false
static int nOffsetTable = 0
static int nTouched0 = 0
static OffsetEntry OffsetTable [MAX_OFFSETS]
static const int InitialCouldBe [9]
const NUMERIC_VALID_RECORD NumericSet []
const PD_TEXT_ENTRY PD_TextTable []
const char LexTable [256]
static int nNodes = 0
static PD_Node Nodes [MAX_NODES]
static PD_NodePD_Head = 0
static PD_NodePD_Tail = 0
static const PD_BREAKDOWN BreakDownTable []
const PD_CANTBE CantBeTable []


Detailed Description

CLinearTimeAbsolute and CLinearTimeDelta modules.

Id
timeutil.cpp,v 1.54 2006/10/05 06:08:02 sdennis Exp

Date/Time code based on algorithms presented in "Calendrical Calculations", Cambridge Press, 1998.

The two primary classes are CLinearTimeAbsolute and CLinearTimeDelta deal with civil time from a fixed Epoch and time differences generally, respectively.

This file also contains code related to parsing date strings and glossing over time-related platform differences.

Definition in file timeutil.cpp.


Define Documentation

#define MAX_NODES   200

Definition at line 3096 of file timeutil.cpp.

Referenced by PD_NewNode().

#define MAX_OFFSETS   50

Definition at line 2054 of file timeutil.cpp.

Referenced by UpdateOffsetTable().

#define NOT_PRESENT   -9999999

Definition at line 2524 of file timeutil.cpp.

Referenced by ConvertAllFieldsToLinearTime(), ParseDate(), and PD_GetFields().

#define PD_LEX_ALPHA   4

Definition at line 3069 of file timeutil.cpp.

Referenced by PD_ScanNextToken().

#define PD_LEX_DIGIT   2

Definition at line 3067 of file timeutil.cpp.

Referenced by PD_ScanNextToken().

#define PD_LEX_EOS   5

Definition at line 3070 of file timeutil.cpp.

Referenced by PD_ScanNextToken().

#define PD_LEX_INVALID   0

Definition at line 3065 of file timeutil.cpp.

Referenced by PD_ScanNextToken().

#define PD_LEX_SPACE   3

Definition at line 3068 of file timeutil.cpp.

Referenced by PD_ScanNextToken().

#define PD_LEX_SYMBOL   1

Definition at line 3066 of file timeutil.cpp.

Referenced by PD_ScanNextToken().

#define PDCB_DATE_FIELD_SEPARATOR   0x00000002

Definition at line 2486 of file timeutil.cpp.

Referenced by PD_Pass2(), and PD_ScanNextToken().

#define PDCB_DATE_TIME_SEPARATOR   0x00020000

Definition at line 2502 of file timeutil.cpp.

Referenced by PD_GetFields(), and PD_Pass5().

#define PDCB_DAY_OF_MONTH   0x00000200

Definition at line 2494 of file timeutil.cpp.

Referenced by BreakDownDMY(), BreakDownMDY(), BreakDownYMD(), PD_GetFields(), PD_Pass2(), PD_Pass5(), and PD_Pass6().

#define PDCB_DAY_OF_MONTH_SUFFIX   0x00000008

Definition at line 2488 of file timeutil.cpp.

Referenced by PD_Pass2(), and PD_ScanNextToken().

#define PDCB_DAY_OF_WEEK   0x00000400

Definition at line 2495 of file timeutil.cpp.

Referenced by PD_GetFields(), PD_Pass5(), and PD_Pass6().

#define PDCB_DAY_OF_YEAR   0x00001000

Definition at line 2497 of file timeutil.cpp.

Referenced by BreakDownYD(), PD_GetFields(), PD_Pass5(), and PD_Pass6().

#define PDCB_DMY   0x00010000

Definition at line 2501 of file timeutil.cpp.

Referenced by PD_Pass5(), and PD_Pass6().

#define PDCB_HMS_TIME   0x02000000

Definition at line 2510 of file timeutil.cpp.

Referenced by BreakDownHMS(), PD_Pass2(), PD_Pass5(), and PD_Pass6().

#define PDCB_HMS_TIMEZONE   0x08000000

Definition at line 2512 of file timeutil.cpp.

Referenced by PD_Pass2(), and PD_Pass5().

#define PDCB_HOUR_TIME   0x01000000

Definition at line 2509 of file timeutil.cpp.

Referenced by BreakDownHMS(), PD_GetFields(), PD_Pass2(), PD_Pass5(), and PD_Pass6().

#define PDCB_HOUR_TIMEZONE   0x04000000

Definition at line 2511 of file timeutil.cpp.

Referenced by BreakDownHMS(), PD_GetFields(), PD_Pass2(), and PD_Pass5().

#define PDCB_MDY   0x00008000

Definition at line 2500 of file timeutil.cpp.

Referenced by PD_Pass5(), and PD_Pass6().

#define PDCB_MERIDIAN   0x00100000

Definition at line 2505 of file timeutil.cpp.

Referenced by PD_GetFields(), and PD_Pass5().

#define PDCB_MINUTE   0x00200000

Definition at line 2506 of file timeutil.cpp.

Referenced by BreakDownHMS(), PD_GetFields(), PD_Pass2(), and PD_Pass5().

#define PDCB_MONTH   0x00000100

Definition at line 2493 of file timeutil.cpp.

Referenced by BreakDownDMY(), BreakDownMDY(), BreakDownYMD(), PD_GetFields(), PD_Pass5(), and PD_Pass6().

#define PDCB_NOTHING   0x00000000

Definition at line 2484 of file timeutil.cpp.

Referenced by PD_ScanNextToken().

#define PDCB_REMOVEABLE   0x00000040

Definition at line 2491 of file timeutil.cpp.

Referenced by PD_Pass2(), PD_Pass5(), and PD_ScanNextToken().

#define PDCB_SECOND   0x00400000

Definition at line 2507 of file timeutil.cpp.

Referenced by BreakDownHMS(), PD_GetFields(), PD_Pass2(), and PD_Pass5().

#define PDCB_SECONDS_DECIMAL   0x00000020

Definition at line 2490 of file timeutil.cpp.

Referenced by PD_Pass2(), and PD_ScanNextToken().

#define PDCB_SEPS   (PDCB_YEAR|PDCB_MONTH|PDCB_DAY_OF_MONTH|PDCB_DAY_OF_YEAR|PDCB_WEEK_OF_YEAR|PDCB_DAY_OF_WEEK)

Referenced by PD_Pass2().

#define PDCB_SIGN   0x00000010

Definition at line 2489 of file timeutil.cpp.

Referenced by PD_GetFields(), PD_Pass2(), and PD_ScanNextToken().

#define PDCB_SIGNABLES_NEG   (PDCB_YEAR|PDCB_YD|PDCB_SIGNABLES_POS|PDCB_YMD)

Referenced by PD_Pass2().

#define PDCB_SIGNABLES_POS   (PDCB_HMS_TIME|PDCB_HMS_TIMEZONE)

Referenced by PD_Pass2().

#define PDCB_SUBSECOND   0x00800000

Definition at line 2508 of file timeutil.cpp.

Referenced by PD_GetFields(), PD_Pass2(), and PD_Pass5().

#define PDCB_TIME_FIELD_SEPARATOR   0x00000001

Definition at line 2485 of file timeutil.cpp.

Referenced by PD_Pass2(), and PD_ScanNextToken().

#define PDCB_TIMEZONE   0x00040000

Definition at line 2503 of file timeutil.cpp.

Referenced by PD_GetFields(), and PD_Pass5().

#define PDCB_WEEK_OF_YEAR   0x00000800

Definition at line 2496 of file timeutil.cpp.

Referenced by PD_GetFields(), PD_Pass5(), and PD_Pass6().

#define PDCB_WEEK_OF_YEAR_PREFIX   0x00080000

Definition at line 2504 of file timeutil.cpp.

Referenced by PD_Pass5().

#define PDCB_WHITESPACE   0x00000004

Definition at line 2487 of file timeutil.cpp.

Referenced by PD_Pass2(), and PD_ScanNextToken().

#define PDCB_YD   0x00002000

Definition at line 2498 of file timeutil.cpp.

Referenced by PD_Pass5(), and PD_Pass6().

#define PDCB_YEAR   0x00000080

Definition at line 2492 of file timeutil.cpp.

Referenced by BreakDownDMY(), BreakDownMDY(), BreakDownYD(), BreakDownYMD(), PD_GetFields(), PD_Pass5(), and PD_Pass6().

#define PDCB_YMD   0x00004000

Definition at line 2499 of file timeutil.cpp.

#define PDTT_NUMERIC_SIGNED   5

Definition at line 2471 of file timeutil.cpp.

#define PDTT_NUMERIC_UNSIGNED   2

Definition at line 2468 of file timeutil.cpp.

Referenced by PD_ScanNextToken().

#define PDTT_SPACES   3

Definition at line 2469 of file timeutil.cpp.

Referenced by PD_ScanNextToken().

#define PDTT_SYMBOL   1

Definition at line 2467 of file timeutil.cpp.

Referenced by PD_ScanNextToken().

#define PDTT_TEXT   4

Definition at line 2470 of file timeutil.cpp.

Referenced by PD_ScanNextToken().

#define PFSS_PRECISION   7

Referenced by ParseFractionalSecondsString().


Typedef Documentation

typedef struct tag_AllFields ALLFIELDS

typedef void BREAK_DOWN_FUNC(PD_Node *pNode)

Definition at line 2517 of file timeutil.cpp.

typedef struct tag_pd_numeric_valid NUMERIC_VALID_RECORD

typedef struct tag_pd_breakdown PD_BREAKDOWN

typedef struct tag_pd_cantbe PD_CANTBE

typedef struct tag_pd_node PD_Node

typedef bool PVALIDFUNC(size_t nStr, char *pStr, int iValue)

Definition at line 2908 of file timeutil.cpp.


Function Documentation

static void BreakDownDMY ( PD_Node pNode  )  [static]

Definition at line 2863 of file timeutil.cpp.

References PDCB_DAY_OF_MONTH, PDCB_MONTH, PDCB_YEAR, SplitLastTwoDigits(), and tag_pd_node::uCouldBe.

02864 {
02865     pNode->uCouldBe = PDCB_DAY_OF_MONTH;
02866     SplitLastTwoDigits(pNode, PDCB_YEAR);
02867     SplitLastTwoDigits(pNode, PDCB_MONTH);
02868 }

static void BreakDownHMS ( PD_Node pNode  )  [static]

Definition at line 2761 of file timeutil.cpp.

References tag_pd_node::nToken, PDCB_HMS_TIME, PDCB_HOUR_TIME, PDCB_HOUR_TIMEZONE, PDCB_MINUTE, PDCB_SECOND, SplitLastTwoDigits(), and tag_pd_node::uCouldBe.

02762 {
02763     if (pNode->uCouldBe & PDCB_HMS_TIME)
02764     {
02765         pNode->uCouldBe = PDCB_HOUR_TIME;
02766     }
02767     else
02768     {
02769         pNode->uCouldBe = PDCB_HOUR_TIMEZONE;
02770     }
02771     switch (pNode->nToken)
02772     {
02773     case 5:
02774     case 6:
02775         SplitLastTwoDigits(pNode, PDCB_SECOND);
02776 
02777     case 3:
02778     case 4:
02779         SplitLastTwoDigits(pNode, PDCB_MINUTE);
02780     }
02781 }

static void BreakDownMDY ( PD_Node pNode  )  [static]

Definition at line 2834 of file timeutil.cpp.

References PDCB_DAY_OF_MONTH, PDCB_MONTH, PDCB_YEAR, SplitLastTwoDigits(), and tag_pd_node::uCouldBe.

02835 {
02836     pNode->uCouldBe = PDCB_MONTH;
02837     SplitLastTwoDigits(pNode, PDCB_YEAR);
02838     SplitLastTwoDigits(pNode, PDCB_DAY_OF_MONTH);
02839 }

static void BreakDownYD ( PD_Node pNode  )  [static]

Definition at line 2889 of file timeutil.cpp.

References PDCB_DAY_OF_YEAR, PDCB_YEAR, SplitLastThreeDigits(), and tag_pd_node::uCouldBe.

02890 {
02891     pNode->uCouldBe = PDCB_YEAR;
02892     SplitLastThreeDigits(pNode, PDCB_DAY_OF_YEAR);
02893 }

static void BreakDownYMD ( PD_Node pNode  )  [static]

Definition at line 2805 of file timeutil.cpp.

References PDCB_DAY_OF_MONTH, PDCB_MONTH, PDCB_YEAR, SplitLastTwoDigits(), and tag_pd_node::uCouldBe.

02806 {
02807     pNode->uCouldBe = PDCB_YEAR;
02808     SplitLastTwoDigits(pNode, PDCB_DAY_OF_MONTH);
02809     SplitLastTwoDigits(pNode, PDCB_MONTH);
02810 }

static void ClassifyNumericToken ( PD_Node pNode  )  [static]

Definition at line 2939 of file timeutil.cpp.

References tag_pd_node::iToken, tag_pd_node::nToken, NumericSet, tag_pd_node::pToken, and tag_pd_node::uCouldBe.

Referenced by PD_ScanNextToken().

02940 {
02941     size_t nToken = pNode->nToken;
02942     char  *pToken = pNode->pToken;
02943     int    iToken = pNode->iToken;
02944 
02945     unsigned int uCouldBe = InitialCouldBe[nToken-1];
02946 
02947     int i = 0;
02948     int mask = 0;
02949     while ((mask = NumericSet[i].mask) != 0)
02950     {
02951         if (  (mask & uCouldBe)
02952            && !(NumericSet[i].fnValid(nToken, pToken, iToken)))
02953         {
02954             uCouldBe &= ~mask;
02955         }
02956         i++;
02957     }
02958     pNode->uCouldBe = uCouldBe;
02959 }

static bool ConvertAllFieldsToLinearTime ( CLinearTimeAbsolute lta,
ALLFIELDS paf 
) [static]

Definition at line 3927 of file timeutil.cpp.

References i64FloorDivisionMod(), tag_AllFields::iDayOfMonth, tag_AllFields::iDayOfWeek, tag_AllFields::iDayOfYear, tag_AllFields::iHourTime, tag_AllFields::iMicrosecondTime, tag_AllFields::iMillisecondTime, tag_AllFields::iMinuteTime, tag_AllFields::iMinuteTimeZone, tag_AllFields::iMonthOfYear, tag_AllFields::iNanosecondTime, tag_AllFields::iSecondTime, tag_AllFields::iWeekOfYear, tag_AllFields::iYear, NOT_PRESENT, CLinearTimeAbsolute::Return100ns(), CLinearTimeAbsolute::ReturnFields(), CLinearTimeDelta::Set100ns(), CLinearTimeAbsolute::Set100ns(), CLinearTimeAbsolute::SetFields(), and CLinearTimeDelta::SetSeconds().

Referenced by ParseDate().

03928 {
03929     FIELDEDTIME ft;
03930     memset(&ft, 0, sizeof(ft));
03931 
03932     int iExtraDays = 0;
03933     if (paf->iYear == NOT_PRESENT)
03934     {
03935         return false;
03936     }
03937     ft.iYear = paf->iYear;
03938 
03939     if (paf->iMonthOfYear != NOT_PRESENT && paf->iDayOfMonth != NOT_PRESENT)
03940     {
03941         ft.iMonth = paf->iMonthOfYear;
03942         ft.iDayOfMonth = paf->iDayOfMonth;
03943     }
03944     else if (paf->iDayOfYear != NOT_PRESENT)
03945     {
03946         iExtraDays = paf->iDayOfYear - 1;
03947         ft.iMonth = 1;
03948         ft.iDayOfMonth = 1;
03949     }
03950     else if (paf->iWeekOfYear != NOT_PRESENT && paf->iDayOfWeek != NOT_PRESENT)
03951     {
03952         // Remember that iYear in this case represents an ISO year, which
03953         // is not exactly the same thing as a Gregorian year.
03954         //
03955         FIELDEDTIME ftWD;
03956         memset(&ftWD, 0, sizeof(ftWD));
03957         ftWD.iYear = paf->iYear - 1;
03958         ftWD.iMonth = 12;
03959         ftWD.iDayOfMonth = 27;
03960         if (!lta.SetFields(&ftWD))
03961         {
03962             return false;
03963         }
03964         INT64 i64 = lta.Return100ns();
03965         INT64 j64;
03966         i64FloorDivisionMod(i64+FACTOR_100NS_PER_DAY, FACTOR_100NS_PER_WEEK, &j64);
03967         i64 -= j64;
03968 
03969         // i64 now corresponds to the Sunday that strickly preceeds before
03970         // December 28th, and the 28th is guaranteed to be in the previous
03971         // year so that the ISO and Gregorian Years are the same thing.
03972         //
03973         i64 += FACTOR_100NS_PER_WEEK*paf->iWeekOfYear;
03974         i64 += FACTOR_100NS_PER_DAY*paf->iDayOfWeek;
03975         lta.Set100ns(i64);
03976         lta.ReturnFields(&ft);
03977 
03978         // Validate that this week actually has a week 53.
03979         //
03980         if (paf->iWeekOfYear == 53)
03981         {
03982             int iDOW_ISO = (ft.iDayOfWeek == 0) ? 7 : ft.iDayOfWeek;
03983             int j = ft.iDayOfMonth - iDOW_ISO;
03984             if (ft.iMonth == 12)
03985             {
03986                 if (28 <= j)
03987                 {
03988                     return false;
03989                 }
03990             }
03991             else // if (ft.iMonth == 1)
03992             {
03993                 if (-3 <= j)
03994                 {
03995                     return false;
03996                 }
03997             }
03998         }
03999     }
04000     else
04001     {
04002         // Under-specified.
04003         //
04004         return false;
04005     }
04006 
04007     if (paf->iHourTime != NOT_PRESENT)
04008     {
04009         ft.iHour = paf->iHourTime;
04010         if (paf->iMinuteTime != NOT_PRESENT)
04011         {
04012             ft.iMinute = paf->iMinuteTime;
04013             if (paf->iSecondTime != NOT_PRESENT)
04014             {
04015                 ft.iSecond = paf->iSecondTime;
04016                 if (paf->iMillisecondTime != NOT_PRESENT)
04017                 {
04018                     ft.iMillisecond = paf->iMillisecondTime;
04019                     ft.iMicrosecond = paf->iMicrosecondTime;
04020                     ft.iNanosecond = paf->iNanosecondTime;
04021                 }
04022             }
04023         }
04024     }
04025 
04026     if (lta.SetFields(&ft))
04027     {
04028         CLinearTimeDelta ltd;
04029         if (paf->iMinuteTimeZone != NOT_PRESENT)
04030         {
04031             ltd.SetSeconds(60 * paf->iMinuteTimeZone);
04032             lta -= ltd;
04033         }
04034         if (iExtraDays)
04035         {
04036             ltd.Set100ns(FACTOR_100NS_PER_DAY);
04037             lta += ltd * iExtraDays;
04038         }
04039         return true;
04040     }
04041     return false;
04042 }

static void ConvertToSecondsString ( char *  buffer,
INT64  n64,
int  nFracDigits 
) [static]

Definition at line 621 of file timeutil.cpp.

References i64FloorDivisionMod(), and mux_i64toa().

Referenced by CLinearTimeAbsolute::ReturnSecondsString(), and CLinearTimeDelta::ReturnSecondsString().

00622 {
00623     INT64 Leftover;
00624     INT64 lt = i64FloorDivisionMod(n64, FACTOR_100NS_PER_SECOND, &Leftover);
00625 
00626     size_t n = mux_i64toa(lt, buffer);
00627     if (Leftover == 0)
00628     {
00629         return;
00630     }
00631 
00632     // Sanitize Precision Request.
00633     //
00634     const int maxFracDigits = 7;
00635     const int minFracDigits = 0;
00636     if (nFracDigits < minFracDigits)
00637     {
00638         nFracDigits = minFracDigits;
00639     }
00640     else if (maxFracDigits < nFracDigits)
00641     {
00642         nFracDigits = maxFracDigits;
00643     }
00644     if (0 < nFracDigits)
00645     {
00646         char *p = buffer + n;
00647         *p++ = '.';
00648         char *q = p;
00649 
00650         char buf[maxFracDigits+1];
00651         size_t m = mux_i64toa(Leftover, buf);
00652         memset(p, '0', maxFracDigits - m);
00653         p += maxFracDigits - m;
00654         memcpy(p, buf, m);
00655         p = q + nFracDigits - 1;
00656         while (*p == '0')
00657         {
00658             p--;
00659         }
00660         p++;
00661         *p = '\0';
00662     }
00663 }

static bool do_convtime ( const char *  str,
FIELDEDTIME ft 
) [static]

Definition at line 1021 of file timeutil.cpp.

References FIELDEDTIME::iDayOfMonth, FIELDEDTIME::iMonth, mux_atol(), and ParseThreeLetters().

Referenced by CLinearTimeAbsolute::SetString().

01022 {
01023     memset(ft, 0, sizeof(FIELDEDTIME));
01024     if (!str || !ft)
01025     {
01026         return false;
01027     }
01028 
01029     // Day-of-week OR month.
01030     //
01031     const char *p = str;
01032     int i, iHash;
01033     if (!ParseThreeLetters(&p, &iHash))
01034     {
01035         return false;
01036     }
01037     for (i = 0; (i < 12) && iHash != MonthTabHash[i]; i++) ;
01038     if (i == 12)
01039     {
01040         // The above three letters were probably the Day-Of-Week, the
01041         // next three letters are required to be the month name.
01042         //
01043         if (!ParseThreeLetters(&p, &iHash))
01044         {
01045             return false;
01046         }
01047         for (i = 0; (i < 12) && iHash != MonthTabHash[i]; i++) ;
01048         if (i == 12)
01049         {
01050             return false;
01051         }
01052     }
01053     ft->iMonth = i + 1; // January = 1, February = 2, etc.
01054 
01055     // Day of month.
01056     //
01057     ft->iDayOfMonth = (unsigned short)mux_atol(p);
01058     if (ft->iDayOfMonth < 1 || daystab[i] < ft->iDayOfMonth)
01059     {
01060         return false;
01061     }
01062     while (*p && *p != ' ') p++;
01063     while (*p == ' ') p++;
01064 
01065     // Hours
01066     //
01067     ft->iHour = (unsigned short)mux_atol(p);
01068     if (ft->iHour > 23 || (ft->iHour == 0 && *p != '0'))
01069     {
01070         return false;
01071     }
01072     while (*p && *p != ':') p++;
01073     if (*p == ':') p++;
01074     while (*p == ' ') p++;
01075 
01076     // Minutes
01077     //
01078     ft->iMinute = (unsigned short)mux_atol(p);
01079     if (ft->iMinute > 59 || (ft->iMinute == 0 && *p != '0'))
01080     {
01081         return false;
01082     }
01083     while (*p && *p != ':') p++;
01084     if (*p == ':') p++;
01085     while (*p == ' ') p++;
01086 
01087     // Seconds
01088     //
01089     ft->iSecond = (unsigned short)mux_atol(p);
01090     if (ft->iSecond > 59 || (ft->iSecond == 0 && *p != '0'))
01091     {
01092         return false;
01093     }
01094     while (mux_isdigit(*p))
01095     {
01096         p++;
01097     }
01098 
01099     // Milliseconds, Microseconds, and Nanoseconds
01100     //
01101     if (*p == '.')
01102     {
01103         p++;
01104         size_t n;
01105         const char *q = strchr(p, ' ');
01106         if (q)
01107         {
01108             n = q - p;
01109         }
01110         else
01111         {
01112             n = strlen(p);
01113         }
01114 
01115         ParseDecimalSeconds(n, p, &ft->iMillisecond, &ft->iMicrosecond,
01116             &ft->iNanosecond);
01117     }
01118     while (*p && *p != ' ') p++;
01119     while (*p == ' ') p++;
01120 
01121     // Year
01122     //
01123     ft->iYear = (short)mux_atol(p);
01124     while (mux_isdigit(*p))
01125     {
01126         p++;
01127     }
01128     while (*p == ' ') p++;
01129     if (*p != '\0')
01130     {
01131         return false;
01132     }
01133 
01134     // DayOfYear and DayOfWeek
01135     //
01136     ft->iDayOfYear = 0;
01137     ft->iDayOfWeek = 0;
01138 
01139     return isValidDate(ft->iYear, ft->iMonth, ft->iDayOfMonth);
01140 }

bool FieldedTimeToLinearTime ( FIELDEDTIME ft,
INT64 plt 
)

Definition at line 1333 of file timeutil.cpp.

References FACTOR_100NS_PER_MICROSECOND, FACTOR_100NS_PER_MILLISECOND, FACTOR_NANOSECONDS_PER_100NS, FixedFromGregorian_Adjusted(), FIELDEDTIME::iDayOfMonth, FIELDEDTIME::iDayOfWeek, FIELDEDTIME::iHour, FIELDEDTIME::iMicrosecond, FIELDEDTIME::iMillisecond, FIELDEDTIME::iMinute, iMod(), FIELDEDTIME::iMonth, FIELDEDTIME::iNanosecond, FIELDEDTIME::iSecond, isValidDate(), and FIELDEDTIME::iYear.

Referenced by CLinearTimeAbsolute::SetFields(), and CLinearTimeAbsolute::SetString().

01334 {
01335     if (!isValidDate(ft->iYear, ft->iMonth, ft->iDayOfMonth))
01336     {
01337         *plt = 0;
01338         return false;
01339     }
01340 
01341     int iFixedDay = FixedFromGregorian_Adjusted(ft->iYear, ft->iMonth, ft->iDayOfMonth);
01342     ft->iDayOfWeek = iMod(iFixedDay+1, 7);
01343 
01344     INT64 lt;
01345     lt  = iFixedDay * FACTOR_100NS_PER_DAY;
01346     lt += ft->iHour * FACTOR_100NS_PER_HOUR;
01347     lt += ft->iMinute * FACTOR_100NS_PER_MINUTE;
01348     lt += ft->iSecond * FACTOR_100NS_PER_SECOND;
01349     lt += ft->iMicrosecond * FACTOR_100NS_PER_MICROSECOND;
01350     lt += ft->iMillisecond * FACTOR_100NS_PER_MILLISECOND;
01351     lt += ft->iNanosecond / FACTOR_NANOSECONDS_PER_100NS;
01352 
01353     *plt = lt;
01354     return true;
01355 }

static int FindOffsetEntry ( const CLinearTimeAbsolute lta  )  [static]

Definition at line 2063 of file timeutil.cpp.

References OffsetTable.

Referenced by QueryOffsetTable().

02064 {
02065     int lo = 0;
02066     int hi = nOffsetTable - 1;
02067     int mid = 0;
02068     while (lo <= hi)
02069     {
02070         mid = ((hi - lo) >> 1) + lo;
02071         if (OffsetTable[mid].ltaStart <= lta)
02072         {
02073             lo = mid + 1;
02074         }
02075         else
02076         {
02077             hi = mid - 1;
02078         }
02079 
02080     }
02081     return lo-1;
02082 }

static int FixedFromGregorian ( int  iYear,
int  iMonth,
int  iDay 
) [static]

Definition at line 835 of file timeutil.cpp.

References iFloorDivision(), and isLeapYear().

Referenced by FixedFromGregorian_Adjusted(), and GregorianFromFixed().

00836 {
00837     iYear = iYear - 1;
00838     int iFixedDay = 365 * iYear;
00839     iFixedDay += iFloorDivision(iYear, 4);
00840     iFixedDay -= iFloorDivision(iYear, 100);
00841     iFixedDay += iFloorDivision(iYear, 400);
00842     iFixedDay += iFloorDivision(367 * iMonth - 362, 12);
00843     iFixedDay += iDay;
00844 
00845     if (iMonth > 2)
00846     {
00847         if (isLeapYear(iYear+1))
00848         {
00849             iFixedDay -= 1;
00850         }
00851         else
00852         {
00853             iFixedDay -= 2;
00854         }
00855     }
00856 
00857     // At this point, iFixedDay has an epoch of 1 R.D.
00858     //
00859     return iFixedDay;
00860 }

static int FixedFromGregorian_Adjusted ( int  iYear,
int  iMonth,
int  iDay 
) [static]

Definition at line 862 of file timeutil.cpp.

References FixedFromGregorian().

Referenced by FieldedTimeToLinearTime().

00863 {
00864     int iFixedDay = FixedFromGregorian(iYear, iMonth, iDay);
00865 
00866     // At this point, iFixedDay has an epoch of 1 R.D.
00867     // We need an Epoch of (00:00:00 UTC, January 1, 1601)
00868     //
00869     return iFixedDay - 584389;
00870 }

void GetUTCLinearTime ( INT64 plt  )  [static]

Definition at line 1687 of file timeutil.cpp.

References EPOCH_OFFSET, and FACTOR_100NS_PER_MICROSECOND.

Referenced by CLinearTimeAbsolute::GetLocal(), and CLinearTimeAbsolute::GetUTC().

01688 {
01689 #ifdef HAVE_GETTIMEOFDAY
01690     struct timeval tv;
01691     struct timezone tz;
01692     tz.tz_minuteswest = 0;
01693     tz.tz_dsttime = 0;
01694 
01695     gettimeofday(&tv, &tz);
01696 
01697     *plt = (((INT64)tv.tv_sec) * FACTOR_100NS_PER_SECOND)
01698          + (tv.tv_usec * FACTOR_100NS_PER_MICROSECOND)
01699          + EPOCH_OFFSET;
01700 #else
01701     time_t t;
01702 
01703     time(&t);
01704 
01705     *plt = t*FACTOR_100NS_PER_SECOND;
01706 #endif
01707 }

static void GregorianFromFixed ( int  iFixedDay,
int &  iYear,
int &  iMonth,
int &  iDayOfYear,
int &  iDayOfMonth,
int &  iDayOfWeek 
) [static]

Definition at line 875 of file timeutil.cpp.

References d0, d1, FixedFromGregorian(), iFloorDivisionMod(), iMod(), and isLeapYear().

Referenced by GregorianFromFixed_Adjusted().

00876 {
00877     int d0 = iFixedDay - 1;
00878     int d1, n400 = iFloorDivisionMod(d0, 146097, &d1);
00879     int d2, n100 = iFloorDivisionMod(d1,  36524, &d2);
00880     int d3, n4   = iFloorDivisionMod(d2,   1461, &d3);
00881     int d4, n1   = iFloorDivisionMod(d3,    365, &d4);
00882     d4 = d4 + 1;
00883 
00884     iYear = 400*n400 + 100*n100 + 4*n4 + n1;
00885 
00886     if (n100 != 4 && n1 != 4)
00887     {
00888         iYear = iYear + 1;
00889     }
00890 
00891     static int cache_iYear = 99999;
00892     static int cache_iJan1st = 0;
00893     static int cache_iMar1st = 0;
00894     int iFixedDayOfJanuary1st;
00895     int iFixedDayOfMarch1st;
00896     if (iYear == cache_iYear)
00897     {
00898         iFixedDayOfJanuary1st = cache_iJan1st;
00899         iFixedDayOfMarch1st = cache_iMar1st;
00900     }
00901     else
00902     {
00903         cache_iYear = iYear;
00904         cache_iJan1st = iFixedDayOfJanuary1st = FixedFromGregorian(iYear, 1, 1);
00905         cache_iMar1st = iFixedDayOfMarch1st = FixedFromGregorian(iYear, 3, 1);
00906     }
00907 
00908 
00909     int iPriorDays = iFixedDay - iFixedDayOfJanuary1st;
00910     int iCorrection;
00911     if (iFixedDay < iFixedDayOfMarch1st)
00912     {
00913         iCorrection = 0;
00914     }
00915     else if (isLeapYear(iYear))
00916     {
00917         iCorrection = 1;
00918     }
00919     else
00920     {
00921         iCorrection = 2;
00922     }
00923 
00924     iMonth = (12*(iPriorDays+iCorrection)+373)/367;
00925     iDayOfMonth = iFixedDay - FixedFromGregorian(iYear, iMonth, 1) + 1;
00926     iDayOfYear = iPriorDays + 1;
00927 
00928     // Calculate the Day of week using the linear progression of days.
00929     //
00930     iDayOfWeek = iMod(iFixedDay, 7);
00931 }

static void GregorianFromFixed_Adjusted ( int  iFixedDay,
int &  iYear,
int &  iMonth,
int &  iDayOfYear,
int &  iDayOfMonth,
int &  iDayOfWeek 
) [static]

Definition at line 933 of file timeutil.cpp.

References GregorianFromFixed().

Referenced by LinearTimeToFieldedTime().

00934 {
00935     // We need to convert the Epoch to 1 R.D. from
00936     // (00:00:00 UTC, January 1, 1601)
00937     //
00938     GregorianFromFixed(iFixedDay + 584389, iYear, iMonth, iDayOfYear, iDayOfMonth, iDayOfWeek);
00939 }

INT64 i64FloorDivision ( INT64  x,
INT64  y 
)

Definition at line 148 of file timeutil.cpp.

Referenced by FUNCTION(), CLinearTimeAbsolute::ReturnSeconds(), and CLinearTimeDelta::ReturnTimeValueStruct().

00149 {
00150     if (y < 0)
00151     {
00152         if (x <= 0)
00153         {
00154             return x / y;
00155         }
00156         else
00157         {
00158             return (x - y - 1) / y;
00159         }
00160     }
00161     else
00162     {
00163         if (x < 0)
00164         {
00165             return (x - y + 1) / y;
00166         }
00167         else
00168         {
00169             return x / y;
00170         }
00171     }
00172 }

static INT64 i64FloorDivisionMod ( INT64  x,
INT64  y,
INT64 piMod 
) [static]

Definition at line 204 of file timeutil.cpp.

Referenced by ConvertAllFieldsToLinearTime(), ConvertToSecondsString(), LinearTimeToFieldedTime(), and CLinearTimeDelta::ReturnTimeValueStruct().

00205 {
00206     if (y < 0)
00207     {
00208         if (x <= 0)
00209         {
00210             *piMod = x % y;
00211             return x / y;
00212         }
00213         else
00214         {
00215             *piMod = ((x-1) % y) + y + 1;
00216             return (x - y - 1) / y;
00217         }
00218     }
00219     else
00220     {
00221         if (x < 0)
00222         {
00223             *piMod = ((x+1) % y) + y - 1;
00224             return (x - y + 1) / y;
00225         }
00226         else
00227         {
00228             *piMod = x % y;
00229             return x / y;
00230         }
00231     }
00232 }

INT64 i64Mod ( INT64  x,
INT64  y 
)

Definition at line 80 of file timeutil.cpp.

Referenced by FUNCTION().

00081 {
00082     if (y < 0)
00083     {
00084         if (x <= 0)
00085         {
00086             return x % y;
00087         }
00088         else
00089         {
00090             return ((x-1) % y) + y + 1;
00091         }
00092     }
00093     else
00094     {
00095         if (x < 0)
00096         {
00097             return ((x+1) % y) + y - 1;
00098         }
00099         else
00100         {
00101             return x % y;
00102         }
00103     }
00104 }

DCL_INLINE int iDivision ( int  x,
int  y 
)

Definition at line 115 of file timeutil.cpp.

00116 {
00117     return x / y;
00118 }

static int iFloorDivision ( int  x,
int  y 
) [static]

Definition at line 122 of file timeutil.cpp.

Referenced by FixedFromGregorian().

00123 {
00124     if (y < 0)
00125     {
00126         if (x <= 0)
00127         {
00128             return x / y;
00129         }
00130         else
00131         {
00132             return (x - y - 1) / y;
00133         }
00134     }
00135     else
00136     {
00137         if (x < 0)
00138         {
00139             return (x - y + 1) / y;
00140         }
00141         else
00142         {
00143             return x / y;
00144         }
00145     }
00146 }

int iFloorDivisionMod ( int  x,
int  y,
int *  piMod 
)

Definition at line 174 of file timeutil.cpp.

Referenced by GregorianFromFixed().

00175 {
00176     if (y < 0)
00177     {
00178         if (x <= 0)
00179         {
00180             *piMod = x % y;
00181             return x / y;
00182         }
00183         else
00184         {
00185             *piMod = ((x-1) % y) + y + 1;
00186             return (x - y - 1) / y;
00187         }
00188     }
00189     else
00190     {
00191         if (x < 0)
00192         {
00193             *piMod = ((x+1) % y) + y - 1;
00194             return (x - y + 1) / y;
00195         }
00196         else
00197         {
00198             *piMod = x % y;
00199             return x / y;
00200         }
00201     }
00202 }

int iMod ( int  x,
int  y 
)

Definition at line 54 of file timeutil.cpp.

Referenced by crypt_code(), do_comlast(), FieldedTimeToLinearTime(), GregorianFromFixed(), isLeapYear(), and SendChannelMessage().

00055 {
00056     if (y < 0)
00057     {
00058         if (x <= 0)
00059         {
00060             return x % y;
00061         }
00062         else
00063         {
00064             return ((x-1) % y) + y + 1;
00065         }
00066     }
00067     else
00068     {
00069         if (x < 0)
00070         {
00071             return ((x+1) % y) + y - 1;
00072         }
00073         else
00074         {
00075             return x % y;
00076         }
00077     }
00078 }

DCL_INLINE int iRemainder ( int  x,
int  y 
)

Definition at line 108 of file timeutil.cpp.

00109 {
00110     return x % y;
00111 }

bool isLeapYear ( long  iYear  ) 

Definition at line 796 of file timeutil.cpp.

References iMod().

Referenced by FixedFromGregorian(), FUNCTION(), GregorianFromFixed(), isValidDate(), and YearType().

00797 {
00798     if (iMod(iYear, 4) != 0)
00799     {
00800         // Not a leap year.
00801         //
00802         return false;
00803     }
00804     unsigned long wMod = iMod(iYear, 400);
00805     if ((wMod == 100) || (wMod == 200) || (wMod == 300))
00806     {
00807         // Not a leap year.
00808         //
00809         return false;
00810     }
00811     return true;
00812 }

static bool isValidDate ( int  iYear,
int  iMonth,
int  iDay 
) [static]

Definition at line 814 of file timeutil.cpp.

References isLeapYear().

Referenced by FieldedTimeToLinearTime(), and LinearTimeToFieldedTime().

00815 {
00816     if (iYear < -27256 || 30826 < iYear)
00817     {
00818         return false;
00819     }
00820     if (iMonth < 1 || 12 < iMonth)
00821     {
00822         return false;
00823     }
00824     if (iDay < 1 || daystab[iMonth-1] < iDay)
00825     {
00826         return false;
00827     }
00828     if (iMonth == 2 && iDay == 29 && !isLeapYear(iYear))
00829     {
00830         return false;
00831     }
00832     return true;
00833 }

static bool isValidDayOfMonth ( size_t  nStr,
char *  pStr,
int  iValue 
) [static]

Definition at line 2574 of file timeutil.cpp.

References UNUSED_PARAMETER.

Referenced by isValidDMY(), isValidMDY(), and isValidYMD().

02575 {
02576     UNUSED_PARAMETER(pStr);
02577 
02578     // Day Of Month may be 1 through 9, 01 through 09, 10 through 19,
02579     // 20 through 29, 30, and 31.
02580     //
02581     if (  1 <= nStr && nStr <= 2
02582        && 1 <= iValue && iValue <= 31)
02583     {
02584         return true;
02585     }
02586     return false;
02587 }

static bool isValidDayOfWeek ( size_t  nStr,
char *  pStr,
int  iValue 
) [static]

Definition at line 2589 of file timeutil.cpp.

References UNUSED_PARAMETER.

02590 {
02591     UNUSED_PARAMETER(pStr);
02592 
02593     // Day Of Week may be 1 through 7.
02594     //
02595     if (  1 == nStr
02596        && 1 <= iValue && iValue <= 7)
02597     {
02598         return true;
02599     }
02600     return false;
02601 }

static bool isValidDayOfYear ( size_t  nStr,
char *  pStr,
int  iValue 
) [static]

Definition at line 2603 of file timeutil.cpp.

References UNUSED_PARAMETER.

Referenced by isValidYD().

02604 {
02605     UNUSED_PARAMETER(pStr);
02606 
02607     // Day Of Year 001 through 366
02608     //
02609     if (  3 == nStr
02610        && 1 <= iValue && iValue <= 366)
02611     {
02612         return true;
02613     }
02614     return false;
02615 }

static bool isValidDMY ( size_t  nStr,
char *  pStr,
int  iValue 
) [static]

Definition at line 2843 of file timeutil.cpp.

References isValidDayOfMonth(), isValidMonth(), and isValidYear().

02844 {
02845     int iDay = iValue / 10000;
02846     iValue -= 10000 * iDay;
02847     int iMonth = iValue / 100;
02848     iValue -= 100 * iMonth;
02849     int iYear = iValue;
02850 
02851     if (  6 == nStr
02852        && isValidMonth(2, pStr+2, iMonth)
02853        && isValidDayOfMonth(2, pStr, iDay)
02854        && isValidYear(2, pStr+4, iYear))
02855     {
02856         return true;
02857     }
02858     return false;
02859 }

static bool isValidHMS ( size_t  nStr,
char *  pStr,
int  iValue 
) [static]

Definition at line 2691 of file timeutil.cpp.

References isValidHour(), isValidMinute(), and isValidSecond().

02692 {
02693     int iHour, iMinutes, iSeconds;
02694     switch (nStr)
02695     {
02696     case 1:
02697     case 2:
02698         return isValidHour(nStr, pStr, iValue);
02699 
02700     case 3:
02701     case 4:
02702         iHour    = iValue/100; iValue -= iHour*100;
02703         iMinutes = iValue;
02704         if (  isValidHour(nStr-2, pStr, iHour)
02705            && isValidMinute(2, pStr+nStr-2, iMinutes))
02706         {
02707             return true;
02708         }
02709         break;
02710 
02711     case 5:
02712     case 6:
02713         iHour    = iValue/10000;  iValue -= iHour*10000;
02714         iMinutes = iValue/100;    iValue -= iMinutes*100;
02715         iSeconds = iValue;
02716         if (  isValidHour(nStr-4, pStr, iHour)
02717            && isValidMinute(2, pStr+nStr-4, iMinutes)
02718            && isValidSecond(2, pStr+nStr-2, iSeconds))
02719         {
02720             return true;
02721         }
02722         break;
02723     }
02724     return false;
02725 }

static bool isValidHour ( size_t  nStr,
char *  pStr,
int  iValue 
) [static]

Definition at line 2631 of file timeutil.cpp.

References UNUSED_PARAMETER.

Referenced by isValidHMS().

02632 {
02633     UNUSED_PARAMETER(pStr);
02634 
02635     // Hour may be 0 through 9, 00 through 09, 10 through 19, 20 through 24.
02636     //
02637     if (  1 <= nStr && nStr <= 2
02638        && 0 <= iValue && iValue <= 24)
02639     {
02640         return true;
02641     }
02642     return false;
02643 }

static bool isValidMDY ( size_t  nStr,
char *  pStr,
int  iValue 
) [static]

Definition at line 2814 of file timeutil.cpp.

References isValidDayOfMonth(), isValidMonth(), and isValidYear().

02815 {
02816     int iMonth = iValue / 10000;
02817     iValue -= 10000 * iMonth;
02818     int iDay = iValue / 100;
02819     iValue -= 100 * iDay;
02820     int iYear = iValue;
02821 
02822     if (  6 == nStr
02823        && isValidMonth(2, pStr, iMonth)
02824        && isValidDayOfMonth(2, pStr+2, iDay)
02825        && isValidYear(2, pStr+4, iYear))
02826     {
02827         return true;
02828     }
02829     return false;
02830 }

static bool isValidMinute ( size_t  nStr,
char *  pStr,
int  iValue 
) [static]

Definition at line 2645 of file timeutil.cpp.

References UNUSED_PARAMETER.

Referenced by isValidHMS().

02646 {
02647     UNUSED_PARAMETER(pStr);
02648 
02649     // Minute may be 00 through 59.
02650     //
02651     if (  2 == nStr
02652        && 0 <= iValue && iValue <= 59)
02653     {
02654         return true;
02655     }
02656     return false;
02657 }

static bool isValidMonth ( size_t  nStr,
char *  pStr,
int  iValue 
) [static]

Definition at line 2560 of file timeutil.cpp.

References UNUSED_PARAMETER.

Referenced by isValidDMY(), isValidMDY(), and isValidYMD().

02561 {
02562     UNUSED_PARAMETER(pStr);
02563 
02564     // Month may be 1 through 9, 01 through 09, 10, 11, or 12.
02565     //
02566     if (  1 <= nStr && nStr <= 2
02567        && 1 <= iValue && iValue <= 12)
02568     {
02569         return true;
02570     }
02571     return false;
02572 }

static bool isValidSecond ( size_t  nStr,
char *  pStr,
int  iValue 
) [static]

Definition at line 2659 of file timeutil.cpp.

References UNUSED_PARAMETER.

Referenced by isValidHMS().

02660 {
02661     UNUSED_PARAMETER(pStr);
02662 
02663     // Second may be 00 through 59. Leap seconds represented
02664     // by '60' are not dealt with.
02665     //
02666     if (  2 == nStr
02667        && 0 <= iValue && iValue <= 59)
02668     {
02669         return true;
02670     }
02671     return false;
02672 }

static bool isValidSubSecond ( size_t  nStr,
char *  pStr,
int  iValue 
) [static]

Definition at line 2674 of file timeutil.cpp.

References UNUSED_PARAMETER.

02675 {
02676     UNUSED_PARAMETER(pStr);
02677     UNUSED_PARAMETER(iValue);
02678 
02679     // Sub seconds can really be anything, but we limit
02680     // it's precision to 100 ns.
02681     //
02682     if (nStr <= 7)
02683     {
02684         return true;
02685     }
02686     return false;
02687 }

static bool isValidWeekOfYear ( size_t  nStr,
char *  pStr,
int  iValue 
) [static]

Definition at line 2617 of file timeutil.cpp.

References UNUSED_PARAMETER.

02618 {
02619     UNUSED_PARAMETER(pStr);
02620 
02621     // Week Of Year may be 01 through 53.
02622     //
02623     if (  2 == nStr
02624        && 1 <= iValue && iValue <= 53)
02625     {
02626         return true;
02627     }
02628     return false;
02629 }

static bool isValidYD ( size_t  nStr,
char *  pStr,
int  iValue 
) [static]

Definition at line 2872 of file timeutil.cpp.

References isValidDayOfYear(), and isValidYear().

02873 {
02874     int iYear = iValue / 1000;
02875     iValue -= 1000*iYear;
02876     int iDay = iValue;
02877 
02878     if (  4 <= nStr && nStr <= 8
02879        && isValidDayOfYear(3, pStr+nStr-3, iDay)
02880        && isValidYear(nStr-3, pStr, iYear))
02881     {
02882         return true;
02883     }
02884     return false;
02885 }

static bool isValidYear ( size_t  nStr,
char *  pStr,
int  iValue 
) [static]

Definition at line 2544 of file timeutil.cpp.

References UNUSED_PARAMETER.

Referenced by isValidDMY(), isValidMDY(), isValidYD(), and isValidYMD().

02545 {
02546     UNUSED_PARAMETER(pStr);
02547     UNUSED_PARAMETER(iValue);
02548 
02549     // Year may be Y, YY, YYY, YYYY, or YYYYY.
02550     // Negative and zero years are permitted in general, but we aren't
02551     // give the leading sign.
02552     //
02553     if (1 <= nStr && nStr <= 5)
02554     {
02555         return true;
02556     }
02557     return false;
02558 }

static bool isValidYMD ( size_t  nStr,
char *  pStr,
int  iValue 
) [static]

Definition at line 2786 of file timeutil.cpp.

References isValidDayOfMonth(), isValidMonth(), and isValidYear().

02787 {
02788     int iYear = iValue / 10000;
02789     iValue -= 10000 * iYear;
02790     int iMonth = iValue / 100;
02791     iValue -= 100 * iMonth;
02792     int iDay = iValue;
02793 
02794     if (  isValidMonth(2, pStr+nStr-4, iMonth)
02795        && isValidDayOfMonth(2, pStr+nStr-2, iDay)
02796        && isValidYear(nStr-4, pStr, iYear))
02797     {
02798         return true;
02799     }
02800     return false;
02801 }

bool LinearTimeToFieldedTime ( INT64  lt,
FIELDEDTIME ft 
)

Definition at line 1357 of file timeutil.cpp.

References d0, FACTOR_100NS_PER_MICROSECOND, FACTOR_100NS_PER_MILLISECOND, FACTOR_NANOSECONDS_PER_100NS, GregorianFromFixed_Adjusted(), i64FloorDivisionMod(), FIELDEDTIME::iDayOfMonth, FIELDEDTIME::iDayOfWeek, FIELDEDTIME::iDayOfYear, FIELDEDTIME::iHour, FIELDEDTIME::iMicrosecond, FIELDEDTIME::iMillisecond, FIELDEDTIME::iMinute, FIELDEDTIME::iMonth, FIELDEDTIME::iNanosecond, FIELDEDTIME::iSecond, isValidDate(), and FIELDEDTIME::iYear.

Referenced by CLinearTimeAbsolute::ReturnDateString(), CLinearTimeAbsolute::ReturnFields(), and CLinearTimeAbsolute::ReturnUniqueString().

01358 {
01359     INT64 ns100;
01360     int iYear, iMonth, iDayOfYear, iDayOfMonth, iDayOfWeek;
01361 
01362     memset(ft, 0, sizeof(FIELDEDTIME));
01363     int d0 = (int)i64FloorDivisionMod(lt, FACTOR_100NS_PER_DAY, &ns100);
01364     GregorianFromFixed_Adjusted(d0, iYear, iMonth, iDayOfYear, iDayOfMonth, iDayOfWeek);
01365     if (!isValidDate(iYear, iMonth, iDayOfMonth))
01366     {
01367         return false;
01368     }
01369 
01370     ft->iYear = iYear;
01371     ft->iMonth = iMonth;
01372     ft->iDayOfYear = iDayOfYear;
01373     ft->iDayOfMonth = iDayOfMonth;
01374     ft->iDayOfWeek = iDayOfWeek;
01375 
01376     ft->iHour = (int)(ns100 / FACTOR_100NS_PER_HOUR);
01377     ns100 = ns100 % FACTOR_100NS_PER_HOUR;
01378     ft->iMinute = (int)(ns100 / FACTOR_100NS_PER_MINUTE);
01379     ns100 = ns100 % FACTOR_100NS_PER_MINUTE;
01380     ft->iSecond = (int)(ns100 / FACTOR_100NS_PER_SECOND);
01381     ns100 = ns100 % FACTOR_100NS_PER_SECOND;
01382 
01383     ft->iMillisecond = (int)(ns100 / FACTOR_100NS_PER_MILLISECOND);
01384     ns100 = ns100 % FACTOR_100NS_PER_MILLISECOND;
01385     ft->iMicrosecond = (int)(ns100 / FACTOR_100NS_PER_MICROSECOND);
01386     ns100 = ns100 % FACTOR_100NS_PER_MICROSECOND;
01387     ft->iNanosecond = (int)(ns100 * FACTOR_NANOSECONDS_PER_100NS);
01388 
01389     return true;
01390 }

CLinearTimeDelta operator * ( const CLinearTimeDelta ltd,
int  Scale 
)

Definition at line 1207 of file timeutil.cpp.

References CLinearTimeDelta::m_tDelta.

01208 {
01209     CLinearTimeDelta ltdResult;
01210     ltdResult.m_tDelta = ltd.m_tDelta * Scale;
01211     return ltdResult;
01212 }

bool operator!= ( const CLinearTimeDelta lta,
const CLinearTimeDelta ltb 
)

Definition at line 439 of file timeutil.cpp.

References CLinearTimeDelta::m_tDelta.

00440 {
00441     return lta.m_tDelta != ltb.m_tDelta;
00442 }

CLinearTimeAbsolute operator+ ( const CLinearTimeAbsolute ltaA,
const CLinearTimeDelta ltdB 
)

Definition at line 1195 of file timeutil.cpp.

References CLinearTimeAbsolute::m_tAbsolute, and CLinearTimeDelta::m_tDelta.

01196 {
01197     CLinearTimeAbsolute lta;
01198     lta.m_tAbsolute = ltaA.m_tAbsolute + ltdB.m_tDelta;
01199     return lta;
01200 }

CLinearTimeDelta operator- ( const CLinearTimeDelta lta,
const CLinearTimeDelta ltb 
)

Definition at line 1188 of file timeutil.cpp.

References CLinearTimeDelta::m_tDelta.

01189 {
01190     CLinearTimeDelta ltd;
01191     ltd.m_tDelta = lta.m_tDelta - ltb.m_tDelta;
01192     return ltd;
01193 }

CLinearTimeDelta operator- ( const CLinearTimeAbsolute ltaA,
const CLinearTimeAbsolute ltaB 
)

Definition at line 1181 of file timeutil.cpp.

References CLinearTimeAbsolute::m_tAbsolute, and CLinearTimeDelta::m_tDelta.

01182 {
01183     CLinearTimeDelta ltd;
01184     ltd.m_tDelta = ltaA.m_tAbsolute - ltaB.m_tAbsolute;
01185     return ltd;
01186 }

CLinearTimeAbsolute operator- ( const CLinearTimeAbsolute lta,
const CLinearTimeDelta ltd 
)

Definition at line 454 of file timeutil.cpp.

References CLinearTimeAbsolute::m_tAbsolute, and CLinearTimeDelta::m_tDelta.

00455 {
00456     CLinearTimeAbsolute t;
00457     t.m_tAbsolute = lta.m_tAbsolute - ltd.m_tDelta;
00458     return t;
00459 }

int operator/ ( const CLinearTimeDelta ltdA,
const CLinearTimeDelta ltdB 
)

Definition at line 1214 of file timeutil.cpp.

References CLinearTimeDelta::m_tDelta.

01215 {
01216     int iResult = (int)(ltdA.m_tDelta / ltdB.m_tDelta);
01217     return iResult;
01218 }

bool operator< ( const CLinearTimeDelta ltdA,
const CLinearTimeDelta ltdB 
)

Definition at line 1220 of file timeutil.cpp.

References CLinearTimeDelta::m_tDelta.

01221 {
01222     return ltdA.m_tDelta < ltdB.m_tDelta;
01223 }

bool operator< ( const CLinearTimeAbsolute lta,
const CLinearTimeAbsolute ltb 
)

Definition at line 419 of file timeutil.cpp.

References CLinearTimeAbsolute::m_tAbsolute.

00420 {
00421     return lta.m_tAbsolute < ltb.m_tAbsolute;
00422 }

bool operator<= ( const CLinearTimeAbsolute lta,
const CLinearTimeAbsolute ltb 
)

Definition at line 449 of file timeutil.cpp.

References CLinearTimeAbsolute::m_tAbsolute.

00450 {
00451     return lta.m_tAbsolute <= ltb.m_tAbsolute;
00452 }

bool operator<= ( const CLinearTimeDelta lta,
const CLinearTimeDelta ltb 
)

Definition at line 444 of file timeutil.cpp.

References CLinearTimeDelta::m_tDelta.

00445 {
00446     return lta.m_tDelta <= ltb.m_tDelta;
00447 }

bool operator== ( const CLinearTimeDelta lta,
const CLinearTimeDelta ltb 
)

Definition at line 434 of file timeutil.cpp.

References CLinearTimeDelta::m_tDelta.

00435 {
00436     return lta.m_tDelta == ltb.m_tDelta;
00437 }

bool operator== ( const CLinearTimeAbsolute lta,
const CLinearTimeAbsolute ltb 
)

Definition at line 429 of file timeutil.cpp.

References CLinearTimeAbsolute::m_tAbsolute.

00430 {
00431     return lta.m_tAbsolute == ltb.m_tAbsolute;
00432 }

bool operator> ( const CLinearTimeDelta ltdA,
const CLinearTimeDelta ltdB 
)

Definition at line 1225 of file timeutil.cpp.

References CLinearTimeDelta::m_tDelta.

01226 {
01227     return ltdA.m_tDelta > ltdB.m_tDelta;
01228 }

bool operator> ( const CLinearTimeAbsolute lta,
const CLinearTimeAbsolute ltb 
)

Definition at line 424 of file timeutil.cpp.

References CLinearTimeAbsolute::m_tAbsolute.

00425 {
00426     return lta.m_tAbsolute > ltb.m_tAbsolute;
00427 }

bool ParseDate ( CLinearTimeAbsolute lt,
char *  pDateString,
bool *  pbZoneSpecified 
)

Definition at line 4045 of file timeutil.cpp.

References ConvertAllFieldsToLinearTime(), tag_AllFields::iMinuteTimeZone, NOT_PRESENT, PD_AppendNode(), PD_BreakItDown(), PD_Deduction(), PD_GetFields(), PD_Pass2(), PD_Pass5(), PD_Pass6(), PD_Reset(), and PD_ScanNextToken().

Referenced by FUNCTION().

04050 {
04051     PD_Reset();
04052 
04053     char *p = pDateString;
04054     PD_Node *pNode;
04055     while ((pNode = PD_ScanNextToken(&p)))
04056     {
04057         PD_AppendNode(pNode);
04058     }
04059 
04060     PD_Pass2();
04061 
04062     PD_Deduction();
04063     PD_BreakItDown();
04064     PD_Pass5();
04065     PD_Pass6();
04066 
04067     PD_Deduction();
04068     PD_BreakItDown();
04069     PD_Pass5();
04070     PD_Pass6();
04071 
04072     ALLFIELDS af;
04073     if (  PD_GetFields(&af)
04074        && ConvertAllFieldsToLinearTime(lt, &af))
04075     {
04076         *pbZoneSpecified = (af.iMinuteTimeZone != NOT_PRESENT);
04077         return true;
04078     }
04079     return false;
04080 }

static void ParseDecimalSeconds ( size_t  n,
const char *  p,
unsigned short *  iMilli,
unsigned short *  iMicro,
unsigned short *  iNano 
) [static]

Definition at line 1003 of file timeutil.cpp.

References mux_atol().

Referenced by PD_GetFields().

01005 {
01006    char aBuffer[10];
01007    if (n > sizeof(aBuffer) - 1)
01008    {
01009        n = sizeof(aBuffer) - 1;
01010    }
01011    memcpy(aBuffer, p, n);
01012    memset(aBuffer + n, '0', sizeof(aBuffer) - n - 1);
01013    aBuffer[sizeof(aBuffer) - 1] = '\0';
01014    int ns = mux_atol(aBuffer);
01015    *iNano = ns % 1000;
01016    ns /= 1000;
01017    *iMicro = ns % 1000;
01018    *iMilli = ns / 1000;
01019 }

static bool ParseFractionalSecondsString ( INT64 i64,
char *  str 
) [static]

Definition at line 466 of file timeutil.cpp.

References INT64_MAX_VALUE, INT64_MIN_VALUE, mux_atoi64(), mux_isdigit, mux_isspace, and PFSS_PRECISION.

Referenced by CLinearTimeAbsolute::SetSecondsString(), and CLinearTimeDelta::SetSecondsString().

00467 {
00468     bool bMinus = false;
00469 
00470     i64 = 0;
00471 
00472     bool bGotOne;
00473 
00474     // Leading spaces.
00475     //
00476     while (mux_isspace(*str))
00477     {
00478         str++;
00479     }
00480 
00481     // Leading minus
00482     //
00483     if (*str == '-')
00484     {
00485         bMinus = true;
00486         str++;
00487 
00488         // But not if just a minus
00489         //
00490         if (!*str)
00491         {
00492             return false;
00493         }
00494     }
00495 
00496     // Need at least one digit.
00497     //
00498     bGotOne = false;
00499     char *pIntegerStart = str;
00500     if (mux_isdigit(*str))
00501     {
00502         bGotOne = true;
00503         str++;
00504     }
00505 
00506     // The number (int)
00507     //
00508     while (mux_isdigit(*str))
00509     {
00510         str++;
00511     }
00512     char *pIntegerEnd = str;
00513 
00514     // Decimal point.
00515     //
00516     if (*str == '.')
00517     {
00518         str++;
00519     }
00520 
00521     // Need at least one digit
00522     //
00523     char *pFractionalStart = str;
00524     if (mux_isdigit(*str))
00525     {
00526         bGotOne = true;
00527         str++;
00528     }
00529 
00530     // The number (fract)
00531     //
00532     while (mux_isdigit(*str))
00533     {
00534         str++;
00535     }
00536     char *pFractionalEnd = str;
00537 
00538     // Trailing spaces.
00539     //
00540     while (mux_isspace(*str))
00541     {
00542         str++;
00543     }
00544 
00545     if (*str || !bGotOne)
00546     {
00547         return false;
00548     }
00549 
00550 #define PFSS_PRECISION 7
00551     char   aBuffer[64];
00552     size_t nBufferAvailable = sizeof(aBuffer) - PFSS_PRECISION - 1;
00553     char  *p = aBuffer;
00554 
00555     // Sign.
00556     //
00557     if (bMinus)
00558     {
00559         *p++ = '-';
00560         nBufferAvailable--;
00561     }
00562 
00563     // Integer part.
00564     //
00565     bool bOverUnderflow = false;
00566     size_t n = pIntegerEnd - pIntegerStart;
00567     if (n > 0)
00568     {
00569         if (n > nBufferAvailable)
00570         {
00571             bOverUnderflow = true;
00572             n = nBufferAvailable;
00573         }
00574         memcpy(p, pIntegerStart, n);
00575         p += n;
00576         nBufferAvailable -= n;
00577     }
00578 
00579     // Fractional part.
00580     //
00581     n = pFractionalEnd - pFractionalStart;
00582     if (n > 0)
00583     {
00584         if (n > PFSS_PRECISION)
00585         {
00586             n = PFSS_PRECISION;
00587         }
00588         memcpy(p, pFractionalStart, n);
00589         p += n;
00590         nBufferAvailable -= n;
00591     }
00592 
00593     // Handle trailing zeroes.
00594     //
00595     n = PFSS_PRECISION - n;
00596     if (n > 0)
00597     {
00598         memset(p, '0', n);
00599         p += n;
00600     }
00601     *p++ = '\0';
00602 
00603     if (bOverUnderflow)
00604     {
00605         if (bMinus)
00606         {
00607             i64 = INT64_MIN_VALUE;
00608         }
00609         else
00610         {
00611             i64 = INT64_MAX_VALUE;
00612         }
00613     }
00614     else
00615     {
00616         i64 = mux_atoi64(aBuffer);
00617     }
00618     return true;
00619 }

static bool ParseThreeLetters ( const char **  pp,
int *  piHash 
) [static]

Definition at line 957 of file timeutil.cpp.

References mux_isalpha, and mux_toupper.

Referenced by do_convtime().

00958 {
00959     *piHash = 0;
00960 
00961     // Skip Initial spaces
00962     //
00963     const char *p = *pp;
00964     while (*p == ' ')
00965     {
00966         p++;
00967     }
00968 
00969     // Parse space-separate token.
00970     //
00971     const char *q = p;
00972     int iHash = 0;
00973     while (*q && *q != ' ')
00974     {
00975         if (!mux_isalpha(*q))
00976         {
00977             return false;
00978         }
00979         iHash = (iHash << 8) | mux_toupper(*q);
00980         q++;
00981     }
00982 
00983     // Must be exactly 3 letters long.
00984     //
00985     if (q - p != 3)
00986     {
00987         return false;
00988     }
00989     p = q;
00990 
00991     // Skip final spaces
00992     //
00993     while (*p == ' ')
00994     {
00995         p++;
00996     }
00997 
00998     *pp = p;
00999     *piHash = iHash;
01000     return true;
01001 }

void PD_AppendNode ( PD_Node pNode  )  [static]

Definition at line 3148 of file timeutil.cpp.

References PD_Head, PD_Tail, tag_pd_node::pNextNode, and tag_pd_node::pPrevNode.

Referenced by ParseDate().

03149 {
03150     if (!PD_Head)
03151     {
03152         PD_Head = PD_Tail = pNode;
03153         return;
03154     }
03155     pNode->pNextNode = 0;
03156     PD_Tail->pNextNode = pNode;
03157     pNode->pPrevNode = PD_Tail;
03158     PD_Tail = pNode;
03159 }

static void PD_BreakItDown ( void   )  [static]

Definition at line 3543 of file timeutil.cpp.

References BreakDownTable, tag_pd_breakdown::fpBreakDown, tag_pd_breakdown::mask, PD_FirstNode(), PD_NextNode(), and tag_pd_node::uCouldBe.

Referenced by ParseDate().

03544 {
03545     PD_Node *pNode = PD_FirstNode();
03546     while (pNode)
03547     {
03548         int j =0;
03549         while (BreakDownTable[j].mask)
03550         {
03551             if (pNode->uCouldBe == BreakDownTable[j].mask)
03552             {
03553                 BreakDownTable[j].fpBreakDown(pNode);
03554                 break;
03555             }
03556             j++;
03557         }
03558         pNode = PD_NextNode(pNode);
03559     }
03560 }

static void PD_Deduction ( void   )  [static]

Definition at line 3518 of file timeutil.cpp.

References tag_pd_cantbe::cantbe, CantBeTable, tag_pd_cantbe::mask, PD_FirstNode(), PD_NextNode(), and tag_pd_node::uCouldBe.

Referenced by ParseDate().

03519 {
03520     PD_Node *pNode = PD_FirstNode();
03521     while (pNode)
03522     {
03523         int j =0;
03524         while (CantBeTable[j].mask)
03525         {
03526             if (pNode->uCouldBe == CantBeTable[j].mask)
03527             {
03528                 PD_Node *pNodeInner = PD_FirstNode();
03529                 while (pNodeInner)
03530                 {
03531                     pNodeInner->uCouldBe &= ~CantBeTable[j].cantbe;
03532                     pNodeInner = PD_NextNode(pNodeInner);
03533                 }
03534                 pNode->uCouldBe = CantBeTable[j].mask;
03535                 break;
03536             }
03537             j++;
03538         }
03539         pNode = PD_NextNode(pNode);
03540     }
03541 }

static PD_Node* PD_FirstNode ( void   )  [static]

Definition at line 3118 of file timeutil.cpp.

References PD_Head.

Referenced by PD_BreakItDown(), PD_Deduction(), PD_GetFields(), PD_Pass2(), PD_Pass5(), and PD_Pass6().

03119 {
03120     return PD_Head;
03121 }

static bool PD_GetFields ( ALLFIELDS paf  )  [static]

Definition at line 3785 of file timeutil.cpp.

References tag_AllFields::iDayOfMonth, tag_AllFields::iDayOfWeek, tag_AllFields::iDayOfYear, tag_AllFields::iHourTime, tag_AllFields::iMicrosecondTime, tag_AllFields::iMillisecondTime, tag_AllFields::iMinuteTime, tag_AllFields::iMinuteTimeZone, tag_AllFields::iMonthOfYear, tag_AllFields::iNanosecondTime, tag_AllFields::iSecondTime, tag_pd_node::iToken, tag_AllFields::iWeekOfYear, tag_AllFields::iYear, NOT_PRESENT, tag_pd_node::nToken, ParseDecimalSeconds(), PD_FirstNode(), PD_NextNode(), PD_PrevNode(), PDCB_DATE_TIME_SEPARATOR, PDCB_DAY_OF_MONTH, PDCB_DAY_OF_WEEK, PDCB_DAY_OF_YEAR, PDCB_HOUR_TIME, PDCB_HOUR_TIMEZONE, PDCB_MERIDIAN, PDCB_MINUTE, PDCB_MONTH, PDCB_SECOND, PDCB_SIGN, PDCB_SUBSECOND, PDCB_TIMEZONE, PDCB_WEEK_OF_YEAR, PDCB_YEAR, tag_pd_node::pToken, and tag_pd_node::uCouldBe.

Referenced by ParseDate().

03786 {
03787     paf->iYear            = NOT_PRESENT;
03788     paf->iDayOfYear       = NOT_PRESENT;
03789     paf->iMonthOfYear     = NOT_PRESENT;
03790     paf->iDayOfMonth      = NOT_PRESENT;
03791     paf->iWeekOfYear      = NOT_PRESENT;
03792     paf->iDayOfWeek       = NOT_PRESENT;
03793     paf->iHourTime        = NOT_PRESENT;
03794     paf->iMinuteTime      = NOT_PRESENT;
03795     paf->iSecondTime      = NOT_PRESENT;
03796     paf->iMillisecondTime = NOT_PRESENT;
03797     paf->iMicrosecondTime = NOT_PRESENT;
03798     paf->iNanosecondTime  = NOT_PRESENT;
03799     paf->iMinuteTimeZone  = NOT_PRESENT;
03800 
03801     PD_Node *pNode = PD_FirstNode();
03802     while (pNode)
03803     {
03804         if (pNode->uCouldBe == PDCB_YEAR)
03805         {
03806             paf->iYear = pNode->iToken;
03807             PD_Node *pPrev = PD_PrevNode(pNode);
03808             if (  pPrev
03809                && pPrev->uCouldBe == PDCB_SIGN
03810                && pPrev->pToken[0] == '-')
03811             {
03812                 paf->iYear = -paf->iYear;
03813             }
03814         }
03815         else if (pNode->uCouldBe == PDCB_DAY_OF_YEAR)
03816         {
03817             paf->iDayOfYear = pNode->iToken;
03818         }
03819         else if (pNode->uCouldBe == PDCB_MONTH)
03820         {
03821             paf->iMonthOfYear = pNode->iToken;
03822         }
03823         else if (pNode->uCouldBe == PDCB_DAY_OF_MONTH)
03824         {
03825             paf->iDayOfMonth = pNode->iToken;
03826         }
03827         else if (pNode->uCouldBe == PDCB_WEEK_OF_YEAR)
03828         {
03829             paf->iWeekOfYear = pNode->iToken;
03830         }
03831         else if (pNode->uCouldBe == PDCB_DAY_OF_WEEK)
03832         {
03833             paf->iDayOfWeek = pNode->iToken;
03834         }
03835         else if (pNode->uCouldBe == PDCB_HOUR_TIME)
03836         {
03837             paf->iHourTime = pNode->iToken;
03838             pNode = PD_NextNode(pNode);
03839             if (  pNode
03840                && pNode->uCouldBe == PDCB_MINUTE)
03841             {
03842                 paf->iMinuteTime = pNode->iToken;
03843                 pNode = PD_NextNode(pNode);
03844                 if (  pNode
03845                    && pNode->uCouldBe == PDCB_SECOND)
03846                 {
03847                     paf->iSecondTime = pNode->iToken;
03848                     pNode = PD_NextNode(pNode);
03849                     if (  pNode
03850                        && pNode->uCouldBe == PDCB_SUBSECOND)
03851                     {
03852                         unsigned short ms, us, ns;
03853                         ParseDecimalSeconds(pNode->nToken, pNode->pToken, &ms,
03854                             &us, &ns);
03855 
03856                         paf->iMillisecondTime = ms;
03857                         paf->iMicrosecondTime = us;
03858                         paf->iNanosecondTime  = ns;
03859                         pNode = PD_NextNode(pNode);
03860                     }
03861                 }
03862             }
03863             if (  pNode
03864                && pNode->uCouldBe == PDCB_MERIDIAN)
03865             {
03866                 if (paf->iHourTime == 12)
03867                 {
03868                     paf->iHourTime = 0;
03869                 }
03870                 paf->iHourTime += pNode->iToken;
03871                 pNode = PD_NextNode(pNode);
03872             }
03873             continue;
03874         }
03875         else if (pNode->uCouldBe == PDCB_HOUR_TIMEZONE)
03876         {
03877             paf->iMinuteTimeZone = pNode->iToken * 60;
03878             PD_Node *pPrev = PD_PrevNode(pNode);
03879             if (  pPrev
03880                && pPrev->uCouldBe == PDCB_SIGN
03881                && pPrev->pToken[0] == '-')
03882             {
03883                 paf->iMinuteTimeZone = -paf->iMinuteTimeZone;
03884             }
03885             pNode = PD_NextNode(pNode);
03886             if (  pNode
03887                && pNode->uCouldBe == PDCB_MINUTE)
03888             {
03889                 if (paf->iMinuteTimeZone < 0)
03890                 {
03891                     paf->iMinuteTimeZone -= pNode->iToken;
03892                 }
03893                 else
03894                 {
03895                     paf->iMinuteTimeZone += pNode->iToken;
03896                 }
03897                 pNode = PD_NextNode(pNode);
03898             }
03899             continue;
03900         }
03901         else if (pNode->uCouldBe == PDCB_TIMEZONE)
03902         {
03903             if (pNode->iToken < 0)
03904             {
03905                 paf->iMinuteTimeZone = (pNode->iToken / 100) * 60
03906                                 - ((-pNode->iToken) % 100);
03907             }
03908             else
03909             {
03910                 paf->iMinuteTimeZone = (pNode->iToken / 100) * 60
03911                                 + pNode->iToken % 100;
03912             }
03913         }
03914         else if (pNode->uCouldBe & (PDCB_SIGN|PDCB_DATE_TIME_SEPARATOR))
03915         {
03916             ; // Nothing
03917         }
03918         else
03919         {
03920             return false;
03921         }
03922         pNode = PD_NextNode(pNode);
03923     }
03924     return true;
03925 }

void PD_InsertAfter ( PD_Node pWhere,
PD_Node pNode 
) [static]

Definition at line 3161 of file timeutil.cpp.

References PD_Tail, tag_pd_node::pNextNode, and tag_pd_node::pPrevNode.

Referenced by SplitLastThreeDigits(), and SplitLastTwoDigits().

03162 {
03163     pNode->pPrevNode = pWhere;
03164     pNode->pNextNode = pWhere->pNextNode;
03165 
03166     pWhere->pNextNode = pNode;
03167     if (pNode->pNextNode)
03168     {
03169         pNode->pNextNode->pPrevNode = pNode;
03170     }
03171     else
03172     {
03173         PD_Tail = pNode;
03174     }
03175 }

PD_Node * PD_NewNode ( void   )  [static]

Definition at line 3109 of file timeutil.cpp.

References MAX_NODES, and Nodes.

Referenced by PD_ScanNextToken(), SplitLastThreeDigits(), and SplitLastTwoDigits().

03110 {
03111     if (nNodes < MAX_NODES)
03112     {
03113         return Nodes+(nNodes++);
03114     }
03115     return NULL;
03116 }

static PD_Node* PD_NextNode ( PD_Node pNode  )  [static]

Definition at line 3130 of file timeutil.cpp.

References tag_pd_node::pNextNode.

Referenced by PD_BreakItDown(), PD_Deduction(), PD_GetFields(), PD_Pass2(), PD_Pass5(), and PD_Pass6().

03131 {
03132     return pNode->pNextNode;
03133 }

static void PD_Pass2 ( void   )  [static]

Definition at line 3342 of file timeutil.cpp.

References PD_FirstNode(), PD_NextNode(), PD_PrevNode(), PD_RemoveNode(), PDCB_DATE_FIELD_SEPARATOR, PDCB_DAY_OF_MONTH, PDCB_DAY_OF_MONTH_SUFFIX, PDCB_HMS_TIME, PDCB_HMS_TIMEZONE, PDCB_HOUR_TIME, PDCB_HOUR_TIMEZONE, PDCB_MINUTE, PDCB_REMOVEABLE, PDCB_SECOND, PDCB_SECONDS_DECIMAL, PDCB_SEPS, PDCB_SIGN, PDCB_SIGNABLES_NEG, PDCB_SIGNABLES_POS, PDCB_SUBSECOND, PDCB_TIME_FIELD_SEPARATOR, PDCB_WHITESPACE, tag_pd_node::pToken, and tag_pd_node::uCouldBe.

Referenced by ParseDate().

03343 {
03344     PD_Node *pNode = PD_FirstNode();
03345     while (pNode)
03346     {
03347         PD_Node *pPrev = PD_PrevNode(pNode);
03348         PD_Node *pNext = PD_NextNode(pNode);
03349 
03350         // Absorb information from PDCB_TIME_FIELD_SEPARATOR.
03351         //
03352         if (pNode->uCouldBe & PDCB_TIME_FIELD_SEPARATOR)
03353         {
03354             if (pPrev && pNext)
03355             {
03356                 if (  (pPrev->uCouldBe & (PDCB_HOUR_TIME|PDCB_HOUR_TIMEZONE))
03357                    && (pNext->uCouldBe & PDCB_MINUTE))
03358                 {
03359                     pPrev->uCouldBe &= (PDCB_HOUR_TIME|PDCB_HOUR_TIMEZONE);
03360                     pNext->uCouldBe = PDCB_MINUTE;
03361                 }
03362                 else if (  (pPrev->uCouldBe & PDCB_MINUTE)
03363                         && (pNext->uCouldBe & PDCB_SECOND))
03364                 {
03365                     pPrev->uCouldBe = PDCB_MINUTE;
03366                     pNext->uCouldBe = PDCB_SECOND;
03367                 }
03368             }
03369             pNode->uCouldBe = PDCB_REMOVEABLE;
03370         }
03371 
03372         // Absorb information from PDCB_SECONDS_DECIMAL.
03373         //
03374         if (pNode->uCouldBe & PDCB_SECONDS_DECIMAL)
03375         {
03376             if (  pPrev
03377                && pNext
03378                && pPrev->uCouldBe == PDCB_SECOND
03379                && (pNext->uCouldBe & PDCB_SUBSECOND))
03380             {
03381                 pNode->uCouldBe = PDCB_SECONDS_DECIMAL;
03382                 pNext->uCouldBe = PDCB_SUBSECOND;
03383             }
03384             else
03385             {
03386                 pNode->uCouldBe &= ~PDCB_SECONDS_DECIMAL;
03387             }
03388             pNode->uCouldBe = PDCB_REMOVEABLE;
03389         }
03390 
03391         // Absorb information from PDCB_SUBSECOND
03392         //
03393         if (pNode->uCouldBe != PDCB_SUBSECOND)
03394         {
03395             pNode->uCouldBe &= ~PDCB_SUBSECOND;
03396         }
03397 
03398         // Absorb information from PDCB_DATE_FIELD_SEPARATOR.
03399         //
03400         if (pNode->uCouldBe & PDCB_DATE_FIELD_SEPARATOR)
03401         {
03402             pNode->uCouldBe &= ~PDCB_DATE_FIELD_SEPARATOR;
03403 
03404 #define PDCB_SEPS (PDCB_YEAR|PDCB_MONTH|PDCB_DAY_OF_MONTH|PDCB_DAY_OF_YEAR|PDCB_WEEK_OF_YEAR|PDCB_DAY_OF_WEEK)
03405             if (  pPrev
03406                && pNext
03407                && (pPrev->uCouldBe & PDCB_SEPS)
03408                && (pNext->uCouldBe & PDCB_SEPS))
03409             {
03410                 pPrev->uCouldBe &= PDCB_SEPS;
03411                 pNext->uCouldBe &= PDCB_SEPS;
03412                 pNode->uCouldBe = PDCB_REMOVEABLE;
03413             }
03414         }
03415 
03416 
03417         // Process PDCB_DAY_OF_MONTH_SUFFIX
03418         //
03419         if (pNode->uCouldBe & PDCB_DAY_OF_MONTH_SUFFIX)
03420         {
03421             pNode->uCouldBe = PDCB_REMOVEABLE;
03422             if (  pPrev
03423                && (pPrev->uCouldBe & PDCB_DAY_OF_MONTH))
03424             {
03425                 pPrev->uCouldBe = PDCB_DAY_OF_MONTH;
03426             }
03427         }
03428 
03429         // Absorb semantic meaning of PDCB_SIGN.
03430         //
03431         if (pNode->uCouldBe == PDCB_SIGN)
03432         {
03433 #define PDCB_SIGNABLES_POS (PDCB_HMS_TIME|PDCB_HMS_TIMEZONE)
03434 #define PDCB_SIGNABLES_NEG (PDCB_YEAR|PDCB_YD|PDCB_SIGNABLES_POS|PDCB_YMD)
03435             unsigned Signable;
03436             if (pNode->pToken[0] == '-')
03437             {
03438                 Signable = PDCB_SIGNABLES_NEG;
03439             }
03440             else
03441             {
03442                 Signable = PDCB_SIGNABLES_POS;
03443             }
03444             if (  pNext
03445                && (pNext->uCouldBe & Signable))
03446             {
03447                 pNext->uCouldBe &= Signable;
03448             }
03449             else
03450             {
03451                 pNode->uCouldBe = PDCB_REMOVEABLE;
03452             }
03453         }
03454 
03455         // A timezone HOUR or HMS requires a leading sign.
03456         //
03457         if (pNode->uCouldBe & (PDCB_HMS_TIMEZONE|PDCB_HOUR_TIMEZONE))
03458         {
03459             if (  !pPrev
03460                || pPrev->uCouldBe != PDCB_SIGN)
03461             {
03462                 pNode->uCouldBe &= ~(PDCB_HMS_TIMEZONE|PDCB_HOUR_TIMEZONE);
03463             }
03464         }
03465 
03466         // Likewise, a PDCB_HOUR_TIME or PDCB_HMS_TIME cannot have a
03467         // leading sign.
03468         //
03469         if (pNode->uCouldBe & (PDCB_HMS_TIME|PDCB_HOUR_TIME))
03470         {
03471             if (  pPrev
03472                && pPrev->uCouldBe == PDCB_SIGN)
03473             {
03474                 pNode->uCouldBe &= ~(PDCB_HMS_TIME|PDCB_HOUR_TIME);
03475             }
03476         }
03477 
03478         // Remove PDCB_WHITESPACE.
03479         //
03480         if (pNode->uCouldBe & (PDCB_WHITESPACE|PDCB_REMOVEABLE))
03481         {
03482             PD_RemoveNode(pNode);
03483         }
03484         pNode = pNext;
03485     }
03486 }

static void PD_Pass5 ( void   )  [static]

Definition at line 3562 of file timeutil.cpp.

References PD_FirstNode(), PD_NextNode(), PD_PrevNode(), PD_RemoveNode(), PDCB_DATE_TIME_SEPARATOR, PDCB_DAY_OF_MONTH, PDCB_DAY_OF_WEEK, PDCB_DAY_OF_YEAR, PDCB_DMY, PDCB_HMS_TIME, PDCB_HMS_TIMEZONE, PDCB_HOUR_TIME, PDCB_HOUR_TIMEZONE, PDCB_MDY, PDCB_MERIDIAN, PDCB_MINUTE, PDCB_MONTH, PDCB_REMOVEABLE, PDCB_SECOND, PDCB_SUBSECOND, PDCB_TIMEZONE, PDCB_WEEK_OF_YEAR, PDCB_WEEK_OF_YEAR_PREFIX, PDCB_YD, PDCB_YEAR, and tag_pd_node::uCouldBe.

Referenced by ParseDate().

03563 {
03564     bool bHaveSeenTimeHour = false;
03565     bool bMightHaveSeenTimeHour = false;
03566     PD_Node *pNode = PD_FirstNode();
03567     while (pNode)
03568     {
03569         PD_Node *pPrev = PD_PrevNode(pNode);
03570         PD_Node *pNext = PD_NextNode(pNode);
03571 
03572         // If all that is left is PDCB_HMS_TIME and PDCB_HOUR_TIME, then
03573         // it's PDCB_HOUR_TIME.
03574         //
03575         if (pNode->uCouldBe == (PDCB_HMS_TIME|PDCB_HOUR_TIME))
03576         {
03577             pNode->uCouldBe = PDCB_HOUR_TIME;
03578         }
03579         if (pNode->uCouldBe == (PDCB_HMS_TIMEZONE|PDCB_HOUR_TIMEZONE))
03580         {
03581             pNode->uCouldBe = PDCB_HOUR_TIMEZONE;
03582         }
03583 
03584         // PDCB_MINUTE must follow an PDCB_HOUR_TIME or PDCB_HOUR_TIMEZONE.
03585         //
03586         if (pNode->uCouldBe & PDCB_MINUTE)
03587         {
03588             if (  !pPrev
03589                || !(pPrev->uCouldBe & (PDCB_HOUR_TIME|PDCB_HOUR_TIMEZONE)))
03590             {
03591                 pNode->uCouldBe &= ~PDCB_MINUTE;
03592             }
03593         }
03594 
03595         // PDCB_SECOND must follow an PDCB_MINUTE.
03596         //
03597         if (pNode->uCouldBe & PDCB_SECOND)
03598         {
03599             if (  !pPrev
03600                || !(pPrev->uCouldBe & PDCB_MINUTE))
03601             {
03602                 pNode->uCouldBe &= ~PDCB_SECOND;
03603             }
03604         }
03605 
03606         // YMD MDY DMY
03607         //
03608         // PDCB_DAY_OF_MONTH cannot follow PDCB_YEAR.
03609         //
03610         if (  (pNode->uCouldBe & PDCB_DAY_OF_MONTH)
03611            && pPrev
03612            && pPrev->uCouldBe == PDCB_YEAR)
03613         {
03614             pNode->uCouldBe &= ~PDCB_DAY_OF_MONTH;
03615         }
03616 
03617         // Timezone cannot occur before the time.
03618         //
03619         if (  (pNode->uCouldBe & PDCB_TIMEZONE)
03620            && !bMightHaveSeenTimeHour)
03621         {
03622             pNode->uCouldBe &= ~PDCB_TIMEZONE;
03623         }
03624 
03625         // TimeDateSeparator cannot occur after the time.
03626         //
03627         if (  (pNode->uCouldBe & PDCB_DATE_TIME_SEPARATOR)
03628            && bHaveSeenTimeHour)
03629         {
03630             pNode->uCouldBe &= ~PDCB_DATE_TIME_SEPARATOR;
03631         }
03632 
03633         if (pNode->uCouldBe == PDCB_DATE_TIME_SEPARATOR)
03634         {
03635             PD_Node *pNodeInner = PD_FirstNode();
03636             while (pNodeInner && pNodeInner != pNode)
03637             {
03638                 pNodeInner->uCouldBe &= ~(PDCB_TIMEZONE|PDCB_HOUR_TIME|PDCB_HOUR_TIMEZONE|PDCB_MINUTE|PDCB_SECOND|PDCB_SUBSECOND|PDCB_MERIDIAN|PDCB_HMS_TIME|PDCB_HMS_TIMEZONE);
03639                 pNodeInner = PD_NextNode(pNodeInner);
03640             }
03641             pNodeInner = pNext;
03642             while (pNodeInner)
03643             {
03644                 pNodeInner->uCouldBe &= ~(PDCB_WEEK_OF_YEAR_PREFIX|PDCB_YD|PDCB_YMD|PDCB_MDY|PDCB_DMY|PDCB_YEAR|PDCB_MONTH|PDCB_DAY_OF_MONTH|PDCB_DAY_OF_WEEK|PDCB_WEEK_OF_YEAR|PDCB_DAY_OF_YEAR);
03645                 pNodeInner = PD_NextNode(pNodeInner);
03646             }
03647             pNode->uCouldBe = PDCB_REMOVEABLE;
03648         }
03649 
03650         if (pNode->uCouldBe & PDCB_WEEK_OF_YEAR_PREFIX)
03651         {
03652             if (  pNext
03653                && (pNext->uCouldBe & PDCB_WEEK_OF_YEAR))
03654             {
03655                 pNext->uCouldBe = PDCB_WEEK_OF_YEAR;
03656                 pNode->uCouldBe = PDCB_REMOVEABLE;
03657             }
03658             else if (pNode->uCouldBe == PDCB_WEEK_OF_YEAR_PREFIX)
03659             {
03660                 pNode->uCouldBe = PDCB_REMOVEABLE;
03661             }
03662         }
03663 
03664         if (pNode->uCouldBe & (PDCB_HOUR_TIME|PDCB_HMS_TIME))
03665         {
03666             if ((pNode->uCouldBe & ~(PDCB_HOUR_TIME|PDCB_HMS_TIME)) == 0)
03667             {
03668                 bHaveSeenTimeHour = true;
03669             }
03670             bMightHaveSeenTimeHour = true;
03671         }
03672 
03673         // Remove PDCB_REMOVEABLE.
03674         //
03675         if (pNode->uCouldBe & PDCB_REMOVEABLE)
03676         {
03677             PD_RemoveNode(pNode);
03678         }
03679         pNode = pNext;
03680     }
03681 }

static void PD_Pass6 ( void   )  [static]

Definition at line 3683 of file timeutil.cpp.

References PD_FirstNode(), PD_NextNode(), PDCB_DAY_OF_MONTH, PDCB_DAY_OF_WEEK, PDCB_DAY_OF_YEAR, PDCB_DMY, PDCB_HMS_TIME, PDCB_HOUR_TIME, PDCB_MDY, PDCB_MONTH, PDCB_WEEK_OF_YEAR, PDCB_YD, PDCB_YEAR, and tag_pd_node::uCouldBe.

Referenced by ParseDate().

03684 {
03685     int cYear = 0;
03686     int cMonth = 0;
03687     int cDayOfMonth = 0;
03688     int cWeekOfYear = 0;
03689     int cDayOfYear = 0;
03690     int cDayOfWeek = 0;
03691     int cTime = 0;
03692 
03693     PD_Node *pNode = PD_FirstNode();
03694     while (pNode)
03695     {
03696         if (pNode->uCouldBe & (PDCB_HMS_TIME|PDCB_HOUR_TIME))
03697         {
03698             cTime++;
03699         }
03700         if (pNode->uCouldBe & PDCB_WEEK_OF_YEAR)
03701         {
03702             cWeekOfYear++;
03703         }
03704         if (pNode->uCouldBe & (PDCB_YEAR|PDCB_YD|PDCB_YMD|PDCB_MDY|PDCB_DMY))
03705         {
03706             cYear++;
03707         }
03708         if (pNode->uCouldBe & (PDCB_MONTH|PDCB_YMD|PDCB_MDY|PDCB_DMY))
03709         {
03710             cMonth++;
03711         }
03712         if (pNode->uCouldBe & (PDCB_DAY_OF_MONTH|PDCB_YMD|PDCB_MDY|PDCB_DMY))
03713         {
03714             cDayOfMonth++;
03715         }
03716         if (pNode->uCouldBe & PDCB_DAY_OF_WEEK)
03717         {
03718             cDayOfWeek++;
03719         }
03720         if (pNode->uCouldBe & (PDCB_DAY_OF_YEAR|PDCB_YD))
03721         {
03722             cDayOfYear++;
03723         }
03724         pNode = PD_NextNode(pNode);
03725     }
03726 
03727     unsigned OnlyOneMask = 0;
03728     unsigned CantBeMask = 0;
03729     if (cYear == 1)
03730     {
03731         OnlyOneMask |= PDCB_YEAR|PDCB_YD|PDCB_YMD|PDCB_MDY|PDCB_DMY;
03732     }
03733     if (cTime == 1)
03734     {
03735         OnlyOneMask |= PDCB_HMS_TIME|PDCB_HOUR_TIME;
03736     }
03737     if (cMonth == 0 || cDayOfMonth == 0)
03738     {
03739         CantBeMask |= PDCB_MONTH|PDCB_DAY_OF_MONTH;
03740     }
03741     if (cDayOfWeek == 0)
03742     {
03743         CantBeMask |= PDCB_WEEK_OF_YEAR;
03744     }
03745     if (  cMonth == 1 && cDayOfMonth == 1
03746        && (cWeekOfYear != 1 || cDayOfWeek != 1)
03747        && cDayOfYear != 1)
03748     {
03749         OnlyOneMask |= PDCB_MONTH|PDCB_YMD|PDCB_MDY|PDCB_DMY;
03750         OnlyOneMask |= PDCB_DAY_OF_MONTH;
03751         CantBeMask |= PDCB_WEEK_OF_YEAR|PDCB_YD;
03752     }
03753     else if (cDayOfYear == 1 && (cWeekOfYear != 1 || cDayOfWeek != 1))
03754     {
03755         OnlyOneMask |= PDCB_DAY_OF_YEAR|PDCB_YD;
03756         CantBeMask |= PDCB_WEEK_OF_YEAR|PDCB_MONTH|PDCB_YMD|PDCB_MDY|PDCB_DMY;
03757         CantBeMask |= PDCB_DAY_OF_MONTH;
03758     }
03759     else if (cWeekOfYear == 1 && cDayOfWeek == 1)
03760     {
03761         OnlyOneMask |= PDCB_WEEK_OF_YEAR;
03762         OnlyOneMask |= PDCB_DAY_OF_WEEK;
03763         CantBeMask |= PDCB_YD|PDCB_MONTH|PDCB_YMD|PDCB_MDY|PDCB_DMY;
03764         CantBeMask |= PDCB_DAY_OF_MONTH;
03765     }
03766 
03767     // Also, if we match OnlyOneMask, then force only something in
03768     // OnlyOneMask.
03769     //
03770     pNode = PD_FirstNode();
03771     while (pNode)
03772     {
03773         if (pNode->uCouldBe & OnlyOneMask)
03774         {
03775             pNode->uCouldBe &= OnlyOneMask;
03776         }
03777         if (pNode->uCouldBe & ~CantBeMask)
03778         {
03779             pNode->uCouldBe &= ~CantBeMask;
03780         }
03781         pNode = PD_NextNode(pNode);
03782     }
03783 }

static PD_Node* PD_PrevNode ( PD_Node pNode  )  [static]

Definition at line 3135 of file timeutil.cpp.

References tag_pd_node::pPrevNode.

Referenced by PD_GetFields(), PD_Pass2(), and PD_Pass5().

03136 {
03137     return pNode->pPrevNode;
03138 }

static void PD_RemoveNode ( PD_Node pNode  )  [static]

Definition at line 3177 of file timeutil.cpp.

References PD_Head, PD_Tail, tag_pd_node::pNextNode, and tag_pd_node::pPrevNode.

Referenced by PD_Pass2(), and PD_Pass5().

03178 {
03179     if (pNode == PD_Head)
03180     {
03181         if (pNode == PD_Tail)
03182         {
03183             PD_Head = PD_Tail = 0;
03184         }
03185         else
03186         {
03187             PD_Head = pNode->pNextNode;
03188             PD_Head->pPrevNode = 0;
03189             pNode->pNextNode = 0;
03190         }
03191     }
03192     else if (pNode == PD_Tail)
03193     {
03194         PD_Tail = pNode->pPrevNode;
03195         PD_Tail->pNextNode = 0;
03196         pNode->pPrevNode = 0;
03197     }
03198     else
03199     {
03200         pNode->pNextNode->pPrevNode = pNode->pPrevNode;
03201         pNode->pPrevNode->pNextNode = pNode->pNextNode;
03202         pNode->pNextNode = 0;
03203         pNode->pPrevNode = 0;
03204     }
03205 }

static void PD_Reset ( void   )  [static]

Definition at line 3102 of file timeutil.cpp.

References PD_Head, and PD_Tail.

Referenced by ParseDate().

03103 {
03104     nNodes = 0;
03105     PD_Head = 0;
03106     PD_Tail = 0;
03107 }

static PD_Node* PD_ScanNextToken ( char **  ppString  )  [static]

Definition at line 3207 of file timeutil.cpp.

References ClassifyNumericToken(), tag_pd_node::iToken, PD_TEXT_ENTRY::iValue, mux_atol(), mux_memicmp(), tag_pd_node::nToken, PD_LEX_ALPHA, PD_LEX_DIGIT, PD_LEX_EOS, PD_LEX_INVALID, PD_LEX_SPACE, PD_LEX_SYMBOL, PD_NewNode(), PD_TextTable, PDCB_DATE_FIELD_SEPARATOR, PDCB_DAY_OF_MONTH_SUFFIX, PDCB_NOTHING, PDCB_REMOVEABLE, PDCB_SECONDS_DECIMAL, PDCB_SIGN, PDCB_TIME_FIELD_SEPARATOR, PDCB_WHITESPACE, PDTT_NUMERIC_UNSIGNED, PDTT_SPACES, PDTT_SYMBOL, PDTT_TEXT, tag_pd_node::pNextNode, tag_pd_node::pPrevNode, tag_pd_node::pToken, PD_TEXT_ENTRY::uCouldBe, tag_pd_node::uCouldBe, and tag_pd_node::uTokenType.

Referenced by ParseDate().

03208 {
03209     char *p = *ppString;
03210     int ch = *p;
03211     if (ch == 0)
03212     {
03213         return NULL;
03214     }
03215     PD_Node *pNode;
03216     int iType = LexTable[ch];
03217     if (iType == PD_LEX_EOS || iType == PD_LEX_INVALID)
03218     {
03219         return NULL;
03220     }
03221     else if (iType == PD_LEX_SYMBOL)
03222     {
03223         pNode = PD_NewNode();
03224         if (!pNode)
03225         {
03226             return NULL;
03227         }
03228         pNode->pNextNode = 0;
03229         pNode->pPrevNode = 0;
03230         pNode->iToken = 0;
03231         pNode->nToken = 1;
03232         pNode->pToken = p;
03233         pNode->uTokenType = PDTT_SYMBOL;
03234         if (ch == ':')
03235         {
03236             pNode->uCouldBe = PDCB_TIME_FIELD_SEPARATOR;
03237         }
03238         else if (ch == '-')
03239         {
03240             pNode->uCouldBe = PDCB_DATE_FIELD_SEPARATOR|PDCB_SIGN;
03241         }
03242         else if (ch == '+')
03243         {
03244             pNode->uCouldBe = PDCB_SIGN;
03245         }
03246         else if (ch == '/')
03247         {
03248             pNode->uCouldBe = PDCB_DATE_FIELD_SEPARATOR;
03249         }
03250         else if (ch == '.')
03251         {
03252             pNode->uCouldBe = PDCB_DATE_FIELD_SEPARATOR|PDCB_SECONDS_DECIMAL;
03253         }
03254         else if (ch == ',')
03255         {
03256             pNode->uCouldBe = PDCB_REMOVEABLE|PDCB_SECONDS_DECIMAL|PDCB_DAY_OF_MONTH_SUFFIX;
03257         }
03258 
03259         p++;
03260     }
03261     else
03262     {
03263         char *pSave = p;
03264         do
03265         {
03266             p++;
03267             ch = *p;
03268         } while (iType == LexTable[ch]);
03269 
03270         pNode = PD_NewNode();
03271         if (!pNode)
03272         {
03273             return NULL;
03274         }
03275         pNode->pNextNode = 0;
03276         pNode->pPrevNode = 0;
03277         size_t nLen = p - pSave;
03278         pNode->nToken = nLen;
03279         pNode->pToken = pSave;
03280         pNode->iToken = 0;
03281         pNode->uCouldBe = PDCB_NOTHING;
03282 
03283         if (iType == PD_LEX_DIGIT)
03284         {
03285             pNode->uTokenType = PDTT_NUMERIC_UNSIGNED;
03286 
03287             if (1 <= nLen && nLen <= 9)
03288             {
03289                 char buff[10];
03290                 memcpy(buff, pSave, nLen);
03291                 buff[nLen] = '\0';
03292                 pNode->iToken = mux_atol(buff);
03293                 ClassifyNumericToken(pNode);
03294             }
03295         }
03296         else if (iType == PD_LEX_SPACE)
03297         {
03298             pNode->uTokenType = PDTT_SPACES;
03299             pNode->uCouldBe = PDCB_WHITESPACE;
03300         }
03301         else if (iType == PD_LEX_ALPHA)
03302         {
03303             pNode->uTokenType = PDTT_TEXT;
03304 
03305             // Match Text.
03306             //
03307             int j = 0;
03308             bool bFound = false;
03309             while (PD_TextTable[j].szText)
03310             {
03311                 if (  strlen(PD_TextTable[j].szText) == nLen
03312                    && mux_memicmp(PD_TextTable[j].szText, pSave, nLen) == 0)
03313                 {
03314                     pNode->uCouldBe = PD_TextTable[j].uCouldBe;
03315                     pNode->iToken = PD_TextTable[j].iValue;
03316                     bFound = true;
03317                     break;
03318                 }
03319                 j++;
03320             }
03321             if (!bFound)
03322             {
03323                 return NULL;
03324             }
03325         }
03326     }
03327     *ppString = p;
03328     return pNode;
03329 }

static CLinearTimeDelta QueryLocalOffsetAt_Internal ( CLinearTimeAbsolute  lta,
bool *  pisDST,
int  iEntry 
) [static]

Definition at line 2246 of file timeutil.cpp.

References FIELDEDTIME::iMicrosecond, FIELDEDTIME::iMillisecond, FIELDEDTIME::iNanosecond, FIELDEDTIME::iYear, ltaUpperBound, ltdTimeZoneStandard, CLinearTimeAbsolute::ReturnFields(), CLinearTimeAbsolute::ReturnSeconds(), CLinearTimeAbsolute::SetFields(), CLinearTimeAbsolute::SetSeconds(), SetStructTm(), TIME_Initialize(), UpdateOffsetTable(), and YearType().

Referenced by QueryLocalOffsetAtUTC().

02251 {
02252     if (!bTimeInitialized)
02253     {
02254         TIME_Initialize();
02255     }
02256 
02257     // At this point, we must use localtime() to discover what the
02258     // UTC to local time offset is for the requested UTC time.
02259     //
02260     // However, localtime() does not support times beyond around
02261     // the 2038 year on machines with 32-bit integers, so to
02262     // compensant for this, and knowing that we are already dealing
02263     // with fictionalized adjustments, we associate a future year
02264     // that is outside the supported range with one that is inside
02265     // the support range of the same type (there are 14 different
02266     // year types depending on leap-year-ness and which day of the
02267     // week that January 1st falls on.
02268     //
02269     // Note: Laws beyond the current year have not been written yet
02270     // and are subject to change at any time. For example, Israel
02271     // doesn't have regular rules for DST but makes a directive each
02272     // year...sometimes to avoid conflicts with Jewish holidays.
02273     //
02274     if (lta > ltaUpperBound)
02275     {
02276         // Map the specified year to the closest year with the same
02277         // pattern of weeks.
02278         //
02279         FIELDEDTIME ft;
02280         lta.ReturnFields(&ft);
02281         ft.iYear = NearestYearOfType[YearType(ft.iYear)];
02282         lta.SetFields(&ft);
02283     }
02284 
02285     // Rely on localtime() to take a UTC count of seconds and convert
02286     // to a fielded local time complete with known timezone and DST
02287     // adjustments.
02288     //
02289     time_t lt = (time_t)lta.ReturnSeconds();
02290     struct tm *ptm = localtime(&lt);
02291     if (!ptm)
02292     {
02293         // This should never happen as we have already taken pains
02294         // to restrict the range of UTC seconds gives to localtime().
02295         //
02296         return ltdTimeZoneStandard;
02297     }
02298 
02299     // With the fielded (or broken down) time from localtime(), we
02300     // can convert to a linear time in the same time zone.
02301     //
02302     FIELDEDTIME ft;
02303     SetStructTm(&ft, ptm);
02304     ft.iMillisecond = 0;
02305     ft.iMicrosecond = 0;
02306     ft.iNanosecond  = 0;
02307 
02308     CLinearTimeAbsolute ltaLocal;
02309     CLinearTimeDelta ltdOffset;
02310     ltaLocal.SetFields(&ft);
02311     lta.SetSeconds(lt);
02312     ltdOffset = ltaLocal - lta;
02313 
02314     *pisDST = (ptm->tm_isdst > 0);
02315 
02316     // We now have a mapping from UTC lta to a (ltdOffset, *pisDST)
02317     // tuple which will will use to update the cache.
02318     //
02319     UpdateOffsetTable(lta, ltdOffset, *pisDST, iEntry);
02320     return ltdOffset;
02321 }

static CLinearTimeDelta QueryLocalOffsetAtUTC ( const CLinearTimeAbsolute lta,
bool *  pisDST 
) [static]

Definition at line 2324 of file timeutil.cpp.

References ltaLowerBound, ltdIntervalMinimum, ltdTimeZoneStandard, QueryLocalOffsetAt_Internal(), and QueryOffsetTable().

Referenced by CLinearTimeAbsolute::Local2UTC(), and CLinearTimeAbsolute::UTC2Local().

02328 {
02329     *pisDST = false;
02330 
02331     // DST started in Britain in May 1916 and in the US in 1918.
02332     // Germany used it a little before May 1916, but I'm not sure
02333     // of exactly when.
02334     //
02335     // So, there is locale specific information about DST adjustments
02336     // that could reasonable be made between 1916 and 1970.
02337     // Because Unix supports negative time_t values while Win32 does
02338     // not, it can also support that 1916 to 1970 interval with
02339     // timezone information.
02340     //
02341     // Win32 only supports one timezone rule at a time, or rather
02342     // it doesn't have any historical timezone information, but you
02343     // can/must provide it yourself. So, in the Win32 case, unless we
02344     // are willing to provide historical information (from a tzfile
02345     // perhaps), it will only give us the current timezone rule
02346     // (the one selected by the control panel or by a TZ environment
02347     // variable). It projects this rule forwards and backwards.
02348     //
02349     // Feel free to fill that gap in yourself with a tzfile file
02350     // reader for Win32.
02351     //
02352     if (lta < ltaLowerBound)
02353     {
02354         return ltdTimeZoneStandard;
02355     }
02356 
02357     // Next, we check our table for whether this time falls into a
02358     // previously discovered interval. You could view this as a
02359     // cache, or you could also view it as a way of reading in the
02360     // tzfile without becoming system-dependent enough to actually
02361     // read the tzfile.
02362     //
02363     CLinearTimeDelta ltdOffset;
02364     int iEntry;
02365     if (QueryOffsetTable(lta, &ltdOffset, pisDST, &iEntry))
02366     {
02367         return ltdOffset;
02368     }
02369     ltdOffset = QueryLocalOffsetAt_Internal(lta, pisDST, iEntry);
02370 
02371     // Since the cache failed, let's make sure we have a useful
02372     // interval surrounding this last request so that future queries
02373     // nearby will be serviced by the cache.
02374     //
02375     CLinearTimeAbsolute ltaProbe;
02376     CLinearTimeDelta ltdDontCare;
02377     bool bDontCare;
02378 
02379     ltaProbe = lta - ltdIntervalMinimum;
02380     if (!QueryOffsetTable(ltaProbe, &ltdDontCare, &bDontCare, &iEntry))
02381     {
02382         QueryLocalOffsetAt_Internal(ltaProbe, &bDontCare, iEntry);
02383     }
02384 
02385     ltaProbe = lta + ltdIntervalMinimum;
02386     if (!QueryOffsetTable(ltaProbe, &ltdDontCare, &bDontCare, &iEntry))
02387     {
02388         QueryLocalOffsetAt_Internal(ltaProbe, &bDontCare, iEntry);
02389     }
02390     return ltdOffset;
02391 }

static bool QueryOffsetTable ( CLinearTimeAbsolute  lta,
CLinearTimeDelta pltdOffset,
bool *  pisDST,
int *  piEntry 
) [static]

Definition at line 2085 of file timeutil.cpp.

References FindOffsetEntry(), OffsetEntry::isDST, OffsetEntry::ltdOffset, OffsetEntry::nTouched, and OffsetTable.

Referenced by QueryLocalOffsetAtUTC().

02091 {
02092     nTouched0++;
02093 
02094     int i = FindOffsetEntry(lta);
02095     *piEntry = i;
02096 
02097     // Is the interval defined?
02098     //
02099     if (  0 <= i
02100        && lta <= OffsetTable[i].ltaEnd)
02101     {
02102         *pltdOffset = OffsetTable[i].ltdOffset;
02103         *pisDST = OffsetTable[i].isDST;
02104         OffsetTable[i].nTouched = nTouched0;
02105         return true;
02106     }
02107     return false;
02108 }

static void SetStructTm ( FIELDEDTIME ft,
struct tm *  ptm 
) [static]

Definition at line 1246 of file timeutil.cpp.

References FIELDEDTIME::iDayOfMonth, FIELDEDTIME::iDayOfWeek, FIELDEDTIME::iDayOfYear, FIELDEDTIME::iHour, FIELDEDTIME::iMinute, FIELDEDTIME::iMonth, FIELDEDTIME::iSecond, and FIELDEDTIME::iYear.

Referenced by QueryLocalOffsetAt_Internal(), and test_time_t().

01247 {
01248     ft->iYear = ptm->tm_year + 1900;
01249     ft->iMonth = ptm->tm_mon + 1;
01250     ft->iDayOfMonth = ptm->tm_mday;
01251     ft->iDayOfWeek = ptm->tm_wday;
01252     ft->iDayOfYear = 0;
01253     ft->iHour = ptm->tm_hour;
01254     ft->iMinute = ptm->tm_min;
01255     ft->iSecond = ptm->tm_sec;
01256 }

static void SplitLastThreeDigits ( PD_Node pNode,
unsigned  mask 
) [static]

Definition at line 2743 of file timeutil.cpp.

References tag_pd_node::iToken, tag_pd_node::nToken, PD_InsertAfter(), PD_NewNode(), tag_pd_node::pToken, and tag_pd_node::uCouldBe.

Referenced by BreakDownYD().

02744 {
02745     PD_Node *p = PD_NewNode();
02746     if (p)
02747     {
02748         *p = *pNode;
02749         p->uCouldBe = mask;
02750         p->nToken = 3;
02751         p->pToken += pNode->nToken - 3;
02752         p->iToken = pNode->iToken % 1000;
02753         pNode->nToken -= 3;
02754         pNode->iToken /= 1000;
02755         PD_InsertAfter(pNode, p);
02756     }
02757 }

static void SplitLastTwoDigits ( PD_Node pNode,
unsigned  mask 
) [static]

Definition at line 2727 of file timeutil.cpp.

References tag_pd_node::iToken, tag_pd_node::nToken, PD_InsertAfter(), PD_NewNode(), tag_pd_node::pToken, and tag_pd_node::uCouldBe.

Referenced by BreakDownDMY(), BreakDownHMS(), BreakDownMDY(), and BreakDownYMD().

02728 {
02729     PD_Node *p = PD_NewNode();
02730     if (p)
02731     {
02732         *p = *pNode;
02733         p->uCouldBe = mask;
02734         p->nToken = 2;
02735         p->pToken += pNode->nToken - 2;
02736         p->iToken = pNode->iToken % 100;
02737         pNode->nToken -= 2;
02738         pNode->iToken /= 100;
02739         PD_InsertAfter(pNode, p);
02740     }
02741 }

static void test_time_t ( void   )  [static]

Definition at line 1926 of file timeutil.cpp.

References ltaLowerBound, ltaUpperBound, ltdTimeZoneStandard, CLinearTimeAbsolute::SetFields(), CLinearTimeAbsolute::SetSeconds(), SetStructTm(), time_t_largest(), time_t_midpoint(), and time_t_smallest().

Referenced by TIME_Initialize().

01927 {
01928     // Search for the highest supported value of time_t.
01929     //
01930     time_t tUpper = time_t_largest();
01931     time_t tLower = 0;
01932     time_t tMid;
01933     while (tLower < tUpper)
01934     {
01935         tMid = time_t_midpoint(tLower+1, tUpper);
01936         if (localtime(&tMid))
01937         {
01938             tLower = tMid;
01939         }
01940         else
01941         {
01942             tUpper = tMid-1;
01943         }
01944     }
01945     ltaUpperBound.SetSeconds(tLower);
01946 
01947     // Search for the lowest supported value of time_t.
01948     //
01949     tUpper = 0;
01950     tLower = time_t_smallest();
01951     while (tLower < tUpper)
01952     {
01953         tMid = time_t_midpoint(tLower, tUpper-1);
01954         if (localtime(&tMid))
01955         {
01956             tUpper = tMid;
01957         }
01958         else
01959         {
01960             tLower = tMid+1;
01961         }
01962     }
01963     ltaLowerBound.SetSeconds(tUpper);
01964 
01965     // Find a time near tLower for which DST is not in affect.
01966     //
01967     for (;;)
01968     {
01969         struct tm *ptm = localtime(&tLower);
01970 
01971         if (ptm->tm_isdst <= 0)
01972         {
01973             // Daylight savings time is either not in effect or
01974             // we have no way of knowing whether it is in effect
01975             // or not.
01976             //
01977             FIELDEDTIME ft;
01978             SetStructTm(&ft, ptm);
01979             ft.iMillisecond = 0;
01980             ft.iMicrosecond = 0;
01981             ft.iNanosecond  = 0;
01982 
01983             CLinearTimeAbsolute ltaLocal;
01984             CLinearTimeAbsolute ltaUTC;
01985             ltaLocal.SetFields(&ft);
01986             ltaUTC.SetSeconds(tLower);
01987             ltdTimeZoneStandard = ltaLocal - ltaUTC;
01988             break;
01989         }
01990 
01991         // Advance the time by 1 month (expressed as seconds).
01992         //
01993         tLower += 30*24*60*60;
01994     }
01995 }

void TIME_Initialize ( void   ) 

Definition at line 2001 of file timeutil.cpp.

References cnt, FIELDEDTIME::iYear, ltaUpperBound, ltdIntervalMinimum, CLinearTimeAbsolute::ReturnFields(), test_time_t(), time_1w, and YearType().

Referenced by main(), and QueryLocalOffsetAt_Internal().

02002 {
02003     if (bTimeInitialized)
02004     {
02005         return;
02006     }
02007     bTimeInitialized = true;
02008 
02009     tzset();
02010 
02011     test_time_t();
02012     ltdIntervalMinimum = time_1w;
02013     int i;
02014     for (i = 0; i < 15; i++)
02015     {
02016         NearestYearOfType[i] = -1;
02017     }
02018     int cnt = 14;
02019     FIELDEDTIME ft;
02020     ltaUpperBound.ReturnFields(&ft);
02021     for (i = ft.iYear-1; cnt; i--)
02022     {
02023         int iYearType = YearType(i);
02024         if (NearestYearOfType[iYearType] < 0)
02025         {
02026             NearestYearOfType[iYearType] = i;
02027             cnt--;
02028         }
02029     }
02030 #ifdef WIN32
02031     InitializeQueryPerformance();
02032 #endif
02033 }

static time_t time_t_largest ( void   )  [static]

Definition at line 1861 of file timeutil.cpp.

References INT32_MAX_VALUE, INT64_MAX_VALUE, and TIMEUTIL_TIME_T_MAX_VALUE.

Referenced by test_time_t().

01862 {
01863     time_t t;
01864     if (sizeof(INT64) <= sizeof(time_t))
01865     {
01866         t = static_cast<time_t>(INT64_MAX_VALUE);
01867     }
01868     else
01869     {
01870         t = static_cast<time_t>(INT32_MAX_VALUE);
01871     }
01872 
01873 #if defined(TIMEUTIL_TIME_T_MAX_VALUE)
01874     INT64 t64 = static_cast<INT64>(t);
01875     if (TIMEUTIL_TIME_T_MAX_VALUE < t64)
01876     {
01877         t = static_cast<time_t>(TIMEUTIL_TIME_T_MAX_VALUE);
01878     }
01879 #endif
01880 #if defined(LOCALTIME_TIME_T_MAX_VALUE)
01881     // Windows cannot handle negative time_t values, and some versions have
01882     // an upper limit as well. Values which are too large cause an assert.
01883     //
01884     // In VS 2003, the limit is 0x100000000000i64 (beyond the size of a
01885     // time_t). In VS 2005, the limit is December 31, 2999, 23:59:59 UTC
01886     // (or 32535215999).
01887     //
01888     if (LOCALTIME_TIME_T_MAX_VALUE < t)
01889     {
01890         t = static_cast<time_t>(LOCALTIME_TIME_T_MAX_VALUE);
01891     }
01892 #endif
01893     return t;
01894 }

static time_t time_t_midpoint ( time_t  tLower,
time_t  tUpper 
) [static]

Definition at line 1855 of file timeutil.cpp.

Referenced by test_time_t().

01856 {
01857     time_t tDiff = (tUpper-2) - tLower;
01858     return tLower+tDiff/2+1;
01859 }

static time_t time_t_smallest ( void   )  [static]

Definition at line 1896 of file timeutil.cpp.

References INT32_MIN_VALUE, INT64_MIN_VALUE, and TIMEUTIL_TIME_T_MIN_VALUE.

Referenced by test_time_t().

01897 {
01898     time_t t;
01899     if (sizeof(INT64) <= sizeof(time_t))
01900     {
01901         t = static_cast<time_t>(INT64_MIN_VALUE);
01902     }
01903     else
01904     {
01905         t = static_cast<time_t>(INT32_MIN_VALUE);
01906     }
01907 #if defined(TIMEUTIL_TIME_T_MIN_VALUE)
01908     INT64 t64 = static_cast<INT64>(t);
01909     if (t64 < TIMEUTIL_TIME_T_MIN_VALUE)
01910     {
01911         t = static_cast<time_t>(TIMEUTIL_TIME_T_MIN_VALUE);
01912     }
01913 #endif
01914 #if defined(LOCALTIME_TIME_T_MIN_VALUE)
01915     if (t < LOCALTIME_TIME_T_MIN_VALUE)
01916     {
01917         t = static_cast<time_t>(LOCALTIME_TIME_T_MIN_VALUE);
01918     }
01919 #endif
01920     return t;
01921 }

static void UpdateOffsetTable ( CLinearTimeAbsolute lta,
CLinearTimeDelta  ltdOffset,
bool  isDST,
int  i 
) [static]

Definition at line 2111 of file timeutil.cpp.

References OffsetEntry::isDST, OffsetEntry::ltaEnd, OffsetEntry::ltaStart, ltdIntervalMinimum, OffsetEntry::ltdOffset, MAX_OFFSETS, OffsetEntry::nTouched, and OffsetTable.

Referenced by QueryLocalOffsetAt_Internal().

02117 {
02118 Again:
02119 
02120     nTouched0++;
02121 
02122     // Is the interval defined?
02123     //
02124     if (  0 <= i
02125        && lta <= OffsetTable[i].ltaEnd)
02126     {
02127         OffsetTable[i].nTouched = nTouched0;
02128         return;
02129     }
02130 
02131     bool bTryMerge = false;
02132 
02133     // Coalesce new data point into this interval if:
02134     //
02135     //  1. Tuple for this interval matches the new tuple value.
02136     //  2. It's close enough that we can assume all intervening
02137     //     values are the same.
02138     //
02139     if (  0 <= i
02140        && OffsetTable[i].ltdOffset == ltdOffset
02141        && OffsetTable[i].isDST == isDST
02142        && lta <= OffsetTable[i].ltaEnd + ltdIntervalMinimum)
02143     {
02144         // Cool. We can just extend this interval to include our new
02145         // data point.
02146         //
02147         OffsetTable[i].ltaEnd = lta;
02148         OffsetTable[i].nTouched = nTouched0;
02149 
02150         // Since we have changed this interval, we may be able to
02151         // coalesce it with the next interval.
02152         //
02153         bTryMerge = true;
02154     }
02155 
02156     // Coalesce new data point into next interval if:
02157     //
02158     //  1. Next interval exists.
02159     //  2. Tuple in next interval matches the new tuple value.
02160     //  3. It's close enough that we can assume all intervening
02161     //     values are the same.
02162     //
02163     int iNext = i+1;
02164     if (  0 <= iNext
02165        && iNext < nOffsetTable
02166        && OffsetTable[iNext].ltdOffset == ltdOffset
02167        && OffsetTable[iNext].isDST == isDST
02168        && OffsetTable[iNext].ltaStart - ltdIntervalMinimum <= lta)
02169     {
02170         // Cool. We can just extend the next interval to include our
02171         // new data point.
02172         //
02173         OffsetTable[iNext].ltaStart = lta;
02174         OffsetTable[iNext].nTouched = nTouched0;
02175 
02176         // Since we have changed the next interval, we may be able
02177         // to coalesce it with the previous interval.
02178         //
02179         bTryMerge = true;
02180     }
02181 
02182     if (bTryMerge)
02183     {
02184         // We should combine the current and next intervals if we can.
02185         //
02186         if (  0 <= i
02187            && iNext < nOffsetTable
02188            && OffsetTable[i].ltdOffset == OffsetTable[iNext].ltdOffset
02189            && OffsetTable[i].isDST     == OffsetTable[iNext].isDST
02190            && OffsetTable[iNext].ltaStart - ltdIntervalMinimum
02191               <= OffsetTable[i].ltaEnd)
02192         {
02193             if (0 <= i && 0 <= iNext)
02194             {
02195                 OffsetTable[i].ltaEnd = OffsetTable[iNext].ltaEnd;
02196             }
02197             int nSize = sizeof(OffsetEntry)*(nOffsetTable-i-2);
02198             memmove(OffsetTable+i+1, OffsetTable+i+2, nSize);
02199             nOffsetTable--;
02200         }
02201     }
02202     else
02203     {
02204         // We'll have'ta create a new interval.
02205         //
02206         if (nOffsetTable < MAX_OFFSETS)
02207         {
02208             size_t nSize = sizeof(OffsetEntry)*(nOffsetTable-i-1);
02209             memmove(OffsetTable+i+2, OffsetTable+i+1, nSize);
02210             nOffsetTable++;
02211             i++;
02212             OffsetTable[i].isDST = isDST;
02213             OffsetTable[i].ltdOffset = ltdOffset;
02214             OffsetTable[i].ltaStart= lta;
02215             OffsetTable[i].ltaEnd= lta;
02216             OffsetTable[i].nTouched = nTouched0;
02217         }
02218         else
02219         {
02220             // We ran out of room. Throw away the least used
02221             // interval and try again.
02222             //
02223             int nMinTouched = OffsetTable[0].nTouched;
02224             int iMinTouched = 0;
02225             for (int j = 1; j < nOffsetTable; j++)
02226             {
02227                 if (OffsetTable[j].nTouched - nMinTouched < 0)
02228                 {
02229                     nMinTouched = OffsetTable[j].nTouched;
02230                     iMinTouched = j;
02231                 }
02232             }
02233             int nSize = sizeof(OffsetEntry)*(nOffsetTable-iMinTouched-1);
02234             memmove(OffsetTable+iMinTouched, OffsetTable+iMinTouched+1, nSize);
02235             nOffsetTable--;
02236             if (iMinTouched <= i)
02237             {
02238                 i--;
02239             }
02240             goto Again;
02241         }
02242     }
02243 }

static int YearType ( int  iYear  )  [static]

Definition at line 1828 of file timeutil.cpp.

References FIELDEDTIME::iDayOfMonth, FIELDEDTIME::iDayOfWeek, FIELDEDTIME::iMonth, isLeapYear(), FIELDEDTIME::iYear, and CLinearTimeAbsolute::SetFields().

Referenced by QueryLocalOffsetAt_Internal(), and TIME_Initialize().

01829 {
01830     FIELDEDTIME ft;
01831     memset(&ft, 0, sizeof(FIELDEDTIME));
01832     ft.iYear        = iYear;
01833     ft.iMonth       = 1;
01834     ft.iDayOfMonth  = 1;
01835 
01836     CLinearTimeAbsolute ltaLocal;
01837     ltaLocal.SetFields(&ft);
01838     if (isLeapYear(iYear))
01839     {
01840         return ft.iDayOfWeek + 8;
01841     }
01842     else
01843     {
01844         return ft.iDayOfWeek + 1;
01845     }
01846 }


Variable Documentation

const PD_BREAKDOWN BreakDownTable[] [static]

Initial value:

Definition at line 3331 of file timeutil.cpp.

Referenced by PD_BreakItDown().

bool bTimeInitialized = false [static]

Definition at line 1999 of file timeutil.cpp.

const PD_CANTBE CantBeTable[]

Initial value:

{
    { PDCB_YEAR,         PDCB_YEAR|PDCB_YD|PDCB_YMD|PDCB_MDY|PDCB_DMY },
    { PDCB_MONTH,        PDCB_MONTH|PDCB_WEEK_OF_YEAR|PDCB_DAY_OF_YEAR|PDCB_YD|PDCB_YMD|PDCB_MDY|PDCB_DMY|PDCB_WEEK_OF_YEAR_PREFIX },
    { PDCB_DAY_OF_MONTH, PDCB_DAY_OF_MONTH|PDCB_WEEK_OF_YEAR|PDCB_DAY_OF_YEAR|PDCB_YD|PDCB_YMD|PDCB_MDY|PDCB_DMY|PDCB_WEEK_OF_YEAR_PREFIX },
    { PDCB_DAY_OF_WEEK,  PDCB_DAY_OF_WEEK },
    { PDCB_WEEK_OF_YEAR, PDCB_WEEK_OF_YEAR|PDCB_MONTH|PDCB_DAY_OF_MONTH|PDCB_YMD|PDCB_MDY|PDCB_DMY },
    { PDCB_DAY_OF_YEAR,  PDCB_DAY_OF_YEAR|PDCB_MONTH|PDCB_DAY_OF_MONTH|PDCB_WEEK_OF_YEAR|PDCB_YMD|PDCB_MDY|PDCB_DMY|PDCB_WEEK_OF_YEAR_PREFIX },
    { PDCB_YD,           PDCB_YEAR|PDCB_YD|PDCB_MONTH|PDCB_DAY_OF_MONTH|PDCB_WEEK_OF_YEAR|PDCB_YMD|PDCB_MDY|PDCB_DMY|PDCB_WEEK_OF_YEAR_PREFIX },
    { PDCB_YMD,          PDCB_YEAR|PDCB_YMD|PDCB_MDY|PDCB_DMY|PDCB_MONTH|PDCB_DAY_OF_MONTH|PDCB_WEEK_OF_YEAR_PREFIX|PDCB_WEEK_OF_YEAR|PDCB_YD|PDCB_DAY_OF_YEAR },
    { PDCB_MDY,          PDCB_YEAR|PDCB_YMD|PDCB_MDY|PDCB_DMY|PDCB_MONTH|PDCB_DAY_OF_MONTH|PDCB_WEEK_OF_YEAR_PREFIX|PDCB_WEEK_OF_YEAR|PDCB_YD|PDCB_DAY_OF_YEAR },
    { PDCB_DMY,          PDCB_YEAR|PDCB_YMD|PDCB_MDY|PDCB_DMY|PDCB_MONTH|PDCB_DAY_OF_MONTH|PDCB_WEEK_OF_YEAR_PREFIX|PDCB_WEEK_OF_YEAR|PDCB_YD|PDCB_DAY_OF_YEAR },
    { PDCB_YMD|PDCB_MDY, PDCB_YEAR|PDCB_YMD|PDCB_MDY|PDCB_DMY|PDCB_MONTH|PDCB_DAY_OF_MONTH|PDCB_WEEK_OF_YEAR_PREFIX|PDCB_WEEK_OF_YEAR|PDCB_YD|PDCB_DAY_OF_YEAR },
    { PDCB_MDY|PDCB_DMY, PDCB_YEAR|PDCB_YMD|PDCB_MDY|PDCB_DMY|PDCB_MONTH|PDCB_DAY_OF_MONTH|PDCB_WEEK_OF_YEAR_PREFIX|PDCB_WEEK_OF_YEAR|PDCB_YD|PDCB_DAY_OF_YEAR },
    { PDCB_YMD|PDCB_DMY, PDCB_YEAR|PDCB_YMD|PDCB_MDY|PDCB_DMY|PDCB_MONTH|PDCB_DAY_OF_MONTH|PDCB_WEEK_OF_YEAR_PREFIX|PDCB_WEEK_OF_YEAR|PDCB_YD|PDCB_DAY_OF_YEAR },
    { PDCB_YMD|PDCB_DMY|PDCB_MDY, PDCB_YEAR|PDCB_YMD|PDCB_MDY|PDCB_DMY|PDCB_MONTH|PDCB_DAY_OF_MONTH|PDCB_WEEK_OF_YEAR_PREFIX|PDCB_WEEK_OF_YEAR|PDCB_YD|PDCB_DAY_OF_YEAR },
    { PDCB_TIMEZONE, PDCB_TIMEZONE|PDCB_HMS_TIMEZONE|PDCB_HOUR_TIMEZONE },
    { PDCB_HOUR_TIME, PDCB_HMS_TIME|PDCB_HOUR_TIME },
    { PDCB_HOUR_TIMEZONE, PDCB_TIMEZONE|PDCB_HMS_TIMEZONE|PDCB_HOUR_TIMEZONE },
    { PDCB_HMS_TIME, PDCB_HMS_TIME|PDCB_HOUR_TIME },
    { PDCB_HMS_TIMEZONE, PDCB_TIMEZONE|PDCB_HMS_TIMEZONE|PDCB_HOUR_TIMEZONE },
    { 0, 0 }
}

Definition at line 3494 of file timeutil.cpp.

Referenced by PD_Deduction().

char* DayOfWeekString[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }

Definition at line 725 of file timeutil.cpp.

Referenced by FUNCTION().

const char daystab[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } [static]

Definition at line 726 of file timeutil.cpp.

const INT64 FACTOR_100NS_PER_DAY = FACTOR_100NS_PER_HOUR*24

Definition at line 410 of file timeutil.cpp.

const INT64 FACTOR_100NS_PER_HOUR = FACTOR_100NS_PER_MINUTE*60

Definition at line 409 of file timeutil.cpp.

const INT64 FACTOR_100NS_PER_MINUTE = FACTOR_100NS_PER_SECOND*60

Definition at line 408 of file timeutil.cpp.

const INT64 FACTOR_100NS_PER_SECOND = 10000000ull

Definition at line 406 of file timeutil.cpp.

const INT64 FACTOR_100NS_PER_WEEK = FACTOR_100NS_PER_DAY*7

Definition at line 411 of file timeutil.cpp.

const int InitialCouldBe[9] [static]

Initial value:

Definition at line 2895 of file timeutil.cpp.

const char LexTable[256]

Initial value:

{


    5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  
    3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,  
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0,  
    0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,  
    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0,  
    0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,  
    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0,  

    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0   
}

Definition at line 3072 of file timeutil.cpp.

CLinearTimeAbsolute ltaLowerBound [static]

Definition at line 1848 of file timeutil.cpp.

Referenced by QueryLocalOffsetAtUTC(), and test_time_t().

CLinearTimeAbsolute ltaUpperBound [static]

Definition at line 1849 of file timeutil.cpp.

Referenced by QueryLocalOffsetAt_Internal(), test_time_t(), and TIME_Initialize().

CLinearTimeDelta ltdIntervalMinimum [static]

Definition at line 1998 of file timeutil.cpp.

Referenced by QueryLocalOffsetAtUTC(), TIME_Initialize(), and UpdateOffsetTable().

CLinearTimeDelta ltdTimeZoneStandard [static]

Definition at line 1850 of file timeutil.cpp.

Referenced by QueryLocalOffsetAt_Internal(), QueryLocalOffsetAtUTC(), and test_time_t().

const char* monthtab[]

Initial value:

{
    "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
}

Definition at line 727 of file timeutil.cpp.

Referenced by FUNCTION().

int MonthTabHash[12] [static]

Initial value:

{
    0x004a414e, 0x00464542, 0x004d4152, 0x00415052,
    0x004d4159, 0x004a554e, 0x004a554c, 0x00415547,
    0x00534550, 0x004f4354, 0x004e4f56, 0x00444543
}

Definition at line 950 of file timeutil.cpp.

CMuxAlarm MuxAlarm

Definition at line 29 of file timeutil.cpp.

Referenced by boot_slave(), check_filter(), compile_regex(), did_it(), do_command(), do_mail_review(), dump_database(), eval_boolexp(), filter_handler(), fork_and_dump(), FUNCTION(), grep_util(), CHashFile::Insert(), list_check(), match(), modSpeech(), mux_exec(), page_return(), CHashPage::ReadPage(), real_regmatch(), real_regrab(), regexp_match(), sighandler(), switch_handler(), Task_RunQueueEntry(), u_comp(), and CHashPage::WritePage().

int NearestYearOfType[15] [static]

Definition at line 1997 of file timeutil.cpp.

int nNodes = 0 [static]

Definition at line 3095 of file timeutil.cpp.

PD_Node Nodes[MAX_NODES] [static]

Definition at line 3097 of file timeutil.cpp.

Referenced by PD_NewNode().

int nOffsetTable = 0 [static]

Definition at line 2055 of file timeutil.cpp.

int nTouched0 = 0 [static]

Definition at line 2056 of file timeutil.cpp.

const NUMERIC_VALID_RECORD NumericSet[]

Initial value:

Definition at line 2916 of file timeutil.cpp.

Referenced by ClassifyNumericToken().

OffsetEntry OffsetTable[MAX_OFFSETS] [static]

Definition at line 2057 of file timeutil.cpp.

Referenced by FindOffsetEntry(), QueryOffsetTable(), and UpdateOffsetTable().

PD_Node* PD_Head = 0 [static]

Definition at line 3099 of file timeutil.cpp.

Referenced by PD_AppendNode(), PD_FirstNode(), PD_RemoveNode(), and PD_Reset().

PD_Node* PD_Tail = 0 [static]

Definition at line 3100 of file timeutil.cpp.

Referenced by PD_AppendNode(), PD_InsertAfter(), PD_RemoveNode(), and PD_Reset().

const PD_TEXT_ENTRY PD_TextTable[]

Definition at line 2968 of file timeutil.cpp.

Referenced by PD_ScanNextToken().


Generated on Mon May 28 04:40:23 2007 for MUX by  doxygen 1.4.7