Topic: DateTime proposal (was: C++ proposal storage)


Author: Eric Ulevik <eau@astsun.fujitsu.com.au>
Date: 1997/02/13
Raw View
------------5F26C12350A0
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=us-ascii

Pablo Halpern wrote:
> 1. A point in time is an abstract pseudo-physical concept.

True, but on what base is this measured? UTC? What about leap seconds?

> 2. The concepts of a day, an hour, a minute, a second, and a fraction
of
> a second are more-or-less universal. The concepts of a week, month and
> year are calendar-specific.

Not true. Calendars also define hours etc. (eg. French Revolutionary
Calendar).
A standard for date and time should allow the user to handle such
calendars.

Standard C++ date and time handling would be nice. But there are many
issues.

Ideally, the user should be able to implement a new calendar. This could
be
used to handle the Islamic calendar, which cannot be calculated
precisely
because it depends upon human decision as to when the new moon appears.

Eric Ulevik
http://www.ozemail.com.au/~eau/sydbest.html "The Best in Sydney"


------------5F26C12350A0
Content-Transfer-Encoding: 7bit
Content-Type: text/html; charset=us-ascii

<HTML><BODY>

<DT>Pablo Halpern wrote:<BR>
&gt; 1. A point in time is an abstract pseudo-physical concept.&nbsp;<BR>
&nbsp;&nbsp;<BR>
True, but on what base is this measured? UTC? What about leap seconds?&nbsp;<BR>
&nbsp;&nbsp;<BR>
&gt; 2. The concepts of a day, an hour, a minute, a second, and a fraction
of<BR>
&gt; a second are more-or-less universal. The concepts of a week, month
and<BR>
&gt; year are calendar-specific.&nbsp;<BR>
&nbsp;&nbsp;<BR>
Not true. Calendars also define hours etc. (eg. French Revolutionary Calendar).&nbsp;<BR>
A standard for date and time should allow the user to handle such calendars.&nbsp;<BR>
&nbsp;&nbsp;<BR>
Standard C++ date and time handling would be nice. But there are many issues.&nbsp;<BR>
&nbsp;&nbsp;<BR>
Ideally, the user should be able to implement a new calendar. This could
be&nbsp;<BR>
used to handle the Islamic calendar, which cannot be calculated precisely&nbsp;<BR>
because it depends upon human decision as to when the new moon appears.&nbsp;<BR>
&nbsp;&nbsp;<BR>
Eric Ulevik&nbsp;<BR>
http://www.ozemail.com.au/~eau/sydbest.html &quot;The Best in Sydney&quot;&nbsp;<BR>
&nbsp;<BR>
<BR></DT>

</BODY>
</HTML>
------------5F26C12350A0--
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: phalpern@truffle.ma.ultranet.com (Pablo Halpern)
Date: 1997/02/11
Raw View
As the posts in this thread have shown, there are many different
requirements that people would like to see in their DateTime classes.
Most of the issues can be divided into three orthogonal requirements:

1. Range (is 1970-2038 enough of a range? Do we need all of history? All
time since the big-bang?)
2. Precision (are seconds precise enough? milliseconds? nanoseconds?)
3. Human interpretation (How long are months? When are the leap years?
Time zones and daylight savings time. Julian vs. Gregorian calendar.
Christian, Jewish or Chinese calendar? 12-hour vs. 24-hour clock)

The requirements for the above three categories are definately
application-specific. There is a space and time tradeoff for any
increase in range or precision, so one should not impose millisecond
precision on an application that does well enough with precision in
seconds. I think that a standard (or quasi-standard) DateTime module
should really be a collection of classes and functions, some of which
are templates. What I envision is the ability to mix and match the above
to get your application's requirements. What I envision is something
like the STL, where the components can be combined at will.

Start with the following observations:

1. A point in time is an abstract pseudo-physical concept. It exists
independent of a calendar. A calendar is separate from a point in time.
For human readability, a point in time must be interpreted using a
calendar. Thus, a time object can exist without knowing what calendar we
are going to use to interpret it.

2. The concepts of a day, an hour, a minute, a second, and a fraction of
a second are more-or-less universal. The concepts of a week, month and
year are calendar-specific. We could make a requirement that all time
classes provide the following interface (at minimum):

  typedef some_type time_diff_t;  // type that can hold time - time val
  static epoch getepoch();     // Returns the zero date in a known fmt
  some_int_type days() const;  // Days since the epoch
  long seconds() const;        // Seconds since midnight
  long nanoseconds() const;    // Nanoseconds within the second
  time(int dy, int sec, int ns); // Constructor

  globals:
  time_diff_t operator-(time,time) etc.

Some time classes will return zero for nanoseconds() (or even seconds())
or will return values that are rounded to the precision supported by the
time class. These requirements do not describe a specific time class.
Rather, like the STL iterator requirements, the specify a minimum
interface for any time class that wants to play in our DateTime system.

Example:

  class unixtime
  {
    static const int secsperday = 24 * 60 * 60;
    long t;
  public:
    typedef long time_diff_t;
    unixtime(int dy, int sec, int ns) : t(dy * secsperday + sec) { }
    int days() const { return t / secsperday; }
    int seconds() const { return t % secsperday; }
    int nanoseconds() const { return 0; }

    friend time_diff_t operator-(unixtime, unixtime);
    friend unixtime operator+(unixtime, time_diff_t);
    friend unixtime operator-(unixtime, time_diff_t);

    unixtime& operator+=(time_diff_t);
    unixtime& operator-=(time_diff_t);
  };

Next, we create a set of template classes to provide the human
interpretation:

template <class Time>
class WesternDates
{
public:
  static timezone setLocalTimeZone(const timezone&);
  static timezone& getLocalTimeZone();

  string localtime(const Time& t, const timezone& = getLocalTimeZone());

  Time makeTime(int yr, int mnth, int day, int min = 0, int sec = 0,
                long ns = 0, const timezone& = getLocalTimeZone());
  // etc.
};

Of course, there would have to be auxiliary types for timezone, and, in
some cases time_diff_t.  You get the idea.

What I like about this is that the hard work of interpreting the
calendar (and keeping track of leap years, month lengths, timezones,
DST, etc.) is centralized in the WesternDates class template. This logic
can then be applied to any reasonable time class to get the desired
precision and range for the application.
-------------------------------------------------------------
Pablo Halpern                   phalpern@truffle.ultranet.com

I am self-employed. Therefore, my opinions *do* represent
those of my employer.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Markus Kuhn <kuhn@cs.purdue.edu>
Date: 1997/02/04
Raw View
David R Tribble wrote:
>
> A date/time class has been proposed, which I repeat here, slightly
> modified:
>
> > class DateTime  // incomplete interface
> > {
> > public:
> >     DateTime(int year, int month, int day);
> >     DateTime(int year, int month, int day, int hour, int min, int sec);

Looking at the posted part of the interface, it seems that this
date/time class is completely unaware of the difference between local
time and universal time (UTC), and therefore of very limited use
in any wide area networked environment (Internet, etc.).

The existing time.h ISO C interface is screwed in a number of ways:
The most silly problem is that there is no inverse function for
gmtime(). You have mktime() as an inverse function for localtime(),
but it is impossible to write a portable ISO C program that converts
a broken-down UTC timestamp into an time_t value. In addition, it is
pretty inconvenient to find out with the time_t ISO C interface, what
the current offset between local time and UTC is. It is in addition
not possible to specify in a portable way (like TZ under POSIX), what
the algorithm that determines the UTC-offset is. ISO 8601 week and
year-of-week format descriptors are missing in strftime(), and
noone knows where the 2nd leap second allowed in the standard should
come from.

There are many tricky details of the ISO C date/time that should
definitely be improved. Some good discussion on this topic was recently
on the time zone mailing list (ask <tz-request@elsie.nci.nih.gov>
if you want to join or check the archives in
<ftp://elsie.nci.nih.gov/pub/tzarchive.gz>).

Markus

--
Markus Kuhn, Computer Science grad student, Purdue
University, Indiana, US, email: kuhn@cs.purdue.edu
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: David R Tribble <david.tribble@central.beasys.com>
Date: 1997/01/29
Raw View
A date/time class has been proposed, which I repeat here, slightly
modified:

> class DateTime  // incomplete interface
> {
> public:
>     DateTime(int year, int month, int day);
>     DateTime(int year, int month, int day, int hour, int min, int sec);
>     DateTime & operator+(signed int sec);  // Advances DateTime by sec seconds
>     DateTime & operator-(DateTime &t);     // Gives the difference in times
>     int Year() const;         // Retrieve this date's year
>     int Month() const;        // Retrieve this date's month
>     int Day() const;
>     int Hour() const;
>     int Minute() const;
>     int Second() const;
>     int DayOfMonth() const;
>     int DayOfYear() const;
>     ...
>     bool setYear(int year);           // Set this date's year (false=error)
>     bool setMonth(int month);         // Set this date's month
>     ...
> };

Most of thus could be implemented on top of the standard library funcs,
specifically:
    struct tm
    typedef time_t
    time()
    gmtime()
    localtime()
    mktime()
    strftime()

The 'tm' struct already gives you most of what you want:
    seconds
    minutes
    hours
    day of month
    day of year
    weekday
    month
    year
    daylight savings time

To extend the functionality of the library, rather than just wrapping a
class around it, it would be nice to have some useful additions:

    Subsecond accuracy.  Say, to the nearest microsecond (if the O/S can
    provide it, otherwise let usec=0).  UNIX has a 'timeval' struct that
    encodes the time as seconds (time_t) and microseconds (32-bit int)
    which is accurate to the nearest O/S clock tick (typically .01 sec).

    Time/date computations, as alluded to in the above class, such as:

        Add a signed number of microseconds/seconds/minutes/days/months/years
        to a time.  (True, we must define what adding a month to 1997/01/31
        or adding a year to 1996/02/29 means, but there's at least one good
        answer to these.)

        Find the (signed?) difference between two times (stored in a DateTime
        format).  (BTW, that's why time_t is a signed value; subtracting
        today's date from yesterday's should result in a negative time_t
        value.)

        Compare two times.  This is probably best done by overloading
        operator <() et al.

    Extended range.  The basic DateTime class should cover the same range
    as 'time_t', but perhaps derived subclasses could extend that range,
    say from 1752 A.D. (the year the Gregorian calendar was adopted in the
    USA) to 2999 A.D.

Whether or not the class is built on top of the standard library, it's a
good idea to allow intermixing (conversions) of 'time_t' and 'struct tm'
values as well.  Not to mention something like strftime() for strings.
Conversion to other date representations, such as Julian dates, may also
be desirable, but we don't want to go overboard here.

-- David R. Tribble, david.tribble@central.beasys.com --



[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: mhamilton@bunge.com.au (Mab)
Date: 1997/01/29
Raw View
In article <2.2.32.19970129195652.002cf360@central.beasys.com>,
   David R Tribble <david.tribble@central.beasys.com> wrote:

<datetime class proposals snipped>

I thought about this a bit after reading the thread. What about a template
class like this:

template <class DateImp, class TimeImp>
class datetime
{
..
};

So that you could specify your own implementation of either date or time or
both?

Take it away, experts - I'm not up to date enough to discuss the pros and cons
of this suggestion! 8)

|~\  /~| /~~| |~|    _______________________________________________
|  \/  |/ / |_| |__  The .sig wears a ring of polymorph! --More--
|      ' /| |_| | /  The .login hits! The .cshrc bites!
| |\/|  /\  | |  /   -----------------------------------------------
| |  |_/  \_| | /    "Say . . . That's a nice bike!" -- The T1000
=\|===========|/==========- The Mabster:  mhamilton@bunge.com.au -==



[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: bill@osisoft.com (Bill Vaughan)
Date: 1997/01/30
Raw View
>To extend the functionality of the library, rather than just wrapping a
>class around it, it would be nice to have some useful additions:
>
>    Subsecond accuracy.  Say, to the nearest microsecond (if the O/S can
>    provide it, otherwise let usec=0).  UNIX has a 'timeval' struct that
>    encodes the time as seconds (time_t) and microseconds (32-bit int)
>    which is accurate to the nearest O/S clock tick (typically .01 sec).
>

The best way to do this would be to make seconds a floating-point
quantity. This avoids messy conflicts between systems that report
milliseconds, those that report microseconds, those that report ticks,
and those that cannot handle high-precision time.

An alternative is to make a date-time type whose representation is
double-precision floating-point seconds. This gives a time accurate to
microseconds or better for a large number of years on either side of
the chosen epoch (zero) date. (Oddly, for best accuracy it is
preferable that the epoch be some ways in the future, so that dates
and times near the present would have negative representations.)

One could use floating-point minutes, hours, days, or fortnights in
lieu of seconds, but if seconds are used, the conversion from existing
standard formats is exact.

This may look like the Microsoft OLE Date data type (also used by
Visual Basic and the Excel spreadsheet) but it is not. The Microsoft
date format is double-precision days, with the epoch on 31 dec 1899 at
0000 local time. Because it is based on the local wallclock rather
than on UTC, it becomes impossible to reasonably render past dates in
the presence of DST changes, particularly when the dates are generated
in other parts of the world. Also, there is a severe (known) bug in
the Microsoft implementation affecting all dates before 31-dec-1899.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Pete Forman <gsez020@megan.bedford.waii.com>
Date: 1997/01/30
Raw View
>>>>> "David" == David R Tribble <david.tribble@central.beasys.com> writes:

    David> A date/time class has been proposed, which I repeat here,
    David> slightly modified:

    [snip]

    David> Subsecond accuracy.  Say, to the nearest microsecond (if
    David> the O/S can provide it, otherwise let usec=0).  UNIX has a
    David> 'timeval' struct that encodes the time as seconds (time_t)
    David> and microseconds (32-bit int) which is accurate to the
    David> nearest O/S clock tick (typically .01 sec).

You need to distinguish between accuracy and precision.  In your
example the precision is microsecond and accuracy is .01 sec.

If you are going for sub-second precision, then you might as well
follow the lead of POSIX 1003.1b and go with nanoseconds.  Their C
functions include clock_gettime() and nanosleep().  Neither us or ns
fit in 16 bits, so you might as well use as many of 32 bits as is
reasonable.
--
Pete Forman
Western Geophysical
pete.forman@bedford.waii.com
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]