473,396 Members | 1,608 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

ctime library - is there anything better in c++?

Is the ctime library really that poorly designed, or is it just me
looking to do things the wrong way?

The whole concept of the struct tm seems way too highlevel for my taste
- this is something that I would implement myself if needed.

I have started programming c++ long before I did Visual Basic, and even
before Visual Basic was around. However, one has to give credit, where
credit is due: What's wrong with the (imo really good) VB approach to
store dates as a floating point value with the whole numbers being the
days since day X and the fraction being the part of the day elapsed?
I.e. 0.5 = 12:00 hours, 1/24 = 1 hour and so on?

If I need any more accurate times, I'll use the timer that starts when
the computer is turned on, not the system clock!

Then the tm structs definitions:
http://www.cplusplus.com/reference/c.../ctime/tm.html
All the values are seconds, minutes, hours, days, months *SINCE* some
point in time, starting with 0, but the tm_mday all of a sudden is "day
of the month" (values 1-31). What ever happened to consistency?

Now if I want to do such a simple thing as read a users text input of a
year and a "day of year", and convert it to an ISO date, I
first: have to create & initialize a tm struct with the date tm_year =
userInput, tm_month = 0, tm_mday = 1, then
second: have to convert that into a time_t value, using mktime()
function that also manipulates my input(!) value,
third: add the user entered "day of year" (minus one) to the time_t,
multiplied by 86400 seconds in a day of course, and finally
fourth: convert the time_t back to a tm struct so I am able to output it
for the user

Not to mention that the tm struct should be a class and initialize in
the constructor with the calendar's counting start date, instead of all
random values (or at least, if it isn't done for speed reasons, an
initialize routine should be part of the library - it's a one-liner, but
it's annoying to do it yourself as a user and include a function that
should be part of the library in every single program that needs it).

Then why on earth does the strftime function take a struct tm as an
argument, and not the (much more sensible) time_t format?

In my eyes, the ctime library is really the poorest piece of programming
I have ever seen in an official c standard library. The only reason I'm
forced to use it at the moment is that I do not know how to reliably
calculate leap years, leap seconds and the likes and really do not feel
like creating my own date/time library at all. Not to mention If I did
it, it wouldn't be anywhere near the speed performance that the standard
library probably is.

So - after being done with my rant, can someone point me to a better
solution in C++?

Best Regards,

Lars

PS: What were they thinking???
Nov 20 '08 #1
9 5444
On Nov 20, 5:11 pm, Lars Uffmann <a...@nurfuerspam.dewrote:
Is the ctime library really that poorly designed, or is it just me
looking to do things the wrong way?

The whole concept of the struct tm seems way too highlevel for my taste
- this is something that I would implement myself if needed.

I have started programming c++ long before I did Visual Basic, and even
before Visual Basic was around. However, one has to give credit, where
credit is due: What's wrong with the (imo really good) VB approach to
store dates as a floating point value with the whole numbers being the
days since day X and the fraction being the part of the day elapsed?
I.e. 0.5 = 12:00 hours, 1/24 = 1 hour and so on?

If I need any more accurate times, I'll use the timer that starts when
the computer is turned on, not the system clock!

Then the tm structs definitions:http://www.cplusplus.com/reference/c.../ctime/tm.html
All the values are seconds, minutes, hours, days, months *SINCE* some
point in time, starting with 0, but the tm_mday all of a sudden is "day
of the month" (values 1-31). What ever happened to consistency?

Now if I want to do such a simple thing as read a users text input of a
year and a "day of year", and convert it to an ISO date, I
first: have to create & initialize a tm struct with the date tm_year =
userInput, tm_month = 0, tm_mday = 1, then
second: have to convert that into a time_t value, using mktime()
function that also manipulates my input(!) value,
third: add the user entered "day of year" (minus one) to the time_t,
multiplied by 86400 seconds in a day of course, and finally
fourth: convert the time_t back to a tm struct so I am able to output it
for the user

