Timestamp function with millisecond precision
I want to be able to print timestamps with milliseconds precision and time_t doesn't provide this. I also want the code to be portable, so operating specific functions are out. ftime seems to be deprecated but there doesn't seem to be a general-purpose alternative to using ftime.
How could this be improved?
#include <stdio.h>
#include <string.h>
#include <systimeb.h>
#include <time.h>
static char* get_timestamp(char* buf) {
struct timeb start;
char append[100];
if (buf) {
ftime(&start);
strftime(buf, 100, "%H:%M:%S", localtime(&start.time));
/* append milliseconds */
sprintf(append, ":%03u", start.millitm);
strcat(buf, append);
}
return buf;
}
int main()
{
char tmp[100];
int countdown = 0;
for (int i = 0; i < 10; i++, countdown = 0) {
printf("%sn", get_timestamp(tmp));
while (countdown++ < 1000000)
;
}
}
c datetime formatting portability
add a comment |
I want to be able to print timestamps with milliseconds precision and time_t doesn't provide this. I also want the code to be portable, so operating specific functions are out. ftime seems to be deprecated but there doesn't seem to be a general-purpose alternative to using ftime.
How could this be improved?
#include <stdio.h>
#include <string.h>
#include <systimeb.h>
#include <time.h>
static char* get_timestamp(char* buf) {
struct timeb start;
char append[100];
if (buf) {
ftime(&start);
strftime(buf, 100, "%H:%M:%S", localtime(&start.time));
/* append milliseconds */
sprintf(append, ":%03u", start.millitm);
strcat(buf, append);
}
return buf;
}
int main()
{
char tmp[100];
int countdown = 0;
for (int i = 0; i < 10; i++, countdown = 0) {
printf("%sn", get_timestamp(tmp));
while (countdown++ < 1000000)
;
}
}
c datetime formatting portability
add a comment |
I want to be able to print timestamps with milliseconds precision and time_t doesn't provide this. I also want the code to be portable, so operating specific functions are out. ftime seems to be deprecated but there doesn't seem to be a general-purpose alternative to using ftime.
How could this be improved?
#include <stdio.h>
#include <string.h>
#include <systimeb.h>
#include <time.h>
static char* get_timestamp(char* buf) {
struct timeb start;
char append[100];
if (buf) {
ftime(&start);
strftime(buf, 100, "%H:%M:%S", localtime(&start.time));
/* append milliseconds */
sprintf(append, ":%03u", start.millitm);
strcat(buf, append);
}
return buf;
}
int main()
{
char tmp[100];
int countdown = 0;
for (int i = 0; i < 10; i++, countdown = 0) {
printf("%sn", get_timestamp(tmp));
while (countdown++ < 1000000)
;
}
}
c datetime formatting portability
I want to be able to print timestamps with milliseconds precision and time_t doesn't provide this. I also want the code to be portable, so operating specific functions are out. ftime seems to be deprecated but there doesn't seem to be a general-purpose alternative to using ftime.
How could this be improved?
#include <stdio.h>
#include <string.h>
#include <systimeb.h>
#include <time.h>
static char* get_timestamp(char* buf) {
struct timeb start;
char append[100];
if (buf) {
ftime(&start);
strftime(buf, 100, "%H:%M:%S", localtime(&start.time));
/* append milliseconds */
sprintf(append, ":%03u", start.millitm);
strcat(buf, append);
}
return buf;
}
int main()
{
char tmp[100];
int countdown = 0;
for (int i = 0; i < 10; i++, countdown = 0) {
printf("%sn", get_timestamp(tmp));
while (countdown++ < 1000000)
;
}
}
c datetime formatting portability
c datetime formatting portability
edited Feb 20 '16 at 16:56
200_success
128k15150412
128k15150412
asked Feb 20 '16 at 15:42
arcomber
89821527
89821527
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
You state that operating specific functions are out, which I assume means that you don't want to use operating system specific system functions. However in this particular case that is actually hindering you from actually solving your task, as POSIX-based systems and Windows-based systems has two different ways of handling this.
Although the ftime is present in various operating system, it has been marked as obsolete as of POSIX.1-2008:
4.2BSD, POSIX.1-2001. POSIX.1-2008 removes the specification of ftime().
This function is obsolete. Don't use it. If the time in seconds
suffices, time(2) can be used; gettimeofday(2) gives microseconds;
clock_gettime(2) gives nanoseconds but is not as widely available.
Further is the gettimeofday() also obsolete as of POSIX.1-2008, leaving only the clock_gettime() alternative, which is not as widely available. Most notably not present in Windows, as indicated in "Porting clock_gettime to windows".
On Windows there are some other options, but seems that most fall back to using QueryPerformanceCounter & co (referred to as QPCs) as indicated in "Acquiring high-resolution time stamps". Some of my search findings also indicate that the QPCs are not be trusted in SMP (Symmetric MultiProcessing environments).
In other words, if you want to do this correctly for use in various operating systems, you do need to make it operating system dependent. If you choose to carry on with your solution using the obsolete ftime() more could surely be said, but here are some comments on your actual code:
Loose theappendvariable – You already have room inbuffor the result, and know how much you've already used. I.e. replace it with something like eithersprintf(&buf[8], ":%03u", start.millitm);orsprintf(buf + 8, ":%03u", start.millitm);1, and you can return without doing thestrcatat the end.
Avoid busy loops – Yourwhileloop is called a busy loop as it does nothing excepting counting. It is usually better to trigger a sleep function or similar, allowing the processor to do other work in between.
Strange reset ofcountdown– Instead of resetting thecountdownin theforloop, it would be clearer code to reset it just before thewhileloop, or even better (if persisting to use the busy loop) to make it into a locally scopedforloop, i.efor (int countdown = 0; countdown < 1000000; countdown++) ;
Decide on one style of bracing – Decide whether you want to have opening braces on the start of the line, or end of preceding line, and stick to it. Mixing like you've done here make your code somewhat harder to read, and when mixing with empty block (aka the busy loop) with missing braces, it is not good.
Some guys advocate a different opening brace style for functions versus other blocks, but I would suggest using the same style for everything making it more consistent.
Addendum: C11 and xtime_get or rather timespec_get
Jerry Coffin refers to a xtime_get() with potential nanoseconds precision (albeit still dependent on operating system precision). This is part of the C++ boost library. It was proposed to be included in C11 (see N1548.pdf, 7.25.7, p 383. This was revised in N1570, 7.27.2.7, into a timespec_get() function. N1570 is the latest draft available, before the standard was defined (and made commercially available). From this I quote:
3 If base is TIME_UTC, the tv_sec member is set to the number of seconds since an implementation defined epoch, truncated to a whole value and the tv_nsec member is set to the integral number of nanoseconds, rounded to the resolution of the system clock.321)
...
321) Although a struct timespec object describes times with nanosecond resolution, the available resolution is system dependent and may even be greater than 1 second.
This does however seem to have made it into C11 (also known as ISO/IEC 9899:2011), according to the table of contents listed here, see section 7.27.2.5. So if your compiler and libraries is compliant to C112, you might use timespec_get() and possibly get a system dependent precision up to nanoseconds (or even greater than 1 second).
1 Thanks to 200_success for pointing out error in code related to buf[8] not being an acceptable target for sprintf()
2 For the gcc family this seems to be gcc ver 4.6 and glibc ver 2.16, or newer
add a comment |
I answered a similar question on Stack Overflow. I wanted a timestamp in a specific format, that could be obtained from a function repeatedly.
My implementation is different than the original posters, for very specific reasons. The goal is thus to create a simple timestamp structure and a function that can create it repeatedly without arguments. I think the function below does that.
A timestamp function should return a timestamp. It should not require the user to have know the necessary length of the char*. Such details should be hidden from the user. If not the user must manage the char* or keep tabs on how users of this function pass char* variables to it.
The function clock_gettime is the ideal POSIX function, but it is not universally supported. Avoid the other deprecated functions such as gettimeofday. As someone said earlier, ftime is not the function to use, and neither is gettimeofday.
I think the code below is mostly portable. I think the trick with timestamp functions is not so much portability, but avoiding the unnecessary usage of dynamically allocated memory. I think this is important because for embedded environments several rules preclude the usage of such C constructs.
Also, strcat requires an implicit search for ''. For the original solution strcat should cause no problems, but I generally avoid the use of strcat because of it's own problems.
My function returns a timestamp with a timestring (not ambiguous) and not a char* (ambiguous) - essentially this timestamp function is at a suitable code 'level', the reader knows what he is being presented with. I am not inter-mixing low and medium level code. I have a medium level type (timestamp) and a medium level function (getTimestamp) and it requires no arguments.
It would be 'nice' if clock_gettime had macro options for something like RAW_GPS_TIME, J2000_TAI_TIME, J2000_UTC_TIME and so forth, providing that such time sources were available, but this is another discussion.
struct Timestamp {
time_t seconds;
long milliseconds;
char timestring[32];
};
struct Timestamp getTimestamp()
{
char timebuffer[32] = {0};
struct timeval tv = {0};
struct tm *tmval = NULL;
struct tm gmtval = {0};
struct timespec curtime = {0};
struct Timestamp timestamp;
int i = 0;
// Get current time
clock_gettime(CLOCK_REALTIME, &curtime);
// Set the fields
timestamp.seconds = curtime.tv_sec;
timestamp.milliseconds = round(curtime.tv_nsec/1.0e6);
if((tmval = gmtime_r(×tamp.seconds, &gmtval)) != NULL)
{
// Build the first part of the time
strftime(timebuffer, sizeof timebuffer, "%Y-%m-%d %H:%M:%S", &gmtval);
// Add the milliseconds part and build the time string
snprintf(timestamp.timestring, sizeof timestamp.timestring, "%s.%03ld", timebuffer, timestamp.milliseconds);
}
return timestamp;
}
int main()
{
int i = 0;
struct timespec sleeptime = {0, 5000000L};
struct Timestamp timestamp;
for (i=0; i < 20; i++)
{
timestamp = getTimestamp();
printf("Time is: %s n", timestamp.timestring);
nanosleep(&sleeptime, NULL);
}
return 0;
}
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f120628%2ftimestamp-function-with-millisecond-precision%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You state that operating specific functions are out, which I assume means that you don't want to use operating system specific system functions. However in this particular case that is actually hindering you from actually solving your task, as POSIX-based systems and Windows-based systems has two different ways of handling this.
Although the ftime is present in various operating system, it has been marked as obsolete as of POSIX.1-2008:
4.2BSD, POSIX.1-2001. POSIX.1-2008 removes the specification of ftime().
This function is obsolete. Don't use it. If the time in seconds
suffices, time(2) can be used; gettimeofday(2) gives microseconds;
clock_gettime(2) gives nanoseconds but is not as widely available.
Further is the gettimeofday() also obsolete as of POSIX.1-2008, leaving only the clock_gettime() alternative, which is not as widely available. Most notably not present in Windows, as indicated in "Porting clock_gettime to windows".
On Windows there are some other options, but seems that most fall back to using QueryPerformanceCounter & co (referred to as QPCs) as indicated in "Acquiring high-resolution time stamps". Some of my search findings also indicate that the QPCs are not be trusted in SMP (Symmetric MultiProcessing environments).
In other words, if you want to do this correctly for use in various operating systems, you do need to make it operating system dependent. If you choose to carry on with your solution using the obsolete ftime() more could surely be said, but here are some comments on your actual code:
Loose theappendvariable – You already have room inbuffor the result, and know how much you've already used. I.e. replace it with something like eithersprintf(&buf[8], ":%03u", start.millitm);orsprintf(buf + 8, ":%03u", start.millitm);1, and you can return without doing thestrcatat the end.
Avoid busy loops – Yourwhileloop is called a busy loop as it does nothing excepting counting. It is usually better to trigger a sleep function or similar, allowing the processor to do other work in between.
Strange reset ofcountdown– Instead of resetting thecountdownin theforloop, it would be clearer code to reset it just before thewhileloop, or even better (if persisting to use the busy loop) to make it into a locally scopedforloop, i.efor (int countdown = 0; countdown < 1000000; countdown++) ;
Decide on one style of bracing – Decide whether you want to have opening braces on the start of the line, or end of preceding line, and stick to it. Mixing like you've done here make your code somewhat harder to read, and when mixing with empty block (aka the busy loop) with missing braces, it is not good.
Some guys advocate a different opening brace style for functions versus other blocks, but I would suggest using the same style for everything making it more consistent.
Addendum: C11 and xtime_get or rather timespec_get
Jerry Coffin refers to a xtime_get() with potential nanoseconds precision (albeit still dependent on operating system precision). This is part of the C++ boost library. It was proposed to be included in C11 (see N1548.pdf, 7.25.7, p 383. This was revised in N1570, 7.27.2.7, into a timespec_get() function. N1570 is the latest draft available, before the standard was defined (and made commercially available). From this I quote:
3 If base is TIME_UTC, the tv_sec member is set to the number of seconds since an implementation defined epoch, truncated to a whole value and the tv_nsec member is set to the integral number of nanoseconds, rounded to the resolution of the system clock.321)
...
321) Although a struct timespec object describes times with nanosecond resolution, the available resolution is system dependent and may even be greater than 1 second.
This does however seem to have made it into C11 (also known as ISO/IEC 9899:2011), according to the table of contents listed here, see section 7.27.2.5. So if your compiler and libraries is compliant to C112, you might use timespec_get() and possibly get a system dependent precision up to nanoseconds (or even greater than 1 second).
1 Thanks to 200_success for pointing out error in code related to buf[8] not being an acceptable target for sprintf()
2 For the gcc family this seems to be gcc ver 4.6 and glibc ver 2.16, or newer
add a comment |
You state that operating specific functions are out, which I assume means that you don't want to use operating system specific system functions. However in this particular case that is actually hindering you from actually solving your task, as POSIX-based systems and Windows-based systems has two different ways of handling this.
Although the ftime is present in various operating system, it has been marked as obsolete as of POSIX.1-2008:
4.2BSD, POSIX.1-2001. POSIX.1-2008 removes the specification of ftime().
This function is obsolete. Don't use it. If the time in seconds
suffices, time(2) can be used; gettimeofday(2) gives microseconds;
clock_gettime(2) gives nanoseconds but is not as widely available.
Further is the gettimeofday() also obsolete as of POSIX.1-2008, leaving only the clock_gettime() alternative, which is not as widely available. Most notably not present in Windows, as indicated in "Porting clock_gettime to windows".
On Windows there are some other options, but seems that most fall back to using QueryPerformanceCounter & co (referred to as QPCs) as indicated in "Acquiring high-resolution time stamps". Some of my search findings also indicate that the QPCs are not be trusted in SMP (Symmetric MultiProcessing environments).
In other words, if you want to do this correctly for use in various operating systems, you do need to make it operating system dependent. If you choose to carry on with your solution using the obsolete ftime() more could surely be said, but here are some comments on your actual code:
Loose theappendvariable – You already have room inbuffor the result, and know how much you've already used. I.e. replace it with something like eithersprintf(&buf[8], ":%03u", start.millitm);orsprintf(buf + 8, ":%03u", start.millitm);1, and you can return without doing thestrcatat the end.
Avoid busy loops – Yourwhileloop is called a busy loop as it does nothing excepting counting. It is usually better to trigger a sleep function or similar, allowing the processor to do other work in between.
Strange reset ofcountdown– Instead of resetting thecountdownin theforloop, it would be clearer code to reset it just before thewhileloop, or even better (if persisting to use the busy loop) to make it into a locally scopedforloop, i.efor (int countdown = 0; countdown < 1000000; countdown++) ;
Decide on one style of bracing – Decide whether you want to have opening braces on the start of the line, or end of preceding line, and stick to it. Mixing like you've done here make your code somewhat harder to read, and when mixing with empty block (aka the busy loop) with missing braces, it is not good.
Some guys advocate a different opening brace style for functions versus other blocks, but I would suggest using the same style for everything making it more consistent.
Addendum: C11 and xtime_get or rather timespec_get
Jerry Coffin refers to a xtime_get() with potential nanoseconds precision (albeit still dependent on operating system precision). This is part of the C++ boost library. It was proposed to be included in C11 (see N1548.pdf, 7.25.7, p 383. This was revised in N1570, 7.27.2.7, into a timespec_get() function. N1570 is the latest draft available, before the standard was defined (and made commercially available). From this I quote:
3 If base is TIME_UTC, the tv_sec member is set to the number of seconds since an implementation defined epoch, truncated to a whole value and the tv_nsec member is set to the integral number of nanoseconds, rounded to the resolution of the system clock.321)
...
321) Although a struct timespec object describes times with nanosecond resolution, the available resolution is system dependent and may even be greater than 1 second.
This does however seem to have made it into C11 (also known as ISO/IEC 9899:2011), according to the table of contents listed here, see section 7.27.2.5. So if your compiler and libraries is compliant to C112, you might use timespec_get() and possibly get a system dependent precision up to nanoseconds (or even greater than 1 second).
1 Thanks to 200_success for pointing out error in code related to buf[8] not being an acceptable target for sprintf()
2 For the gcc family this seems to be gcc ver 4.6 and glibc ver 2.16, or newer
add a comment |
You state that operating specific functions are out, which I assume means that you don't want to use operating system specific system functions. However in this particular case that is actually hindering you from actually solving your task, as POSIX-based systems and Windows-based systems has two different ways of handling this.
Although the ftime is present in various operating system, it has been marked as obsolete as of POSIX.1-2008:
4.2BSD, POSIX.1-2001. POSIX.1-2008 removes the specification of ftime().
This function is obsolete. Don't use it. If the time in seconds
suffices, time(2) can be used; gettimeofday(2) gives microseconds;
clock_gettime(2) gives nanoseconds but is not as widely available.
Further is the gettimeofday() also obsolete as of POSIX.1-2008, leaving only the clock_gettime() alternative, which is not as widely available. Most notably not present in Windows, as indicated in "Porting clock_gettime to windows".
On Windows there are some other options, but seems that most fall back to using QueryPerformanceCounter & co (referred to as QPCs) as indicated in "Acquiring high-resolution time stamps". Some of my search findings also indicate that the QPCs are not be trusted in SMP (Symmetric MultiProcessing environments).
In other words, if you want to do this correctly for use in various operating systems, you do need to make it operating system dependent. If you choose to carry on with your solution using the obsolete ftime() more could surely be said, but here are some comments on your actual code:
Loose theappendvariable – You already have room inbuffor the result, and know how much you've already used. I.e. replace it with something like eithersprintf(&buf[8], ":%03u", start.millitm);orsprintf(buf + 8, ":%03u", start.millitm);1, and you can return without doing thestrcatat the end.
Avoid busy loops – Yourwhileloop is called a busy loop as it does nothing excepting counting. It is usually better to trigger a sleep function or similar, allowing the processor to do other work in between.
Strange reset ofcountdown– Instead of resetting thecountdownin theforloop, it would be clearer code to reset it just before thewhileloop, or even better (if persisting to use the busy loop) to make it into a locally scopedforloop, i.efor (int countdown = 0; countdown < 1000000; countdown++) ;
Decide on one style of bracing – Decide whether you want to have opening braces on the start of the line, or end of preceding line, and stick to it. Mixing like you've done here make your code somewhat harder to read, and when mixing with empty block (aka the busy loop) with missing braces, it is not good.
Some guys advocate a different opening brace style for functions versus other blocks, but I would suggest using the same style for everything making it more consistent.
Addendum: C11 and xtime_get or rather timespec_get
Jerry Coffin refers to a xtime_get() with potential nanoseconds precision (albeit still dependent on operating system precision). This is part of the C++ boost library. It was proposed to be included in C11 (see N1548.pdf, 7.25.7, p 383. This was revised in N1570, 7.27.2.7, into a timespec_get() function. N1570 is the latest draft available, before the standard was defined (and made commercially available). From this I quote:
3 If base is TIME_UTC, the tv_sec member is set to the number of seconds since an implementation defined epoch, truncated to a whole value and the tv_nsec member is set to the integral number of nanoseconds, rounded to the resolution of the system clock.321)
...
321) Although a struct timespec object describes times with nanosecond resolution, the available resolution is system dependent and may even be greater than 1 second.
This does however seem to have made it into C11 (also known as ISO/IEC 9899:2011), according to the table of contents listed here, see section 7.27.2.5. So if your compiler and libraries is compliant to C112, you might use timespec_get() and possibly get a system dependent precision up to nanoseconds (or even greater than 1 second).
1 Thanks to 200_success for pointing out error in code related to buf[8] not being an acceptable target for sprintf()
2 For the gcc family this seems to be gcc ver 4.6 and glibc ver 2.16, or newer
You state that operating specific functions are out, which I assume means that you don't want to use operating system specific system functions. However in this particular case that is actually hindering you from actually solving your task, as POSIX-based systems and Windows-based systems has two different ways of handling this.
Although the ftime is present in various operating system, it has been marked as obsolete as of POSIX.1-2008:
4.2BSD, POSIX.1-2001. POSIX.1-2008 removes the specification of ftime().
This function is obsolete. Don't use it. If the time in seconds
suffices, time(2) can be used; gettimeofday(2) gives microseconds;
clock_gettime(2) gives nanoseconds but is not as widely available.
Further is the gettimeofday() also obsolete as of POSIX.1-2008, leaving only the clock_gettime() alternative, which is not as widely available. Most notably not present in Windows, as indicated in "Porting clock_gettime to windows".
On Windows there are some other options, but seems that most fall back to using QueryPerformanceCounter & co (referred to as QPCs) as indicated in "Acquiring high-resolution time stamps". Some of my search findings also indicate that the QPCs are not be trusted in SMP (Symmetric MultiProcessing environments).
In other words, if you want to do this correctly for use in various operating systems, you do need to make it operating system dependent. If you choose to carry on with your solution using the obsolete ftime() more could surely be said, but here are some comments on your actual code:
Loose theappendvariable – You already have room inbuffor the result, and know how much you've already used. I.e. replace it with something like eithersprintf(&buf[8], ":%03u", start.millitm);orsprintf(buf + 8, ":%03u", start.millitm);1, and you can return without doing thestrcatat the end.
Avoid busy loops – Yourwhileloop is called a busy loop as it does nothing excepting counting. It is usually better to trigger a sleep function or similar, allowing the processor to do other work in between.
Strange reset ofcountdown– Instead of resetting thecountdownin theforloop, it would be clearer code to reset it just before thewhileloop, or even better (if persisting to use the busy loop) to make it into a locally scopedforloop, i.efor (int countdown = 0; countdown < 1000000; countdown++) ;
Decide on one style of bracing – Decide whether you want to have opening braces on the start of the line, or end of preceding line, and stick to it. Mixing like you've done here make your code somewhat harder to read, and when mixing with empty block (aka the busy loop) with missing braces, it is not good.
Some guys advocate a different opening brace style for functions versus other blocks, but I would suggest using the same style for everything making it more consistent.
Addendum: C11 and xtime_get or rather timespec_get
Jerry Coffin refers to a xtime_get() with potential nanoseconds precision (albeit still dependent on operating system precision). This is part of the C++ boost library. It was proposed to be included in C11 (see N1548.pdf, 7.25.7, p 383. This was revised in N1570, 7.27.2.7, into a timespec_get() function. N1570 is the latest draft available, before the standard was defined (and made commercially available). From this I quote:
3 If base is TIME_UTC, the tv_sec member is set to the number of seconds since an implementation defined epoch, truncated to a whole value and the tv_nsec member is set to the integral number of nanoseconds, rounded to the resolution of the system clock.321)
...
321) Although a struct timespec object describes times with nanosecond resolution, the available resolution is system dependent and may even be greater than 1 second.
This does however seem to have made it into C11 (also known as ISO/IEC 9899:2011), according to the table of contents listed here, see section 7.27.2.5. So if your compiler and libraries is compliant to C112, you might use timespec_get() and possibly get a system dependent precision up to nanoseconds (or even greater than 1 second).
1 Thanks to 200_success for pointing out error in code related to buf[8] not being an acceptable target for sprintf()
2 For the gcc family this seems to be gcc ver 4.6 and glibc ver 2.16, or newer
edited May 23 '17 at 12:40
Community♦
1
1
answered Feb 20 '16 at 16:48
holroy
10.8k11752
10.8k11752
add a comment |
add a comment |
I answered a similar question on Stack Overflow. I wanted a timestamp in a specific format, that could be obtained from a function repeatedly.
My implementation is different than the original posters, for very specific reasons. The goal is thus to create a simple timestamp structure and a function that can create it repeatedly without arguments. I think the function below does that.
A timestamp function should return a timestamp. It should not require the user to have know the necessary length of the char*. Such details should be hidden from the user. If not the user must manage the char* or keep tabs on how users of this function pass char* variables to it.
The function clock_gettime is the ideal POSIX function, but it is not universally supported. Avoid the other deprecated functions such as gettimeofday. As someone said earlier, ftime is not the function to use, and neither is gettimeofday.
I think the code below is mostly portable. I think the trick with timestamp functions is not so much portability, but avoiding the unnecessary usage of dynamically allocated memory. I think this is important because for embedded environments several rules preclude the usage of such C constructs.
Also, strcat requires an implicit search for ''. For the original solution strcat should cause no problems, but I generally avoid the use of strcat because of it's own problems.
My function returns a timestamp with a timestring (not ambiguous) and not a char* (ambiguous) - essentially this timestamp function is at a suitable code 'level', the reader knows what he is being presented with. I am not inter-mixing low and medium level code. I have a medium level type (timestamp) and a medium level function (getTimestamp) and it requires no arguments.
It would be 'nice' if clock_gettime had macro options for something like RAW_GPS_TIME, J2000_TAI_TIME, J2000_UTC_TIME and so forth, providing that such time sources were available, but this is another discussion.
struct Timestamp {
time_t seconds;
long milliseconds;
char timestring[32];
};
struct Timestamp getTimestamp()
{
char timebuffer[32] = {0};
struct timeval tv = {0};
struct tm *tmval = NULL;
struct tm gmtval = {0};
struct timespec curtime = {0};
struct Timestamp timestamp;
int i = 0;
// Get current time
clock_gettime(CLOCK_REALTIME, &curtime);
// Set the fields
timestamp.seconds = curtime.tv_sec;
timestamp.milliseconds = round(curtime.tv_nsec/1.0e6);
if((tmval = gmtime_r(×tamp.seconds, &gmtval)) != NULL)
{
// Build the first part of the time
strftime(timebuffer, sizeof timebuffer, "%Y-%m-%d %H:%M:%S", &gmtval);
// Add the milliseconds part and build the time string
snprintf(timestamp.timestring, sizeof timestamp.timestring, "%s.%03ld", timebuffer, timestamp.milliseconds);
}
return timestamp;
}
int main()
{
int i = 0;
struct timespec sleeptime = {0, 5000000L};
struct Timestamp timestamp;
for (i=0; i < 20; i++)
{
timestamp = getTimestamp();
printf("Time is: %s n", timestamp.timestring);
nanosleep(&sleeptime, NULL);
}
return 0;
}
add a comment |
I answered a similar question on Stack Overflow. I wanted a timestamp in a specific format, that could be obtained from a function repeatedly.
My implementation is different than the original posters, for very specific reasons. The goal is thus to create a simple timestamp structure and a function that can create it repeatedly without arguments. I think the function below does that.
A timestamp function should return a timestamp. It should not require the user to have know the necessary length of the char*. Such details should be hidden from the user. If not the user must manage the char* or keep tabs on how users of this function pass char* variables to it.
The function clock_gettime is the ideal POSIX function, but it is not universally supported. Avoid the other deprecated functions such as gettimeofday. As someone said earlier, ftime is not the function to use, and neither is gettimeofday.
I think the code below is mostly portable. I think the trick with timestamp functions is not so much portability, but avoiding the unnecessary usage of dynamically allocated memory. I think this is important because for embedded environments several rules preclude the usage of such C constructs.
Also, strcat requires an implicit search for ''. For the original solution strcat should cause no problems, but I generally avoid the use of strcat because of it's own problems.
My function returns a timestamp with a timestring (not ambiguous) and not a char* (ambiguous) - essentially this timestamp function is at a suitable code 'level', the reader knows what he is being presented with. I am not inter-mixing low and medium level code. I have a medium level type (timestamp) and a medium level function (getTimestamp) and it requires no arguments.
It would be 'nice' if clock_gettime had macro options for something like RAW_GPS_TIME, J2000_TAI_TIME, J2000_UTC_TIME and so forth, providing that such time sources were available, but this is another discussion.
struct Timestamp {
time_t seconds;
long milliseconds;
char timestring[32];
};
struct Timestamp getTimestamp()
{
char timebuffer[32] = {0};
struct timeval tv = {0};
struct tm *tmval = NULL;
struct tm gmtval = {0};
struct timespec curtime = {0};
struct Timestamp timestamp;
int i = 0;
// Get current time
clock_gettime(CLOCK_REALTIME, &curtime);
// Set the fields
timestamp.seconds = curtime.tv_sec;
timestamp.milliseconds = round(curtime.tv_nsec/1.0e6);
if((tmval = gmtime_r(×tamp.seconds, &gmtval)) != NULL)
{
// Build the first part of the time
strftime(timebuffer, sizeof timebuffer, "%Y-%m-%d %H:%M:%S", &gmtval);
// Add the milliseconds part and build the time string
snprintf(timestamp.timestring, sizeof timestamp.timestring, "%s.%03ld", timebuffer, timestamp.milliseconds);
}
return timestamp;
}
int main()
{
int i = 0;
struct timespec sleeptime = {0, 5000000L};
struct Timestamp timestamp;
for (i=0; i < 20; i++)
{
timestamp = getTimestamp();
printf("Time is: %s n", timestamp.timestring);
nanosleep(&sleeptime, NULL);
}
return 0;
}
add a comment |
I answered a similar question on Stack Overflow. I wanted a timestamp in a specific format, that could be obtained from a function repeatedly.
My implementation is different than the original posters, for very specific reasons. The goal is thus to create a simple timestamp structure and a function that can create it repeatedly without arguments. I think the function below does that.
A timestamp function should return a timestamp. It should not require the user to have know the necessary length of the char*. Such details should be hidden from the user. If not the user must manage the char* or keep tabs on how users of this function pass char* variables to it.
The function clock_gettime is the ideal POSIX function, but it is not universally supported. Avoid the other deprecated functions such as gettimeofday. As someone said earlier, ftime is not the function to use, and neither is gettimeofday.
I think the code below is mostly portable. I think the trick with timestamp functions is not so much portability, but avoiding the unnecessary usage of dynamically allocated memory. I think this is important because for embedded environments several rules preclude the usage of such C constructs.
Also, strcat requires an implicit search for ''. For the original solution strcat should cause no problems, but I generally avoid the use of strcat because of it's own problems.
My function returns a timestamp with a timestring (not ambiguous) and not a char* (ambiguous) - essentially this timestamp function is at a suitable code 'level', the reader knows what he is being presented with. I am not inter-mixing low and medium level code. I have a medium level type (timestamp) and a medium level function (getTimestamp) and it requires no arguments.
It would be 'nice' if clock_gettime had macro options for something like RAW_GPS_TIME, J2000_TAI_TIME, J2000_UTC_TIME and so forth, providing that such time sources were available, but this is another discussion.
struct Timestamp {
time_t seconds;
long milliseconds;
char timestring[32];
};
struct Timestamp getTimestamp()
{
char timebuffer[32] = {0};
struct timeval tv = {0};
struct tm *tmval = NULL;
struct tm gmtval = {0};
struct timespec curtime = {0};
struct Timestamp timestamp;
int i = 0;
// Get current time
clock_gettime(CLOCK_REALTIME, &curtime);
// Set the fields
timestamp.seconds = curtime.tv_sec;
timestamp.milliseconds = round(curtime.tv_nsec/1.0e6);
if((tmval = gmtime_r(×tamp.seconds, &gmtval)) != NULL)
{
// Build the first part of the time
strftime(timebuffer, sizeof timebuffer, "%Y-%m-%d %H:%M:%S", &gmtval);
// Add the milliseconds part and build the time string
snprintf(timestamp.timestring, sizeof timestamp.timestring, "%s.%03ld", timebuffer, timestamp.milliseconds);
}
return timestamp;
}
int main()
{
int i = 0;
struct timespec sleeptime = {0, 5000000L};
struct Timestamp timestamp;
for (i=0; i < 20; i++)
{
timestamp = getTimestamp();
printf("Time is: %s n", timestamp.timestring);
nanosleep(&sleeptime, NULL);
}
return 0;
}
I answered a similar question on Stack Overflow. I wanted a timestamp in a specific format, that could be obtained from a function repeatedly.
My implementation is different than the original posters, for very specific reasons. The goal is thus to create a simple timestamp structure and a function that can create it repeatedly without arguments. I think the function below does that.
A timestamp function should return a timestamp. It should not require the user to have know the necessary length of the char*. Such details should be hidden from the user. If not the user must manage the char* or keep tabs on how users of this function pass char* variables to it.
The function clock_gettime is the ideal POSIX function, but it is not universally supported. Avoid the other deprecated functions such as gettimeofday. As someone said earlier, ftime is not the function to use, and neither is gettimeofday.
I think the code below is mostly portable. I think the trick with timestamp functions is not so much portability, but avoiding the unnecessary usage of dynamically allocated memory. I think this is important because for embedded environments several rules preclude the usage of such C constructs.
Also, strcat requires an implicit search for ''. For the original solution strcat should cause no problems, but I generally avoid the use of strcat because of it's own problems.
My function returns a timestamp with a timestring (not ambiguous) and not a char* (ambiguous) - essentially this timestamp function is at a suitable code 'level', the reader knows what he is being presented with. I am not inter-mixing low and medium level code. I have a medium level type (timestamp) and a medium level function (getTimestamp) and it requires no arguments.
It would be 'nice' if clock_gettime had macro options for something like RAW_GPS_TIME, J2000_TAI_TIME, J2000_UTC_TIME and so forth, providing that such time sources were available, but this is another discussion.
struct Timestamp {
time_t seconds;
long milliseconds;
char timestring[32];
};
struct Timestamp getTimestamp()
{
char timebuffer[32] = {0};
struct timeval tv = {0};
struct tm *tmval = NULL;
struct tm gmtval = {0};
struct timespec curtime = {0};
struct Timestamp timestamp;
int i = 0;
// Get current time
clock_gettime(CLOCK_REALTIME, &curtime);
// Set the fields
timestamp.seconds = curtime.tv_sec;
timestamp.milliseconds = round(curtime.tv_nsec/1.0e6);
if((tmval = gmtime_r(×tamp.seconds, &gmtval)) != NULL)
{
// Build the first part of the time
strftime(timebuffer, sizeof timebuffer, "%Y-%m-%d %H:%M:%S", &gmtval);
// Add the milliseconds part and build the time string
snprintf(timestamp.timestring, sizeof timestamp.timestring, "%s.%03ld", timebuffer, timestamp.milliseconds);
}
return timestamp;
}
int main()
{
int i = 0;
struct timespec sleeptime = {0, 5000000L};
struct Timestamp timestamp;
for (i=0; i < 20; i++)
{
timestamp = getTimestamp();
printf("Time is: %s n", timestamp.timestring);
nanosleep(&sleeptime, NULL);
}
return 0;
}
edited Dec 19 '16 at 5:13
Jamal♦
30.2k11116226
30.2k11116226
answered Dec 17 '16 at 9:28
Xofo
1091
1091
add a comment |
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f120628%2ftimestamp-function-with-millisecond-precision%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown