Click here to Skip to main content
13,458,960 members
Click here to Skip to main content
Add your own
alternative version


19 bookmarked
Posted 22 Apr 2004

Simple(x) Date & Time Math Parser

, 22 Apr 2004
Rate this:
Please Sign up or sign in to vote.
Date and time class from the SimplexParser freeware.


In fact, it is not difficult to find a C/C++ date & time class for our main purposes. One of the best is surely P J Naughter's DTime. To bring the functionality for a Date & Time Mathematical Parser, we need additional methods to this or a special class for those purposes. SimplexParser has such a class, so I am decided to set it up to the CodeProject site.

Sample Operations

The parser interprets editor's code like:

Result = Startdatetime + 40 hours + 12 min + 1 year

in the form:

Result = C<[21.04.2004 | 16:19:18] + h[40] + m[12] + Y[1]
Result = 23.04.2005 08:31:18

or as span:

Result = 366.925 days or +366d 22h 12m 0s

or as:

Julian Date: Result = 2453483.855069

and so on...

whereby C< stands for Start Clock, D< for Start Date and T< for Start Time. Or:

Result = Startdate - Enddate
Result = C<[21.04.2004 | 16:19:18] - C>[20.03.2003 | 06:19:15]
Result = +398d 10h 0m 3s

whereby C> stands for End Clock, D> for End Date and T> for End Time. The syntax was introduced in the early days of development and simplifies the parser's error input check. The output is in the normal form like +366d 22h 12m 0s (day, hour, minute and sec.) or 21.04.2004 16:19:18 or 04/21/2004.

Julian Day Algorithm

The parser's date & time class is based on the Julian Day system. The Julian Day is the number of days since noon on January 1, -4712, i.e., January 1, 4713 BC. It was proposed by J. J. Scaliger in 1583, so the name for this system derived from Julius Scaliger (not Julius Caesar). Scaliger defined Day One as a day when three calendrical cycles converged. The first cycle was the 28 year period over which the Julian calendar repeats days of the week (the so-called solar number). After 28 years, all the dates fall on the same days of the week, so one need only buy 28 calendars. (Note that since the Gregorian calendar was adopted, the calendar now takes 400 years to repeat.) The second was the 19 year golden number cycle over which phases of the moon almost land on the same dates of the year. The third cycle was the 15 year ancient Roman tax cycle of Emperor Constantine (the so-called indiction). Scaliger picked January 1, 4713 BC on the Julian calendar as Day One. The three cycles coincide every 7980 years. For more information, please see: this or this.

CJulianDay class

The following code shows the main methods from the CJulianDay class. Some of the method names are well known from other codes:


class CJulianDay 
  virtual ~CJulianDay();

// Member Functions
  // Gives Julian Date back
  bool Enter(CString& strBaseDate, CString& 
       strBaseTime, CString strInput, double& dJulian);
  double CalcJulianDayTime(CString& strBaseDate, 
       CString& strBaseTime, CString strInput, bool bSignPlus = true);
  double GetJulianDayTime(CString strBaseDate, CString strBaseTime);

  CString WeekNumber(int Jul);
  CString DayNumber(int Jul);
  CString WeekDay(int Jul);


  bool IsLeapYear(int nYear);
  int DaysInMonth(int nMonth, BOOL bLeapYear);

  double HmsToDec(CString strTime);
  CString DecToHms(double dDec, bool bF);

  double DatToJul(CString strDate);
  CString JulToDat(double Jul);

  bool ValidDate(int nYear, int nMonth, int nDay);
  bool IsValidDate(CString strDate, int& nDay, 
                   int& nMonth, int& nYear);

  double EvaluateNumberOfDays(CString strInput);
  int EvaluateNumberOfYears(CString strDate, CString strInput);
  int EvaluateNumberOfMonth(CString strDate, CString strInput);
  int EvaluateNumberOfWeeks(CString strInput);
  void AddYear(CString& strDate, int nAddYear);
  void AddMonth(CString& strDate, int nAddMonths);


Using the code