Not to mention that the tm struct should be a class and initialize in
the constructor with the calendar's counting start date, instead of all
random values (or at least, if it isn't done for speed reasons, an
initialize routine should be part of the library - it's a one-liner, but
it's annoying to do it yourself as a user and include a function that
should be part of the library in every single program that needs it).

Then why on earth does the strftime function take a struct tm as an
argument, and not the (much more sensible) time_t format?

In my eyes, the ctime library is really the poorest piece of programming
I have ever seen in an official c standard library. The only reason I'm
forced to use it at the moment is that I do not know how to reliably
calculate leap years, leap seconds and the likes and really do not feel
like creating my own date/time library at all. Not to mention If I did
it, it wouldn't be anywhere near the speed performance that the standard
library probably is.

So - after being done with my rant, can someone point me to a better
solution in C++?

Best Regards,

Lars

PS: What were they thinking???
Use boost library. It is open source. Download it from
www.boost.org

--
Daya
Nov 20 '08 #2
ma******@gmail.com wrote:
Use boost library. It is open source. Download it from
www.boost.org
oO! That was too obvious :/ Thank you! I already use boost for
threading, so I don't even have to download it.

Thanks for the fast reply!

Lars
Nov 20 '08 #3
Lars Uffmann wrote:
What's wrong with the (imo really good) VB approach to
store dates as a floating point value with the whole numbers being the
days since day X and the fraction being the part of the day elapsed?
Accuracy comes to mind. For example the value 0.1 cannot be
represented accurately with base-2 floating point numbers (for the exact
same reason as 1/3 cannot be represented accurately with base-10 decimal
numbers).

If you add 0.1 to itself 10 times, you won't get 1.0 (you get a value
which is extremely close to it, but not exactly 1.0). That might not be
what one wants.
Nov 20 '08 #4
In article <6o************@mid.dfncis.de>,
Lars Uffmann <ar**@nurfuerspam.dewrote:
>Is the ctime library really that poorly designed, or is it just me
looking to do things the wrong way?

The whole concept of the struct tm seems way too highlevel for my taste
- this is something that I would implement myself if needed.

I have started programming c++ long before I did Visual Basic, and even
before Visual Basic was around. However, one has to give credit, where
credit is due: What's wrong with the (imo really good) VB approach to
store dates as a floating point value with the whole numbers being the
days since day X and the fraction being the part of the day elapsed?
I.e. 0.5 = 12:00 hours, 1/24 = 1 hour and so on?
Sounds poor to me...
>If I need any more accurate times, I'll use the timer that starts when
the computer is turned on, not the system clock!

Then the tm structs definitions:
http://www.cplusplus.com/reference/c.../ctime/tm.html
All the values are seconds, minutes, hours, days, months *SINCE* some
point in time, starting with 0, but the tm_mday all of a sudden is "day
of the month" (values 1-31). What ever happened to consistency?
Euh, ask the peoples that invented the time system. In most cultures
I have been exposed to, a day starts at 00:00:00 as hours, minutes
and seconds (some use 12:00:00 AM but most understand both). Nowhere
that I am aware start their day at 01:01:01.

Inconsistently, most culture start their years on the 01/01 i.e first
day of the first month. Nowhere that I am aware of start their years
on 00/00.

So the C library when creating a human referenceable structure simply
followed accepted human patterns.
>Now if I want to do such a simple thing as read a users text input of a
year and a "day of year", and convert it to an ISO date, I
first: have to create & initialize a tm struct with the date tm_year =
userInput, tm_month = 0, tm_mday = 1, then
second: have to convert that into a time_t value, using mktime()
function that also manipulates my input(!) value,
third: add the user entered "day of year" (minus one) to the time_t,
multiplied by 86400 seconds in a day of course, and finally
fourth: convert the time_t back to a tm struct so I am able to output it
for the user
Sounds convoluted to me. Don't you have strptime?
http://www.opengroup.org/onlinepubs/.../strptime.html

strptime allows you to do things like:
strptime("6 Dec 2001 12:33:45", "%d %b %Y %H:%M:%S", &tm)

Seems fairly usable. That should do what you want.

Yannick
Nov 20 '08 #5
Juha Nieminen wrote:
>What's wrong with the (imo really good) VB approach to
store dates as a floating point value with the whole numbers being the
days since day X and the fraction being the part of the day elapsed?

Accuracy comes to mind. For example the value 0.1 cannot be
represented accurately with base-2 floating point numbers (for the exact
same reason as 1/3 cannot be represented accurately with base-10 decimal
numbers).
Okay, that is a valid point. However, the same point holds true for the
time_t format - just at a higher level of details, with exactly the
examle of 1/3 that you mentioned. :)

Best Regards,

Lars
Nov 20 '08 #6
Yannick Tremblay wrote:
>I.e. 0.5 = 12:00 hours, 1/24 = 1 hour and so on?
Sounds poor to me...
YMMD - it makes for very easy date calculation when you have to handle
lots and lots of date routines (where speed isn't as big an issue as
variety).
>All the values are seconds, minutes, hours, days, months *SINCE* some
point in time, starting with 0, but the tm_mday all of a sudden is "day
of the month" (values 1-31). What ever happened to consistency?

Euh, ask the peoples that invented the time system. In most cultures
I have been exposed to, a day starts at 00:00:00 as hours, minutes
and seconds (some use 12:00:00 AM but most understand both). Nowhere
that I am aware start their day at 01:01:01.
Well - then why is the ctime implementation of struct tm also counting
months starting from zero? And the weekday (tm_wday), day of year
(tm_yday) as well as the year (ok, actually that is being counted from
1970 - also a big limitation of this time format: due to the
unnecessarily high accuracy, you can not express any dates prior to
1902-01-01...
So the C library when creating a human referenceable structure simply
followed accepted human patterns.
Not really ;)
Sounds convoluted to me. Don't you have strptime?
http://www.opengroup.org/onlinepubs/.../strptime.html
No, I was not aware of it, but that was the purpose of my OP - I wanted
to learn about alternatives :) So thanks for that!

Best Regards,

Lars
Nov 20 '08 #7
On Nov 20, 2:12 pm, Juha Nieminen <nos...@thanks.invalidwrote:
Lars Uffmann wrote:
What's wrong with the (imo really good) VB approach to store
dates as a floating point value with the whole numbers being
the days since day X and the fraction being the part of the
day elapsed?
Accuracy comes to mind. For example the value 0.1 cannot be
represented accurately with base-2 floating point numbers (for
the exact same reason as 1/3 cannot be represented accurately
with base-10 decimal numbers).
If you add 0.1 to itself 10 times, you won't get 1.0 (you get
a value which is extremely close to it, but not exactly 1.0).
That might not be what one wants.
Just a nit, but you *might* get 1.0. More accurately, too, you
probably can't add 0.1 to itself, because you can't have a value
0.1, just a value which is extremely close to it. Although the
standard allows base 10 floating pointer arithmetic, I don't
know of a modern implementation that uses anything other than
base 2, 8 or 16. And 0.1 isn't representable in any of those
bases. (And of course, if adding 0.1 ten times does happen to
work, just choose some other value---whatever the
representation, adding 1/N to itself N times will fail to give 1
for some N. Because 1/N isn't representable.)

But the basic objection remains: you can't exactly represent
seconds, and the results of any calculations which should result
in seconds may be off by some very small amount. Which could
cause problems if you want to compare two times. Not to mention
that you're likely to end up with fractions of a second when you
don't want them. All in all, using floating point here is
probably the worst possible solution (but the standard allows
it: time_t may be a typedef to double).

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Nov 21 '08 #8
On Nov 20, 5:04 pm, Lars Uffmann <a...@nurfuerspam.dewrote:
Yannick Tremblay wrote:
I.e. 0.5 = 12:00 hours, 1/24 = 1 hour and so on?
Sounds poor to me...
YMMD - it makes for very easy date calculation when you have
to handle lots and lots of date routines (where speed isn't as
big an issue as variety).
All the values are seconds, minutes, hours, days, months
*SINCE* some point in time, starting with 0, but the
tm_mday all of a sudden is "day of the month" (values
1-31). What ever happened to consistency?
Euh, ask the peoples that invented the time system. In most
cultures I have been exposed to, a day starts at 00:00:00 as
hours, minutes and seconds (some use 12:00:00 AM but most
understand both). Nowhere that I am aware start their day
at 01:01:01.
Well - then why is the ctime implementation of struct tm also
counting months starting from zero? And the weekday (tm_wday),
Because these values are strings; adding numbers to strings
doesn't work very well, but adding a number to the index into a
table of strings does. And in C, indexes start at 0.
day of year (tm_yday) as well as the year (ok, actually that
is being counted from 1970
In time_t. In tm, its from 1900. Format the tm_year field as
%02d, and you get a 2 digit year, exactly as people back in the
1970's (when time.h was designed) would expect it.
- also a big limitation of this time format: due to the
unnecessarily high accuracy, you can not express any dates
prior to 1902-01-01...
Again, it's implementation defined. But most implementations do
use the Unix conventions, or something similar (in particular,
with time_t being a 32 bit integer). And again: this format was
designed mainly for file timestamps; the inventors weren't
worried about files which were modified before 1970, since they
couldn't exist.

For a general purpose library, 32 bits aren't enough, even for a
resolution of seconds. (A 64 bit value representing nanoseconds
is good for over 200,000 years, and representing microseconds,
for well over the expected age of the universe. Which should
cover most needs.)
So the C library when creating a human referenceable
structure simply followed accepted human patterns.
Not really ;)
Very really, within the context
Sounds convoluted to me. Don't you have strptime?
http://www.opengroup.org/onlinepubs/.../strptime.html
No, I was not aware of it, but that was the purpose of my OP -
I wanted to learn about alternatives :) So thanks for that!
Note that it's a Unix standard function, not necessarily
available everywhere.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Nov 21 '08 #9
"Lars Uffmann" wrote:
Is the ctime library really that poorly designed, or is it just me looking
to do things the wrong way?
I haven't followed this thread but the linked article is germane to the
general discussion. It says 28 GIs were killed because of
rounding/truncation/whatever error. It took me till now to get around to
looking for a clip of some kind, I had heard about the problem quite some
time ago.

http://www.ima.umn.edu/~arnold/disasters/patriot.html
Nov 21 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Ernst Murnleitner | last post by:
Hello Readers, I am looking for a replacement of <ctime>. for the functions gmtime mktime One reason is, that these time functions use statically allocated memory but
3
by: Kevin | last post by:
Hello: I am trying to find documentation on using the ctime library as I need to be able to instantiate an object to keep track of the time when a certain event occurs. I also need to be able...
43
by: Steven T. Hatton | last post by:
Now that I have a better grasp of the scope and capabilities of the C++ Standard Library, I understand that products such as Qt actually provide much of the same functionality through their own...
5
by: berkay | last post by:
long num,num1; char *first; char *last; num=ilk.getTime();//gets time first=ctime(&num); cout.flush(); fflush(stdin); 1) cout<<"first:"<<first;
8
by: B Williams | last post by:
I have been searching the internet trying to find the definition for the function time() in the standard library header <ctime>. Can someone help me with this? Thanks in advance.
4
by: Gary Wessle | last post by:
Hi I am not getting current time with this program, what am I doing wrong? #include <ctime> #include <iostream> using namespace std; #define P(x) cout << #x " = " << (x) << "\n";
20
by: Frank-O | last post by:
Hi , Recently I have been commited to the task of "translating" some complex statistical algorithms from Matlab to C++. The goal is to be three times as fast as matlab ( the latest) . I've...
11
by: aisling.cronin | last post by:
Hi I am using ctime to convert the following string 1144412677847 .... Please could some one to double check if they get the same result as me (The Time is Sun Nov 02 09:11:51 2031). It seems...
4
by: Pietro Cerutti | last post by:
Hi group, #include <stdio.h> #include <unistd.h> #include <time.h> int main(void) { time_t t1, t2; char *st1, *st2;
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.