ezDateTime is a C++ library and utility that parses (ISO 8601) datetime strings (with timezone) into quickly sortable values (and back to strings) and allows arithmetic with various calendars and units.

Calendars supported are

For arithmetic, units for offsets and deltas can be in years, months, weeks, days, hours, minutes or seconds.

Future and past datetimes can also be computed relative to a baseline using an offset (a technique often used in scientific datasets such as NetCDF climate models). As a simple example, you can find the datetime for 365 relative to the unit baseline "days since 2011-01-01 12:00", which would result in "2012-01-01 12:00".

The library is a single header file with only ISO dependencies.


Source code



make test
make memtest
make clean


sudo make install PREFIX=/usr/local

Command-line Usage

# Convert to a double encoding. Prints 2012081.5.
ezdatetime --double 2012-03-21 7:00 -5:00

# Same as above, but more compact ISO string.
ezdatetime --double 201203210700-500

# Convert from a double encoding. Prints 2012-03-21 12:00:00.
ezdatetime 2012081.5

# Get future date time relative to a baseline assuming Gregorian calendar.
# Prints 2012-03-23 00:00:00.
ezdatetime 1.5 days since 2012-03-21 12:00

# Similar as above, but used "after" instead of "since".
ezdatetime 1.5 days after now

# Batch process values since a baseline.
ezdatetime -f /tmp/dates days since 2012

# Same as above, but prints 2012083.0.
ezdatetime --double 1.5 days since 2012-03-21 12:00

# Get past date time. Prints 2012-2-29 (when using leap calendar).
ezdatetime 1 day before 2012-03-1

# Get past date time from now.
ezdatetime 2 months before now
ezdatetime 2 weeks before now

# Get duration between two values. Prints 1.5.
ezdatetime days between 2012-3-22 7:00 -5 and 2012-03-21 1:00 +1

# Get days from beginning of year in nonleap calendar.
ezdatetime -c noleap days between now and 2012

# Batch process file with 2 dates per line split by a comma.
ezdatetime -f /tmp/dates days between

C++ Usage

#include "ezDateTime.hpp"

int main() {
  // Convert string to a sortable double.
  std::string s = "2000-12-30 01:34:15.5 -6:00";
  double dValue;
  char tzHr, tzMin;
  char cal = ez::ezDateTime::GREGORIAN;
  ez::ezDateTime::fromString(dValue, s, cal, tzHr, tzMin);

  // Get components, up to microseconds; I didn't need more precision :).
  int year, month, day, hr, min;
  float sec;
  ez::ezDateTime::fromDouble(dValue, year, month, day, hr, min, sec, cal);

  // Do arithmetic.
  ez::ezTimeDelta delta;
  delta.seconds = 1;
  delta.minutes = 1;
  delta.hours = 1;
  delta.days = -1;
  delta.months = -1;
  delta.years = -1;
  double future = ez::ezDateTime::add(dValue, delta);

  // Find number of units from datetime zero.
  double seconds = ez::ezDateTime::toSeconds(dValue, cal);
  double minutes = ez::ezDateTime::toMinutes(dValue, cal);
  double hours = ez::ezDateTime::toHours(dValue, cal);
  double days = ez::ezDateTime::toDays(dValue, cal);
  double weeks = ez::ezDateTime::toWeeks(dValue, cal);
  double months = ez::ezDateTime::toMonths(dValue, cal);
  double years = ez::ezDateTime::toYears(dValue, cal);

  // Convert between timezones.
  double EST = ez::ezDateTime::utcToTimezone(dValue, -5, 0, cal);

  // Convert back to an ISO-8601 string.
  std::string str;
  ez::ezDateTime::toString(str, EST, cal);

  // Compute number of weeks between two dates.
  ez::ezDateTime dt1( str, cal );
  ez::ezDateTime dt2( "2012", cal );
  double diff = dt1.minus(dt2, ez::ezDateTime::WEEKS);

  return 0;

Help Message

ezdatetime -- datetime utilities.

USAGE: ezdatetime [OPTIONS] datetime
       ezdatetime [OPTIONS] [units] [since|after|before] datetime
       ezdatetime [OPTIONS] [units] between [now|datetime] and [now|datetime]


-c, --cal, --calendar ARG   Set calendar to either "gregorian", "julian",
                            "noleap" or "365", "all_leap" or "366", "360",
                            "proleptic". Default is gregorian.

-D, --debug                 Print debug messages.

-d, --double                Print results as UTC doubles.

-f, --file ARG              Input file for batch processing. For batch
                            "between", separate both values by a comma. For
                            all other batch operations, just have one value
                            per line.

-h, --help, --usage ARG     Display usage instructions.
                            There is a choice of three different layouts for
                            description alignment. Your choice can be any one
                            of the following to suit your style:

                            0 - align (default)
                            1 - interleave
                            2 - stagger

-n, --nonewline             Do not print newline characters. Lists will be
                            comma delimited.

-v, --version               Display version info.

-w, --whole                 Print time with whole numbers (no decimals).

--timezone, --tz ARG        Set output to given timezone, such as -1:30 or 1
                            or +6.

ezdatetime '0.3.2' Copyright Remik Ziemlinski
Software is provided AS IS without WARRANTY under an MIT license.


make html
make clean
make dist VER=0.3.2


ssh -t rsz,ezdatetime@shell.sourceforge.net create
scp html/* rsz,ezdatetime@shell.sourceforge.net:/home/project-web/ezdatetime/htdocs
scp ../ezDateTime-0.3.2.tar.gz rsz,ezdatetime@shell.sourceforge.net:/home/frs/project/e/ez/ezdatetime


v0.3.2 20120716

v0.3.1 20120711

v0.3.0 20120711

v0.2.1 20120626

v0.2.0 20120603

v0.1.0 20111223

v0.0.0 20111201


Copyright 2011, 2012 Remik Ziemlinski (see MIT-LICENSE)