You can use this code as shown next:


  double m = ((double) date.GetYear() - 2000.0) / 1000.0;
  double ve = 2451623.80984 + 365242.37404 * m + 
              0.05169 * m * m - 0.00411 * m * m * m - 
              0.00057 * m * m * m * m ;

  CJulianDay Julian;
  CString strDate, strTime;
  Julian.Enter(strDate, strTime, _T(""), ve);
  strResult = strDate + _T(" ") + strTime;





CJulianDay Julian;
result.dJulianDay = Julian.CalcJulianDayTime(m_strBaseDate, 
                         m_strBaseTime, result.Command, true);


I hope that the code is reasonably obvious how to use, so that we can go to the actual parser class CDateParser.

CDateParser class


typedef struct _tagResultStruct
  CLTimeSpan tmSpan;
  LONG value;
  CString SubString;
  CString Command;
  double dJulianDay;
} stDateParser;

class CDateParser 
  CString m_strFormula;
  CString m_strFunction;
  CString m_strErrortext;
  double m_dFunctionConstant[ANZFUNKTKONST];
  CStringArray m_strStandardFunction;

  stDateParser Expression(int& nPosition, CString& strCharacter);
  stDateParser Factor(int& nPosition, CString& strCharacter);
  double Char_n(int& nPosition, CString& strCharacter);
  CString GetNextToken(CString& strSrc, const CString strDelim);

  CJulianDay m_Julian;
  CString m_strBaseDate;
  CString m_strBaseTime;
  CString m_strAssociateDate;
  CString m_strAssociateTime;

  int StripFormula(CString& strFormula);
  CString GetFormula();
  void SetFormula(CString Formula);
  void SetFunctConst(int index, double val);

  virtual ~CDateParser();

  stDateParser Calculation(CString strFormula, 
     int& ErrorPosition, CString& Errortext, 
     BOOL strip = true);


Use this class in the following manner:


CDateParser DateParser;
stDateParser retValue = DateParser.Calculation(m_strFormulainput, 
                                    nErrorPosition, strErrortext);

  if (nErrorPosition == 0)
    if (strErrortext.IsEmpty())
      if (m_nSpanSet == 1) // Span
        int days = retValue.tmSpan.GetTotalDays();
        int hours = retValue.tmSpan.GetHours();
        int minutes = retValue.tmSpan.GetMinutes();
        int seconds = retValue.tmSpan.GetSeconds();



whereby you can use the other public member functions for clean input, and for example, P J Naughter's DTime class CLTimeSpan for getting back days, hours, etc. The demo project shows you that.

Certainly, I know that we can make for the demo project a better dialog for all the possibilities. But, maybe later...


  • 1.0 (18 April 2004) -Initial release.


This would not have been possible without all the authors making their code freely available! So, thanks for that, SimplexParser will be available as freeware for all the time.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Ralf Wirtz
Software Developer (Senior)
Germany Germany
Ralf is the programmer of the well-known programs SimplexNumerica and SimplexParser. He's been programming since 1986 since he was at the Fraunhofer Institute for Laser Technology (ILT) in Aachen/Germany. His preferred programming language is Visual C++ with MFC/ATL and GFA Basic. Ralf was born near Gerolstein/Germany. He went to Aachen University where he obtained a Diploma of technical physics. He works as a senior design engineer for a fairly large, international company.

You may also be interested in...

Comments and Discussions

GeneralScreenshot is wrong Pin
ronnyek24-Sep-04 8:56
sussronnyek24-Sep-04 8:56 
QuestionTimezone? Pin
Stephane Rodriguez.24-Apr-04 3:41
memberStephane Rodriguez.24-Apr-04 3:41 
AnswerRe: Timezone? Pin
Ralf Wirtz25-Apr-04 20:09
memberRalf Wirtz25-Apr-04 20:09 
GeneralRe: Timezone? Pin
Stephane Rodriguez.26-Apr-04 8:21
memberStephane Rodriguez.26-Apr-04 8:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.180323.1 | Last Updated 23 Apr 2004
Article Copyright 2004 by Ralf Wirtz
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid