Greg Brewer
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std...@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
It's an extension. As a general rule, identifiers starting with '_' are
likely to be implementation specific. Exceptions: __LINE__, __FILE__,
__DATE__, __TIME__, __STDC__, __cplusplus. There may be more exceptions
that I've missed; it's difficult to search a PDF file for strings
starting with '_'.
> I just discovered that Borland C++ supports types of __int64, __int32,
> __int16, and __int8. Is this standard or an extension? Does MS or any
> other C++ support it?
The existence of the three smallest types is guaranteed on any 32-bit
implementation... you might just find them under a different name
(although people here might argue that C++ does not technically require
_int16 any more than it requires _int7). _int64 is required for some
Microsoft functions (and by extension potentially any program) to
function properly. All _int64's functions are provided in the standard
libraries, and not in the compiler. Thus _int64 functions may (will) be
rewritten for IA-64/Sledgehammer.
Richard.
"Greg Brewer" <nospa...@brewer.net> wrote in message
news:8jb3kt$1kig$1...@news.hal-pc.org...
> I just discovered that Borland C++ supports types of __int64, __int32,
> __int16, and __int8. Is this standard or an extension? Does MS or any
> other C++ support it?
>
> Greg Brewer
> I just discovered that Borland C++ supports types of __int64, __int32,
> __int16, and __int8. Is this standard or an extension? Does MS or any
> other C++ support it?
>
> Greg Brewer
There are no C++ standard types that begin with two underscores.
Microsoft has at least some of these type, but they are not standard.
The longest integer type required in a conforming C++ implementation
is long, that must contain at least 32 bits, but may contain more.
The recent 1999 update to the C language standard requires conforming
C implementations provide an integer type named "long long" that must
contain at least 64 bits. Note that this C update is not part of the
C++ standard, although it seems likely that it will be added.
The new C update also defines typedefs for exact width integers (names
like int8_t, uint8_t, and so on) but a compiler is not required to
provide exact width types, since not all processor architectures have
natural support for type that come in exact multiples of 8 bits.
There are other typedefs in C99 for integer types "at least" n bits
wide, and the fastest type "at least" n bits wide. These typedefs
might be more difficult to incorporate into C++, but that of course if
up to the committee.
Jack Klein
--
Home: http://jackklein.home.att.net
The leading double underscore is a good tipoff that it's non-
standard. Borland has quite properly created these identifiers out
of the set of names reserved to the implementation.
--
Stan Brown, Oak Road Systems, Cleveland, Ohio, USA
http://oakroadsystems.com
C++ FAQ Lite: http://www.parashift.com/c++-faq-lite/
the C++ standard: http://webstore.ansi.org/
illegal identifiers: http://oakroadsystems.com/tech/cppredef.htm
more FAQs: http://oakroadsystems.com/tech/faqget.htm
Perhaps, but that guarantee isn't part of the C++ standard. I'm curious
- what is it a part of? I've heard of 32-bit implementations that
violated that guarantee: 8-bit char, 32-bit short, int, long, float, and
pointer, 64-bit double. Therefore, it's not a guarantee that follows
logically just from being a 32-bit implementation.
> (although people here might argue that C++ does not technically require
> _int16 any more than it requires _int7). _int64 is required for some
"might" argue? Why do you have any doubt about it? "technically"? What's
technical about the fact that '_int16' has no more support in the
standard than 'shortest' or 'longer'? It's a pure extension, with no
connection to the C++ standard of any kind.
Richard John Cavell wrote:
>
> On Wed, 28 Jun 2000, Greg Brewer wrote:
>
> > I just discovered that Borland C++ supports types of __int64, __int32,
> > __int16, and __int8. Is this standard or an extension? Does MS or any
> > other C++ support it?
>
> The existence of the three smallest types is guaranteed on any 32-bit
> implementation... you might just find them under a different name
> (although people here might argue that C++ does not technically require
> _int16 any more than it requires _int7).
The standard doesn't require an 8 bit type. It doesn't require a 16 bit type.
It doesn't require are 32 bit type. The only requirement is that there is a type
at least 16 bits and that the progression of char, short, int, long gives you
types that are either the same or greater in size each step.
Greg
> >I just discovered that Borland C++ supports types of __int64, __int32,
> >__int16, and __int8. Is this standard or an extension? Does MS or any
> >other C++ support it?
>
> The leading double underscore is a good tipoff that it's non-
> standard. Borland has quite properly created these identifiers out
> of the set of names reserved to the implementation.
---
If you mean "require an exact 8-bit type", etc., yes, you are correct.
> The only requirement is that there is a type at least 16 bits and
> that the progression of char, short, int, long gives you types that
> are either the same or greater in size each step.
This implies that all the integer types could be 16 bits wide, which
is incorrect.
The requirements are that:
- 'char' must hold at least 8 bits
- 'short' must hold at least 16 bits
- 'int' must hold at least 16 bits
- 'long' must hold at least 32 bits
- 'float' must hold at least 6 (decimal) digits
- 'double' must hold at least 10 (decimal) digits
The ISO C++ requirements are borrowed from the ISO C requirements,
in ANSI/ISO 9899-1990, 5.2.4.2.
--
David R. Tribble, mailto:da...@tribble.com, http://david.tribble.com
You look like a man who needs a typedef. At least then you only
have to fiddle with one line of code when you change compiler.
#if defined(__STDC_VERSION__)
typedef long long int64_t;
#else
typedef __int64 int64_t;
#endif
int64_t f(void);
Better still (since it is likely to be the direction that C++ takes
in future) you might look into the C9X "stdint.h" header, which
you can (probably?) pick up from www.boost.org.
Long is required to be at least 32 bits.
In C99, you can write the following:
#include <stdint.h>
#ifdef INT64_MAX
// The optional type with exactly 64 bits exists
int64_t f(void);
#else
// The type with at least 64 bits is mandatory
int_least64_t f(void);
#endif
I think you can reasonably assume that future versions of the C++
standard will borrow this feature of C99. C++ compilers that share code
with C99 compilers will probably provide <stdint.h> as an extension much
earlier than that.
Greg Brewer wrote:
> ...
> I just discovered that Borland C++ supports types of __int64, __int32,
> __int16, and __int8. Is this standard or an extension? Does MS or any
> other C++ support it?
> ...
Ye, MS Visual C++ does support these types (don't know about others).
And no, they are not standard. It is an extension.
Best regards,
Andrey.
hm... since most (all?) of <stdint.h> can be implemented as typedefs,
(well, actually that assumes already having a 64 bit integral type;
I guess I am too used to the ubiquity of 'long long' on unices)
I would suspect it will be a matter of whether <stdint.h> comes with
the compiler / c library.
(As one example, gcc (freestanding C compiler) does not support
int64_t and friends. However, if the system C library has
<stdint.h>, (linux with glibc >= 2.1.2 being one example), int64_t
etc work fine with C++, as they are only typedefs. )
<stdint.h> includes a fair number of macros.
> (well, actually that assumes already having a 64 bit integral type;
> I guess I am too used to the ubiquity of 'long long' on unices)
C99 requires the existence of 'long long', int_least64_t, int_fast64_t,
and intmax_t, all of which are required to be at least 64 bits.
How about writing a class that behaves like a 64-bit integer? On a 32-bit
architecture, the compiler must typically simulate 64-bit operations with
multiple 32-bit operations. There is no reason why you cannot write
more-or-less portable code that does the same, and is reasonably efficient.
Daniel Pfeffer
My concern is mktime which will max out early in 2038. I have a number of
data structures that are read from disk with 32 bit time fields. My
structure also has an integer basedate field which is zero for now. My plan
is to create a mktime64 function that will return the 64 bit elapsed time
since 1970. I have an idea or two on how to do it just no time. I also
plan to create a function that will return the 64bit time from the basedate
and the 32 bit field. basedate will probably be some multiple of number of
years so that
ts64 = ts32 + basedate * numberofyears
and number of years will probably be some mutlple of 4. That will carry me
until Feb of 2100. Hopefully, the question will be moot by then.
Greg
"Daniel M. Pfeffer" <pfef...@nospam.internet-zahav.net> wrote in message
news:newscache$uel4xf$zvi$1...@lnews.actcom.co.il...
Greg Brewer wrote:
>
> I thought about it.
>
> My concern is mktime which will max out early in 2038. I have a number of
> data structures that are read from disk with 32 bit time fields. My
> structure also has an integer basedate field which is zero for now.
The DEC-10 processors had an "epoch" bump when they ran out of bits in the
late 70's.
If the year 2100 is all you care about, you don't need 64-bit numbers.
Just switch to unsigned! The extra bit will buy you another 68 years
and you'll be ok until 2106.
- Anders
Take a look at my proposal at
<http://david.tribble.com/text/c0xtime.htm>.
My proposal uses a 64-bit signed integer time type, yielding date
values from BC 9999 to AD 9999 (all possible four-digit year values)
with microsecond accuracy.
Other proposals include one by Markus Kuhn at
<http://www.cl.cam.ac.uk/~mgk25/c-time/>,
and one by Paul Eggert at
<http://www.twinsun.com/tz/timeapi.html>.
You'll have to deal with leap seconds, timezones, etc., in order to
be reasonably complete.
--
David R. Tribble, mailto:da...@tribble.com, http://david.tribble.com
---
Only for 32-bit Unix. Implementations with 64-bit time_t values
will not be affected (although transferring data files between the
two types of systems is problematic). IBM OS/390 uses a 64-bit clock,
but it will also run out of bits in 2047. Windows uses a 64-bit
clock internally, but implements time_t as a 32-bit int, so it has
the same problem as 32-bit Unix.
Switching to unsigned will also lose the ability to represent times
before the epoch (1970 in this case).
Systems are naturally evolving to support 64-bit integers. Long
before signed 32-bit time_t runs out in 2038, I predict that typical
systems will have at least signed 64-bit time_t. (It may also be
common for time_t to have a granularity finer than 1 second, perhaps
64 bits signed for the number of seconds and 64 bits unsigned for
fractions of a second.)
If you need to represent times in the future, you need to use
something other than time_t. If all you're concerned about is, say,
file creation timestamps, you might as well stick with time_t *and*
make sure your code doesn't depend on its representation. When future
systems solve the Y2.038K problem (or Y0.9951171875K if you prefer),
just recompile your code (and possibly convert your data files if
you've written time_t values to long-term storage).
--
Keith Thompson (The_Other_Keith) k...@cts.com <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Welcome to the last year of the 20th century.
David R Tribble wrote:
>
> Greg Brewer wrote:
> >
> > My concern is mktime which will max out early in 2038.
>
> Only for 32-bit Unix. Implementations with 64-bit time_t values
> will not be affected (although transferring data files between the
> two types of systems is problematic). IBM OS/390 uses a 64-bit clock,
> but it will also run out of bits in 2047. Windows uses a 64-bit
> clock internally, but implements time_t as a 32-bit int, so it has
> the same problem as 32-bit Unix.
The epochs are different as well. Doesn't the IBM use 1900?
Ron Natalie wrote:
>
> David R Tribble wrote:
>>
>> Greg Brewer wrote:
>> >
>> > My concern is mktime which will max out early in 2038.
>>
>> Only for 32-bit Unix. Implementations with 64-bit time_t values
>> will not be affected (although transferring data files between the
>> two types of systems is problematic). IBM OS/390 uses a 64-bit
>> clock, but it will also run out of bits in 2047. Windows uses a
>> 64-bit clock internally, but implements time_t as a 32-bit int,
>> so it has the same problem as 32-bit Unix.
>
> The epochs are different as well. Doesn't the IBM use 1900?
IBM OS/390 uses a 64-bit counter which counts the number of ticks
since 1900-01-01 00:00:00.000. Each tick is 2**-12 microseconds,
thus the upper 32 bits is a "large" second of 2**20 microseconds.
It's also already an unsigned value (the upper bit flipped over
several years ago). But it still has the same problem as 32-bit
POSIX, in that its end of epoch date is less than 50 years away.
Microsoft uses an epoch starting at 1601-01-01 00:00:00.000 GMT
(counting backward from the current calendar and ignoring the
historical Gregorian calendric change in 1585/1752), with 100 nsec
ticks (even though you can only retrieve system times to the nearest
millisecond). But all of the Microsoft C libraries implement a
32-bit time_t based on the 1970 epoch. (They even embed 32-bit
time_t dates within their object files.)
Embedded 32-bit POSIX time_t values are quite pervasive. PGP uses
them for its encryption timestamps, for example. No telling how
many other physical file formats contain 32-bit POSIX time_t
values that may survive the next 40 years. Moving to a 64-bit
representation is only half the battle; converting existing data
files will be the (quite large) other half. That effort will not
begin in 40 years, but has already started.
--
David R. Tribble, mailto:da...@tribble.com, http://david.tribble.com
---
Greg Brewer wrote in message <8jqed1$1ejg$1...@news.hal-pc.org>...
>> My concern is mktime which will max out early in 2038.
> [...]
>> That will carry me
>> until Feb of 2100. Hopefully, the question will be moot by then.
Anders J. Munch wrote:
> If the year 2100 is all you care about, you don't need 64-bit numbers.
> Just switch to unsigned! The extra bit will buy you another 68 years
> and you'll be ok until 2106.
Except of course that you can't do signed comparisons or differences
between time_t values reliably. That's why POSIX defines time_t to
be a signed type. (ISO C only specifies that it is an arithmetic
type.)
Also, an unsigned time_t will not be able to represent times prior
to the epoch (e.g., 1970). This is a problem already, though, since
ISO C defines '(time_t)(-1)' to represent an error value. Pity that
ISO didn't mandate a '_TIME_ERROR' macro instead.
In learning this profession, the protagonist (Pham Nuwen) is incensed
to find layers of junk and old assumptions. For example, he complains
that all the layers of software think that time started about the time of the
first moon landing on Old Earth, except they didn't quite get it right,
and hit 1970 instead :-)
--
-John Mashey EMAIL: ma...@sgi.com DDD: 650-933-3090 FAX: 650-933-2663
USPS: SGI 1600 Amphitheatre Pkwy., ms. 562, Mountain View, CA 94043-1351
[snip]
>Also, an unsigned time_t will not be able to represent times prior
>to the epoch (e.g., 1970). This is a problem already, though, since
>ISO C defines '(time_t)(-1)' to represent an error value. Pity that
>ISO didn't mandate a '_TIME_ERROR' macro instead.
Why do you see this as a problem already? (time_t)(-1) for an
unsigned time_t is just a way of writing U{time_t}_MAX without
having to know what type time_t is.
I do think it's stylistically ugly, but that's another matter.
Stan
He means that even signed time_t can't be used to represent times
earlier than (time_t)0, because (time_t)-1 has already been
commandeered for something other than representing a time.
paul
It's a problem if time_t is signed, because it inserts an invalid
value in the middle of the representable range. (On typical current
implementations, it means that 1969-12-31 23:59:59 is an error.)
If time_t is unsigned, using -1 isn't a problem (the error value is at
the end of the representable range) -- but making time_t unsigned
makes it impossible to represent times before the epoch.
The proper solution, IMHO, is:
Make time_t signed.
Make its range unreasonably big (64 bits should do it).
Use a macro for the error value, and put it at the far end
of the range (say, -2**63).
And, of course, continue to allow for variations (e.g.,
granularities finer than second).
All of these are compatible with the current standard except the macro
for an error value.
--
Keith Thompson (The_Other_Keith) k...@cts.com <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Welcome to the last year of the 20th century.
---
Because at least on Unix/POSIX platforms (time_t)(-1) is a legal value
representing Dec 31, 1969 23:59:59 GMT (UTC didn't exist until the
early 70's).
-hpa
--
<h...@transmeta.com> at work, <h...@zytor.com> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt
Sure it can, but it means that *one* particular time can be
confused with the error case.
Usurping a value to return an error (or EOF) indication was
very common in the UNIX C library. It is pretty well understood
now that that is not the best way to design function interfaces.
>Because at least on Unix/POSIX platforms (time_t)(-1) is a legal value
>representing Dec 31, 1969 23:59:59 GMT (UTC didn't exist until the
>early 70's).
Actually, UTC did exist back then, though not in the same form as today
(as it didn't have leap seconds). As a standard, GMT became obsolete
in the 1920s.
Both of these statements seem to assume that time_t is a linear
monotonic type; that is, that adding 1 to an (arithmetic) time_t is a
meaningful thing to do.
It is quite legitimate *in ISO C* (POSIX has its own rules and must
solve its own problems where they differ) for time_t to encode the time
in some other manner. For example, it could be a collection of bitfields
holding the various components of the time. The 1 bit does not have to
represent the smallest unit of time; it could be that years are at that
end and seconds at the sign bit end.
In particular, (time_t)(-1) need not represent a valid time in that
encoding.
--
Clive D.W. Feather | Internet Expert | Work: <cl...@demon.net>
Tel: +44 20 8371 1138 | Demon Internet | Home: <cl...@davros.org>
Fax: +44 20 8371 1037 | Thus plc | Web: <http://www.davros.org>
Written on my laptop; please observe the Reply-To address
Microsoft C/C++ 7 used a time_t counting seconds from 1899-12-31
(or was it an option?) Quite a nuisance, probably, so they revert
back. The funny part is that they explained that was for ANSI C
compatibility...
Antoine
That's true, but using (time_t)(-1) as an error indication does poke a
hole in the representable range for the most convenient representation
on many systems (a signed integer type with a linear monotonic mapping
to real time). A macro like TIME_ERROR would allow an appropriate
value to be chosen for any representation. Unfortunately, this would
be a difficult change to make (a lot of existing code depends on
(time_t)(-1) as an error value) unless we initially mandate
TIME_ERROR == (time_t)(-1).
Though it's too late to fix for C99, it would be nice (IMHO) if a
future standard were to guarantee monotonicity and uniqueness (though
not necessarily linearity) for time_t. This would allow safe use of
relational operators on time_t values. If monotonicity is too much of
a burden (are there any implementations that aren't monotonic?), at
least uniqueness would be good. More specifically, even if time_t has
more than one representation for a given time, the standard could
guarantee that any standard function that returns a time_t always
returns a unique value for any time.
--
Keith Thompson (The_Other_Keith) k...@cts.com <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Welcome to the last year of the 20th century.
---
Stan Ryckman wrote:
> Why do you see this as a problem already? (time_t)(-1) for an
> unsigned time_t is just a way of writing U{time_t}_MAX without
> having to know what type time_t is.
>
> I do think it's stylistically ugly, but that's another matter.
Why not provide a _TIME_ERROR constant that represents an invalid
time_t value. And why -1? Why not ((time_t)INT_MIN)?
As I've asked before, why not have several macros that define the
range of time_t?:
_TIME_ERROR invalid time_t value, or error
_TIME_MIN minimum valid time_t value
_TIME_MAX maximum valid time_t value
_TIME_TICKS_PER_SEC resolution of time_t values
--
David R. Tribble, mailto:da...@tribble.com, http://david.tribble.com
---
Clive D.W. Feather wrote:
> Both of these statements seem to assume that time_t is a linear
> monotonic type; that is, that adding 1 to an (arithmetic) time_t is a
> meaningful thing to do.
No - my argument only assumes that some negative time_t values can
represent valid dates on some systems.
> It is quite legitimate *in ISO C* (POSIX has its own rules and must
> solve its own problems where they differ) for time_t to encode the
> time in some other manner. For example, it could be a collection of
> bitfields holding the various components of the time. The 1 bit does
> not have to represent the smallest unit of time; it could be that
> years are at that end and seconds at the sign bit end.
>
> In particular, (time_t)(-1) need not represent a valid time in that
> encoding.
But it certainly screws things up for systems in which (time_t)(-1)
does represent a valid time, doesn't it? At the very least, it's
not very portable, is it?
Wouldn't having an explicit _TIME_ERROR macro be a bit cleaner?
Exactly.
> Usurping a value to return an error (or EOF) indication was
> very common in the UNIX C library. It is pretty well understood
> now that that is not the best way to design function interfaces.
Except that the examples you're (probably) referring to, i.e.,
Unix system calls and I/O functions, the usurped values were not
also valid return values of those functions. Unix system calls
returned positive values on success and -1 on error; character I/O
functions returned positive character codes or -1 on end of file.
And functions that return pointers return non-null pointers on
success and null on failure.
Returning a special value that otherwise can't be returned in order
to indicate an error is a perfectly acceptable practice (especially
if you don't have, or want, exception handling).
But stealing a perfectly good value from the middle of the time_t
range of values was a bad idea (which was my original point).
I suspect you know the answer -- that's what was already implemented.
Frankly, I would not encourage the use of in-band signalling in any
new design for a function interface.
Often they could be, but weren't normally in the limited contexts
of the early UNIX systems. The plain fact is that there was a
common piece of run-time support code that set errno and returned
(int)-1, and it was taken as the canonical way to report an error
from a wide variety of functions, often a "no brainer" when some
brainwork should have been exerted instead. If you rummage through
the legacy functions, you often run into (somepointer)-1 which is
simply disgusting.
Because this is fiddling round the edges when we really need to redesign
from scratch.
--
Clive D.W. Feather | Internet Expert | Work: <cl...@demon.net>
Tel: +44 20 8371 1138 | Demon Internet | Home: <cl...@davros.org>
Fax: +44 20 8371 1037 | Thus plc | Web: <http://www.davros.org>
Written on my laptop; please observe the Reply-To address
---
(time_t)-1 is perfectly portable. Assuming that time_t has arithmetic
properties is what isn't portable.
Not at all. time_t is required to have arithmetic properties, as
it is an arithmetic type. Assuming that its arithmetic properties
bear any relationship to time as we know and love it (whether UTC
or other) is what isn't defined by the standard.
Regards,
Nick Maclaren,
University of Cambridge Computing Service,
New Museums Site, Pembroke Street, Cambridge CB2 3QG, England.
Email: nm...@cam.ac.uk
Tel.: +44 1223 334761 Fax: +44 1223 334679
Clive D.W. Feather wrote:
> Because this is fiddling round the edges when we really need to
> redesign from scratch.
Good point.
So who is going to lead the charge for the redesigned time/date
library functions for C0X? There are several good ideas contributed
by myself and others which would make a good starting point. And
there are probably a few good ideas to borrow from outside C (I'm
thinking specifically of Java's Date/Calendar/TimeZone classes).
--
David R. Tribble, mailto:da...@tribble.com, http://david.tribble.com
---
I'm not so sure of that... legal time_t values might be
trap representations of the underlying arithmetic type for
arithmetic computations (other than comparison for equality
to -1), as far as I can see.
I'm not sure that one can even compare two time_t values for equality
without introducing undefined behavior, though there does seem to
be at least an implication that it's OK if one of them is
(time_t)-1.
>Assuming that its arithmetic properties
>bear any relationship to time as we know and love it (whether UTC
>or other) is what isn't defined by the standard.
Agreed.
Stan
Assuming that time_t *doesn't* have arithmetic properties is equally
non-portable. Using -1 as an error indication imposes an unreasonable
constraint on implementations. (I understand the historical reasons,
and I know it would be difficult to fix without breaking existing
code, but it is a Bad Thing.)
--
Keith Thompson (The_Other_Keith) k...@cts.com <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Welcome to the last year of the 20th century.
---
>And there are probably a few good ideas to borrow from outside C (I'm
>thinking specifically of Java's Date/Calendar/TimeZone classes).
Java's TimeZone classes are a good example of what _not_ to do.
The last time I checked, there was no way to implement accurate time
zone support that is compatible with Java's TimeZone abstract class.
This is because the designers of TimeZone didn't understand how
complicated time zone rules actually are in practice. Even C89's time
primitives are better than Java's.
======================================= MODERATOR'S COMMENT:
[ Warning, topic drift... -mod ]
David R Tribble <da...@tribble.com> writes:
>> And there are probably a few good ideas to borrow from outside C
>> (I'm thinking specifically of Java's Date/Calendar/TimeZone
>> classes).
Paul Eggert wrote:
> Java's TimeZone classes are a good example of what _not_ to do.
> The last time I checked, there was no way to implement accurate time
> zone support that is compatible with Java's TimeZone abstract class.
> This is because the designers of TimeZone didn't understand how
> complicated time zone rules actually are in practice. Even C89's time
> primitives are better than Java's.
Okay, okay, not all ideas in the Java library are worth stealing;
scratch the TimeZone classes.
But I do like the underlying concept of (but not necessarily the
interface to) Java's Calendar class, which separates time/date
representation from external human representations. [Making the
point relevant to C again...] I think it would be useful to look
at other time/date implementations, such as Common LISP and Java,
when we undertake the task of redesigning the C library.
In particular, I think it would be simpler to have an internal
but predictable representation for dates (i.e., a new time_t) which
is capable of subsecond resolution and a 1000+ year range, but which
does not concern itself with timezones, daylight savings time, or
leap seconds. (Perhaps we could call this new type 'date_t'?)
It seems to be widely accepted that the current time_t definition
is just too vague, so a new definition would require pinning down
a few more details:
A. the range of years it is capable of repesenting (minimum and
maximum year values), probably as simple macros;
B. the resolution of time it is capable of representing (e.g.,
ticks per second at its highest resolution), probably as a simple
macro;
C. a better "error" (or "unknown" or "never") time value.
Such a primitive date value could then be expanded into an
appropriate calendric representation (e.g., good ol' Gregorian),
a la 'struct tm'. That representation could be further modified
for a given timezone, and further yet for daylight savings time,
and possibly further yet for leap seconds (if we really must).
But only as separate steps; I think the existing tm struct is
too complicated because it attempts to include all three pieces
of information in one single struct, rather than separating them
out for convenience.
Then there are additional library functions that could be added.
In particular, it would be nice to have a pair of complementary
functions:
1. one determines the difference between two times in broken-down
form (e.g., the delta between 2000-01-01 and 2001-01-01 is 1y 1m 1d,
which is also 366 days).
2. the other adds a delta in broken-down form to a time, yielding
a new time (e.g., adding 1y 1m 1d to 2000-01-01 yields 2001-01-01,
and adding 0y 0m 366d yields the same).
--
David R. Tribble, mailto:da...@tribble.com, http://david.tribble.com
---
How could it usefully have subsecond resolution without leap seconds?
There was a time API working group that was supposed to be working
out a good design; in fact we backed out an attempt at an extended
struct tms and some other supposed improvements when a few problems
surfaced, with the expectation that the working group would get it
right and we could pick up their solution later. Whatever happened
to them?
However, in C++, you could do it better with templates:
template<size_t n> struct int_type
{
typedef ... exact; // only defined if exact type exists
typedef ... smallest; // defined for n<=some maximum value
typedef ... fastest; // dito
};
(Of course, there should also be typedefs for unsigned types)
F.ex. an implementation with 8-bit char, 16-bit short, 32-bit int
and 64-bit long, where int is the fastest type, could have the
definitions (assuming the template recursion limit is high enough):
template<size_t n> struct int_type
{
typedef typename int_type<n+1>::smallest smallest;
typedef typename int_type<n+1>::fastest fastest;
};
template<> struct int_type<8>
{
typedef signed char exact;
typedef signed char smallest;
typedef int fastest;
};
template<> struct int_type<16>
{
typedef short exact;
typedef short smallest;
typedef int fastest;
};
template<> struct int_type<32>
{
typedef int exact;
typedef int smallest;
typedef int fastest;
};
template<> struct int_type<64>
{
typedef long exact;
typedef long smallest;
typedef long fastest;
};
Now you could write
int_type<30>::fastest i;
and could be sure that you get the fastest type with at
least 30 bits. That's far more flexible than the C solution
(which helps only for the common sizes).
>There was a time API working group that was supposed to be working
>out a good design.... Whatever happened to them?
A mailing list was set up but I never got any email on it.
As far as I know, no progress has been made since the current
proposals on the table:
Bernstein ftp://koobera.math.uic.edu/www/libtai.html
Eggert http://www.twinsun.com/tz/timeapi.html
Kuhn http://www.cl.cam.ac.uk/~mgk25/c-time/
Tribble http://home.flash.net/~dtribble/text/c0xtime.htm
I think that these proposals are all too elaborate and need
simplifying, but it'll take some more experience, consensus-building,
and work. Bernstein's proposal has the most experience (with real
code), but the least consensus (he's using TAI, which many people find
off-putting).
The POSIX standardization effort has a discussion group
pasc-ti...@opengroup.org also looking at the subject. Write
Andrew Josey <ajo...@rdg.opengroup.org> to join. Leading lights of
that group include Markus Kuhn of Cambridge University and Donn Terry
of Microsoft. The group seems to be leaning toward defining a new time
type (xtime_t, say?), which is arithmetic and which counts some small
fraction of a second (nanoseconds, say?). However, there's no
commitment yet to try to standardize anything; it's still exploratory.
The two groups should coordinate but as far as I know this hasn't been
done yet.
One of the awkward aspects of the current time_t is that the
difference between two time_t values is a time_t, not a time_diff_t.
A second would be representable as a value of time_diff_t.
Through the wonders of operator overloading and the addition of a
few more types, one can make arithmetic on times account for the
variability in the length of a month, and, given the necessary tables,
the variability in the length of a day.
--Lisa Lippincott
The C solution allows other sizes, it just doesn't require them. In C99
<stdint.h> is allowed to typedef intN_t for any value of N; if it does
that typedef must represent an exactly N-bit integer, along with all the
corresponding macros. Similarly for the other sized integer types, such
as int_leastN_t. Implementing int_leastN_t efficiently for arbitrary N
would call for a bit of compiler magic, but it would be possible and
legal.
Still, I take your point.
[ ... ]
> One of the awkward aspects of the current time_t is that the
> difference between two time_t values is a time_t, not a time_diff_t.
At least as computed by difftime, the difference between two time_t's
is a double. The only mention of computing differences I see in the
C++ standard is in section 20.5, which basically just refers back to
the C standard (and difftime) for all the details. Have I missed
something that computes the difference between two time_t's as
another time_t?
--
Later,
Jerry.
The universe is a figment of its own imagination.
I'd like to think that people know better now, but i'm not so sure.
It may be interesting that earlier conventions, when people wrote in
assembler, are often something like, the carry bit is set on error, and
this is always checked first, so again the error is out of band.
I've worked with coding guidelines which say that all functions should
return an error code, and any actual data is passed back via parameters.
Over time, i'm only more convinced that this is the way to go.
New functions can be provided which follow this.
--
Joe Keane, amateur mathematician
Um, do you really mean _all_ functions? Somehow I don't think this
will work very well. How would one write nontrivial expressions
containing function calls? For example, how would one write the
equivalent of the present-day C/C++ expression
#include <math.h>
/* ... */
double fn = exp(-2.0*beta)
* (sin(2*phi)*cos(theta) + log(cos(2*phi)*sin(theta)));
if each of those trancendental function calls had to return its "real"
result via a parameter? We'd end up basically writing assembler code,
with temp variables for each function call. No thanks!
Yes, errno is a well-known wart in C/C++'s <math.h>. Yes, it's a
performance hit for multithreading. Yes, it's hard to use effectively.
Yes, IEEE nans aren't well-supported in pre-C99 C, and still require
nonstandard hacks to use effectively. Yes, they have their own performance
problems. (Not to mention lots of user problems too.)
But I think the proposed solution would be even worse.
[For C I don't know what would be better, but C++ exceptions provide
a possible solution to this problem.]
--
-- Jonathan Thornburg <jth...@thp.univie.ac.at>
http://www.thp.univie.ac.at/~jthorn/home.html
Universitaet Wien (Vienna, Austria) / Institut fuer Theoretische Physik
"Think about it. Would you work for a company that couldn't tell the
difference in quality of its employees' normal work product and the
work product of someone on drugs without performing a test?" -- anon
Yes, he probably means all functions and, yes, you are correct about
the consequences. However, you have missed a few delightful "gotchas"
in both C90 and C99 (and almost certainly C++):
A) If two of those function calls set errno, then the behaviour
is undefined. So the only correct way to write standard C is not to
call more than one library function between two sequence points,
anyway. Autocode, anyone?
B) Once you start dabbling with 'IEEE' support in C99, there are
similar constraints for similar reasons. At a very late stage, C99
was 'clarified' to state that the IEEE flags do not have object
semantics, but you won't always get the effect you expect if you
have more than one operation or function call in an expression.
C) If the implementation uses the traditional and best fail
safe approach (i.e. an interrupt), it is virtually impossible to
conform with C90, let alone C99. So it isn't done.
There are many ways of handling error returns correctly, and Joe
Keane's approach is only one. All of the following work, and are
reliable and efficient WHEN DESIGNED AND IMPLEMENTED CORRECTLY:
1) Always returning an error indication.
2) Accumulating error flags until (say) a function return.
3) Returning and percolating an error value.
4) Raising an exception.
5) Calling an alternate return (e.g. SNOBOL).
6) And probably others ....
Unfortunately, in all cases, we don't want to start from here.
Regards,
Nick Maclaren,
University of Cambridge Computing Service,
New Museums Site, Pembroke Street, Cambridge CB2 3QG, England.
Email: nm...@cam.ac.uk
Tel.: +44 1223 334761 Fax: +44 1223 334679
---
Jerry Coffin wrote:
> At least as computed by difftime, the difference between two time_t's
> is a double. The only mention of computing differences I see in the
> C++ standard is in section 20.5, which basically just refers back to
> the C standard (and difftime) for all the details. Have I missed
> something that computes the difference between two time_t's as
> another time_t?
time_t now = ...;
time_t then = ...;
time_t diff = (then - now);
The 'diff' value is the difference between two time_t values and is
itself of type time_t. However, it is pretty much useless unless
you happen to know what representation your local machine uses for
time_t. All you know is that time_t is arithmetic, which means you
can subtract two time_t values. But the result may or may not be
meaningful (especially if time_t is actually a set of concatenated
bitfields), and is certainly not portable.
So, no, you haven't missed anything - there is no standard library
function that computes the difference between two time_t values
as a time_t value. The closest thing we have is difftime(), which
gives you the difference in seconds as a double value, which is more
useful and portable (if you don't mind using floating point).
--
David R. Tribble, mailto:da...@tribble.com, http://david.tribble.com
---
James Kuyper wrote:
> How could it usefully have subsecond resolution without leap seconds?
There is a difference between resolution and accuracy. The basic
problem with including leap seconds in any time representation is the
uncertainty incurred when dealing with future time values.
E.g., I want the date that is exactly one year from the current date;
logically, all I should have to do is add 365 days, but how do I
account for possible leap seconds that may or may not occur during
the next year? I can't, because future leap seconds do not occur in
a linear or predictable fashion (unlike leap days, which follow
simple rules). The simplest solution, then, is to choose a time
representation that ignores leap seconds entirely.
Such a representation, however, can still have as high a resolution
as one chooses. E.g., if you choose a representation capable of
microsecond resolution, you can rely on that fact when you add 365
days worth of microseconds to one value in order to arrive at another
(future) time value.
(IIRC, doesn't the UTC reckoning of time ignore leap seconds, such
that the current drift between geological TAI time and UTC is now
about 32 seconds?)
Most system clocks differ from the international time standard by
a few seconds or even minutes; do sysadmins update their system
clocks when a new leap second is decreed? I doubt it.
The approach is "simple," yes, but it's hardly a "solution."
For example, it doesn't solve the problem you posed: find the
date which is exactly one year from the current date. Run *any*
proposed solution at 23:59:59 on 31 December, and the presence or
absence of a leap second can even influence the tm_year field
(or its analog) of the result.
Simple approaches to this problem are doomed. Even the most
complex approaches are unable to solve the generalized problem: as
someone once pointed out, nobody knows whether New Years' Day of
AD 1000000 will be a Tuesday.
> Most system clocks differ from the international time standard by
> a few seconds or even minutes; do sysadmins update their system
> clocks when a new leap second is decreed? I doubt it.
I have no data to support or defend your "most." However, means
of synchronizing system time to accurate external sources certainly
exist, and I imagine they are well-known to the administrators of
systems where accurate calendars are important.
Not true. In 3.9.1.2 C++ Standard 1998, it says
<<There are four signed integer types: "signed char", "short int", "int",
and "long int." In this list, each type provides at least as much storages
as those preceding it in the list. Plain ints have the natural size
suggested by the architecture of the execution environment; the other signed
integer types are provided to meet special needs.>>
Therefore, sizeof(char) <= sizeof(short) <= sizeof(int) << sizeof(long).
That also means that they all could be 8 bits of size.
Regards,
Sebastian Moleski
Well, if "the current date" means 2000-07-18, then that's correct.
But in general...
--
Mark Brader, Toronto "The language should match the users,
m...@vex.net not vice versa" -- Brian W. Kernighan
Please show me the reference into the C++ Standard that forces long to be at
least 32 bits.
TIA,
Sebastian Moleski
You've forgotten <climits>. C++ inherits from C the requirement that
SHRT_MAX be at least 32767. How could that be consistent with an 8 bit
short?
Where is it said that SHRT_MAX *must* be 32767?
Regards,
Sebastian Moleski
Nowhere. I didn't say that it did - reread the marked phrase above.
Section 18.2p4 of the C++ standard says "SEE ALSO: ISO C subclause
7.1.5, 5.2.4.2.2, 5.2.4.2.1". The relevant section of the C standard for
the requirement that SHRT_MAX >= 32767 is 5.2.4.2.1.
Section 18.2.2p4, which contains a cross-reference to section 5.2.4.2.1
of the C standard, which requires that LONG_MAX >=2147483647.
It's possible, and I believe fairly easy, to set up automatic updates to
keep in sync with the time standards, such as the ones put out by the US
Naval Observatory. I used to have the URL for a freeware product that
promised to synchronize my PC with the USNO each time I booted up.
Unfortunately, it was for the wrong version of Windows.
No it doesn't. Section 18 also places some requirements on the minimum
and maximum values that may be stored in shorts/ints/longs. These values
come from the C standard and mean that a long can not be shorter than 32
bits.
Paul
Unless the application is related to astronomy or GPS, it's unlikely that
leap seconds ever make a difference. In fact, I suspect that most
computers in the world are not synchronized closely to a standard time
base, so even if the date library knew about leap seconds, their clocks are
so far off that they don't matter. As long as the standard date library
specification has a caveat that it's designed to be sufficient for human
use, but not for astronomical precision, I think most people would be
happy. The astronomers probably have had time libraries for decades that
work for them, so they can ignore the standard in this regard.
--
Barry Margolin, bar...@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
Sebastian Moleski wrote:
> Please show me the reference into the C++ Standard that forces long to be at
> least 32 bits.
If this is not true, then there's a error in my favorite C++ book. The C++
Programming Language 3rd ed. 1st printing :) section 4.6 Sizes:
1 == sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)
1<= sizeof(bool) <= sizeof(long)
sizeof(char) <= sizeof(wchar_t) <= sizeof(long)
sizeof(float) <= sizeof(double) <= sizeof(long double)
sizeof(N) == sizeof(signed N) == sizeof(unsigned N)
where N can be char, short int, int or long int. In addition, it is guaranteed
that a char has at least 8 bits, a short at least 16 bits, and a long at least
32 bits.
--
Claude Quézel (claude...@syntell.corba)
anti-spam: replace corba by com in private replies
So? Lots of things are easy, but you don't bother because they're not
important. Outside of some very specialized applications (astronomy, GPS),
clock accuracy within a second is rarely important.
--
Barry Margolin, bar...@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
---
Mark Brader wrote:
> Well, if "the current date" means 2000-07-18, then that's correct.
> But in general...
Yes, I know, adding 365 days to simulate adding one year doesn't
work across leap years.
That's one reason, as I posted previously, that I think we need
standard library function to add and subtract broken-down times.
I.e., one function that allows me to add <1y 0m 0d 0h 0m 0s> to
a given date and return the normalized date (which I can probably
already do using the current <time.h> functions); and another
function that allows me to determine the broken-down difference
between two dates (e.g., the difference between <2000-01-01 00:00:00>
and <2001-01-01 00:00:00> is <1y 0m 0d 0h 0m 0s>, even though the
difference is actually 366 days) (this I cannot do conveniently
with the existing library functions).
--
David R. Tribble, mailto:da...@tribble.com, http://david.tribble.com
---
If SHRT_MAX defines the maximum size of a short in C++ as well, it
contradicts with the part of the C++ Standard I quoted before. Maybe this
should be a cause for a DR?
Regards,
Sebastian Moleski
Eric Sosman wrote:
> The approach is "simple," yes, but it's hardly a "solution."
> For example, it doesn't solve the problem you posed: find the
> date which is exactly one year from the current date. Run *any*
> proposed solution at 23:59:59 on 31 December, and the presence or
> absence of a leap second can even influence the tm_year field
> (or its analog) of the result.
But you missed my whole point, which was to choose a simple
representation that avoids the entire issue of leap seconds. If your
time_t doesn't count leap seconds, then adding one year to
CCYY-12-31 23:59:59 always results in a "clean" CCYY-12-31 23:59:59.
No leaps seconds are involved.
> Simple approaches to this problem are doomed. Even the most
> complex approaches are unable to solve the generalized problem: as
> someone once pointed out, nobody knows whether New Years' Day of
> AD 1000000 will be a Tuesday.
But you can choose a calendric representation that dictates, in this
current decade, that it will or won't be (e.g., under the current
Gregorian calendar rules, AD1,000,000-01-01 will be a Saturday).
Choosing a relatively simple calendar (or at least one with regular
rules) with which to represent times allows for the most useful
time/date calculations, even if it can't account for all future
calendar changes that are sure to occur beyond the next century.
--
David R. Tribble, mailto:da...@tribble.com, http://david.tribble.com
---
>difftime(), which
>gives you the difference in seconds as a double value, which is more
>useful and portable (if you don't mind using floating point).
In practice, almost all serious computation using time_t uses signed
integer POSIX time stamps. I rarely see any serious use of difftime
in real software, and I see a lot of time-related code.
In particular, I would avoid difftime in software intended to be
portable to modern 64-bit POSIX hosts, unless you know that your
timestamps are within a safe range. For example, in 64-bit Solaris,
time_t and double are both 64-bit types, which means that difftime can
lose information due to rounding error. Worse, many 64-bit difftime
implementations round incorrectly in some cases.
> "James Kuyper" <kuy...@wizard.net>:
> > Sebastian Moleski wrote:
> > > "James Kuyper" <kuy...@wizard.net>:
> > > > Sebastian Moleski wrote:
> > > > > ....
> > > > > Therefore, sizeof(char) <= sizeof(short) <= sizeof(int) <<
> sizeof(long).
> > > > > That also means that they all could be 8 bits of size.
> > > > You've forgotten <climits>. C++ inherits from C the requirement that
> > > > SHRT_MAX be at least 32767. How could that be consistent with an 8 bit
> > ^^^^^^^^
> > > > short?
> > Section 18.2p4 of the C++ standard says "SEE ALSO: ISO C subclause
> > 7.1.5, 5.2.4.2.2, 5.2.4.2.1". The relevant section of the C standard for
> > the requirement that SHRT_MAX >= 32767 is 5.2.4.2.1.
> If SHRT_MAX defines the maximum size of a short in C++ as well, it
> contradicts with the part of the C++ Standard I quoted before. Maybe this
> should be a cause for a DR?
You mean : " Therefore, sizeof(char) <= sizeof(short) <=
sizeof(int) << sizeof(long). " ?
That's indeed another requirement of the standard. But how does it contradict
the requirement on SHRT_MAX?
The standard allows[1] sizeof(char) == sizeof (short) == sizeof (int)
if and only if a char can be 32767, too.
Michiel Salters
[1] There is a slight problem with int getc(); if sizeof(char)==sizeof(int).
Reading this thread, I've thought about the potential usefulness of
keeping inside the date representation weither the date was a future
date, for example a boolean "future" field.
Hum, now that I'm writing this down, I believe,, to be useful, the date
would need to contain the date on which it was calculated! So a date
would be entered as a composite representation of the current date plus
a signed high-precision quantity of seconds "delta" to reach, forward or
backward, the actual desired date. That way, it would be possible to
infer if leap seconds have been added or not. This presents the problem
that a single date may have multiple representations, but for archiving
purpose, date could be normalize to use the same "base time".
Hum, this sounds really like "epoch" and the current time_t. So this
scheme would simply be an extension of the current scheme... which is
good engineering. If the "current date" field is missing, simply use
"epoch".
Alternatively, one could simply keep to number of leap seconds added
since "epoch", so that if that number differs from the official one, one
would know that either the algorithm that calculated the date was not
updated recently or that the date was calculated before the new leap
second(s) were added.
Oh well, if any of this makes sense and would be useful, then I suppose
it has already been patented...
> In article <3973B10A...@wizard.net>,
> James Kuyper <kuy...@wizard.net> wrote:
> >David R Tribble wrote:
> >....
> >> Most system clocks differ from the international time standard by
> >> a few seconds or even minutes; do sysadmins update their system
> >> clocks when a new leap second is decreed? I doubt it.
I believe that the NTP protocol does know about leap seconds. Anyone
not using something like NTP probably couldn't tell if their system
clock was off by one second, since typical computer clocks drift by
more than a second a month anyway.
> >It's possible, and I believe fairly easy, to set up automatic updates to
> >keep in sync with the time standards
>
> So? Lots of things are easy, but you don't bother because they're not
> important. Outside of some very specialized applications (astronomy, GPS),
> clock accuracy within a second is rarely important.
And NFS. The only reason anyone around here cares about the accuracy
of their system clock is so that make works on NFS-mounted filesystems.
--
- Geoffrey Keating <geo...@cygnus.com>
[ SNIP ]
> That's one reason, as I posted previously, that I think we need
> standard library function to add and subtract broken-down times.
> I.e., one function that allows me to add <1y 0m 0d 0h 0m 0s> to
> a given date and return the normalized date (which I can probably
> already do using the current <time.h> functions); and another
> function that allows me to determine the broken-down difference
> between two dates (e.g., the difference between <2000-01-01 00:00:00>
> and <2001-01-01 00:00:00> is <1y 0m 0d 0h 0m 0s>, even though the
> difference is actually 366 days) (this I cannot do conveniently
> with the existing library functions).
That's still not going to solve
29-02-2000 + { 1y, 0m, 0d } - { 1y, 0m, 0d },
is it?
Or, in words: Just exactly what do you mean with one year later?
Michiel Salters
>Outside of some very specialized applications (astronomy, GPS),
>clock accuracy within a second is rarely important.
I would add "make" (and therefore CVS, RCS, tar, cpio, ...) to that list.
That's why our software development hosts run NTP.
I would also add some financial applications to your list,
e.g. financial trading.
And Kerberos pretty much requires something like NTP,
and NTP needs to handle leap seconds correctly....
Leap seconds aren't just for the astronomers any more.
(Which is why some of the GPS guys are trying to kill off leap seconds....)
>(IIRC, doesn't the UTC reckoning of time ignore leap seconds, such
>that the current drift between geological TAI time and UTC is now
>about 32 seconds?)
The UTC second count ignores leap seconds, which means that the ideal
UTC clock jumps back immediately after an inserted leap second. To
avoid ambiguity in textual representation, the inserted leap second is
given a different broken-down-time (23:59:60 UTC instead of 00:00:00)
>Most system clocks differ from the international time standard by
>a few seconds or even minutes; do sysadmins update their system
>clocks when a new leap second is decreed? I doubt it.
This used to be true, but these days a lot of people run NTP or
something similar, and keep their clocks synchronized to within a few
milliseconds of the actual time. If you count GPS-based units, I'd say
that billions of hosts will care about leap seconds in a few years (or
even months :-) from now. Leap seconds are no longer just a scientific
curiosity.
Another -- and not so specialized -- application which wants synchronized
clocks down to the 1-second-or-better level is multi-processor (parallel)
'make'.
--
-- Jonathan Thornburg <jth...@thp.univie.ac.at>
http://www.thp.univie.ac.at/~jthorn/home.html
Universitaet Wien (Vienna, Austria) / Institut fuer Theoretische Physik
"Washing one's hands of the conflict between the powerful and the powerless
means to side with the powerful, not to be neutral."
-- quote by Freire / poster by Oxfam
It sets the mininum size of a short.
One requirement is that sizeof(char) <= sizeof(short) <= sizeof(int).
Another is that char be at least 8 bits, short be at least 16 bits, and
int be at least 16 bits. There is no conflict.
--
Steve Clamage, stephen...@sun.com
I'm pretty sure Kerberos is designed to allow drift of a few seconds.
--
Barry Margolin, bar...@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
---
Just FWIW, this is not really the same as clock accuracy. If all the
clocks were coordinated to say it was presently midnight, June 2,
1892, a parallel make would still be perfectly happy even though this
is obviously extremely inaccurate. Parallel make requires precision,
but not accuracy.
--
Later,
Jerry.
The universe is a figment of its own imagination.
Michiel Salters wrote:
> That's still not going to solve
>
> 29-02-2000 + { 1y, 0m, 0d } - { 1y, 0m, 0d },
>
> is it?
Arithmetic operations on dates is a lot like matrix operations, in
that they do not obey rules like commutativity and associativity.
Your example, for instance, adds a delta time to a date, then
subtracts a delta time, to yield a new date result. Using the
existing ISO C library, and assuming that date subtraction can be
implemented, we would get these intermediate results:
2000-02-29 + {1y 0m 0d}
= 2001-02-29, normalized to 2001-03-01
2001-03-01 - {1y 0m 0d}
= 2000-03-01, already normalized
So adding "one year" to 2000-02-29 (a leap day) and then subtracting
"one year" would result in 2000-03-01. But like I said, don't expect
these operations to obey normal laws of arithmetic, because you're
not dealing with normal arithmetic values.
> Or, in words: Just exactly what do you mean with one year later?
A common concept of "one year later" is to simulate flipping the
pages of a calendar ahead twelve months and pointing to the same
day in the future month as the current day in the present month.
I.e., the simplest concept is "add one to the year", then normalize
the result to allow for leap days and such.
You get into the same problem areas when defining "one month later",
when months obviously don't have the same number of days. But if
I say "two months from now" and "now" is 2000-07-19, I am pretty safe
in assuming that most people would agree that 2000-09-19 is a
reasonable date to choose. Dates like 2000-07-31, however, pose a
problem that is best solved, as above, by simply normalizing the
result.
While adding days to a given date is fairly strightforward, adding
things like "90 working days" create problems. Again, normalize,
normalize, normalize.
--
David R. Tribble, mailto:da...@tribble.com, http://david.tribble.com
---
David R Tribble wrote:
>> But you can choose a calendric representation that dictates, in this
>> current decade, that it will or won't be (e.g., under the current
>> Gregorian calendar rules, AD1,000,000-01-01 will be a Saturday).
Pierre Baillargeon wrote:
> Reading this thread, I've thought about the potential usefulness of
> keeping inside the date representation weither the date was a future
> date, for example a boolean "future" field.
>
> Hum, now that I'm writing this down, I believe,, to be useful, the
> date would need to contain the date on which it was calculated! So a
> date would be entered as a composite representation of the current
> date plus a signed high-precision quantity of seconds "delta" to
> reach, forward or backward, the actual desired date. That way, it
> would be possible to infer if leap seconds have been added or not.
> This presents the problem that a single date may have multiple
> representations, but for archiving purpose, date could be normalize
> to use the same "base time".
>
> Hum, this sounds really like "epoch" and the current time_t. So this
> scheme would simply be an extension of the current scheme... which is
> good engineering. If the "current date" field is missing, simply use
> "epoch".
>
> Alternatively, one could simply keep to number of leap seconds added
> since "epoch", so that if that number differs from the official one,
> one would know that either the algorithm that calculated the date was
> not updated recently or that the date was calculated before the new
> leap second(s) were added.
Sounds pretty complicated. Which is why I reiterate my original
point: Choosing a time representation that doesn't include leap
seconds avoids all of these problems.
Applications that really need to keep track of leap seconds, as
has been pointed out by other posts in this thread, probably do
so using methods that go beyond the ISO C library, which is just
fine. All other applications, though, can simply ignore leap
seconds.
For make, you only need to keep clocks in sync within your LAN; it doesn't
matter whether they're synchronized to a standard timebase, and leap
seconds certainly aren't significant. You generally don't even need
sub-second accuracy in the synchronization -- a daily "rdate" cron job is
often sufficient.
--
Barry Margolin, bar...@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
---
I disagree that they don't follow normal mathematical rules, provided
that you remember that there are multiple different types of time
lapse - perhaps even an indefinite number. For example:
A number of seconds (in astronomical time)
A number of days in civil time
A number of working days in context XXX
Two additions with the same type of lapse then commute, but two
additions with different types may not. All as expected.
The fault with the POSIX model is that it attempts to be all things
to all men. If the basic time were astronomical, and the context
were attached solely to the time lapse objects and display functions,
there would be no inconsistencies (mathematical or otherwise).
I doubt that there is any chance of this being accepted, though.
Regards,
Nick Maclaren,
University of Cambridge Computing Service,
New Museums Site, Pembroke Street, Cambridge CB2 3QG, England.
Email: nm...@cam.ac.uk
Tel.: +44 1223 334761 Fax: +44 1223 334679
Actually, no. Particularly when cross-compiling, and when tracking
down system problems, drifts of a second or so often cause trouble
and ones of less than a second sometimes do. This can be more
serious in system administration scripts. Similarly, a major
discrepancy from 'the outside world' is bad news. My guidelines
for acceptable drifts in seconds are as follows:
Target Worst
Within close-coupled systems on a LAN 0.1 1
Separately administered local systems 1 10
Systems run by other organisations 10 100
Well, who is to decide what is complicated? I failed to see why adding a
single field to the current date representation is complicated. If you
don't need it, don't use it, but at least it is standardized. As you
say, all applications that don't need it can ignore it. I see little
point in changing the standard representation of time and come up with
something that is still incomplete.
Do they? What about adding 1 month to August 31, then subtracting 1 month
from that? I think you'll end up with either August 30 or September 1,
depending on how you normalize September 31, but you won't get back to
August 31.
Arithmetic with days, weeks, and units smaller than days work relatively
well because they're fixed units, but months are a big problem because the
time lapse is a function of the starting time.
--
Barry Margolin, bar...@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
---
The complication isn't in the representation of leap seconds, it's in the
requirement that all conforming implementations must keep track of all leap
seconds that have ever been inserted. For most purposes this information
is unimportant, so forcing it on all implementations seems excessive.
It is obviously impossible for me to judge whether I've missed
your point. Consider though: If it's worth ignoring leap seconds
in order to simplify the calendar, why stop there? My modest proposal:
One minute = 64 seconds
One hour = 64 minutes
One day = 32 hours (or 16; I'm open to persuasion)
One week = 8 days
One month = 4 weeks
One year = 16 (or maybe 8) months
One decade = 8 (16?) years
One century = 128 years
Such a calendar might be slightly awkward for ordinary uses, but
surely the regularity and simplicity outweigh such mundane concerns.
Nowadays everyone cool is a Netizen;
Who cares just when the Sun rises or setzigen?
IMO good reason to *not* provide such operations as part of the
standard library.
> 2000-02-29 + {1y 0m 0d}
> = 2001-02-29, normalized to 2001-03-01
What property of real life date and time does this normalization
proces model? It seems kinda arbitrary to me. Why should 2001-02-29
normalize to 2001-03-01? The desired result may well have been
2001-02-28 (= the last day in February).
--
Anders Munch, ande...@post.tele.dk
Still confused but at a higher level.
If you add say 365*10,000 current days worth of microseconds,
or even 365.2422*10,000, to "now" you arrive at a well-defined
deterministic value that is unlikely to actually be useful for anything.
> (IIRC, doesn't the UTC reckoning of time ignore leap seconds, such
> that the current drift between geological TAI time and UTC is now
> about 32 seconds?)
>
UTC includes leap seconds to keep it approximately in sync
with observed astronomical time (UT) and therefore does drift
from TAI, which is atomic. There is no "geological" time system.
> Most system clocks differ from the international time standard by
> a few seconds or even minutes; do sysadmins update their system
> clocks when a new leap second is decreed? I doubt it.
>
Those who care about exact time probably NTP from a source
which does it for them. But for most business and DP uses,
neither leap-second precision nor sub-minute accuracy is needed.
--
- David.Thompson 1 now at worldnet.att.net