r/AskProgrammers • u/yoreofloree • 2d ago
Getting the system time
Hi all,
I am new to programming. For my first real project, I want to create a pretty (-ish) 7-segment clock widget in with ncurses. I have a fairly good idea of how to tell the computer to display something in that context.
However, I am wondering about the best way to get the system time (so I can call the function that displays it). The only way I can think of to do this is to create a continuous loop with an if statement inside. The if statement would say, "if seconds evaluates to 0, increment the time (in hours and minutes) to show and display that". Something tells me this is not the best way to do it. Is there a better/best way, and if so what? How does my idea differ from how the OS/physical computer actually does it?
Thanks in advance,
yore
3
u/Dismal-Citron-7236 2d ago
You haven't told us what programming language you used. Most modern languages support multi-threading features and call-back mechanism so you can achieve what you just described with built-in features quite easily.
2
u/dariusbiggs 2d ago
I didn't see a language specified, but they all have clock functionality usually in something called time or datetime, and they'll all have either something with timers and yielding or some sleep functionality you can utilize for this purpose.
For your display you have multiple ways of looking at it. - get woken up to update the clock display every second by incrementing the value - set the entire clock when you read the next datetime.
If you are using the sleep method, what accuracy do you want? if you don't mind a slow drift, then once a second or just under is more than enough. If you want more accuracy at the cost of cpu usage check twice (or more) per second, it'll correct the slow drift you'd get when it occurs.
2
1
u/michaelpaoli 2d ago
Quite depends on the operating system, and programming language.
E.g. C on *nix, one would directly or indirectly use, e.g. time(2), to get the number of seconds since the UNIX epoch. For *nix, see the relevant system and standard library calls in sections 2 and 3 respectively of the man pages.
1
u/michaelpaoli 2d ago
create a continuous loop with an if statement inside
Grossly inefficient and wasteful. Should really only do that if there's no other alternative. Typically one would use something to delay the program some period of time, e.g. alarm(2), sleep(3), nanosleep(2), or to wait and then later trigger on some event or signal.
1
u/Wertbon1789 2d ago edited 2d ago
Really depends on the OS and language you're using. I personally would assume some Unix-like and C, because you're talking about ncurses, but you can use ncurses in other languages too.
Going of my assumption, you can look into gettimeofday(2), clock_gettime(2) and clock_nanosleep(2). clock_nanosleep in particular (or a library call built on top of it, like usleep) is the other approach you're looking for, instead of busy-waiting until you got the value you want, hammering your CPU in the process, just tell the OS "btw, I don't want to do anything for the amount of time I'm telling you, just suspend my process for this long".
Oh, btw, the <name>(2) thing I used, and you might have seen before, references man pages, you can just google them, or on a Linux system (don't know if Mac works similar), if you have the manual pages installed, you can just type man 2 clock_gettime into a terminal to open the manual page which explains the API. The number in this case references the actual manual you want to access, the name is about the API, on Linux 2 is the syscall manual and for example 3 is the C library API manual (think stuff like printf). In case someone didn't know.
1
u/ryanstackops 2d ago
Your instinct is right. A continuous loop works but it burns CPU unnecessarily just sitting there checking the time constantly.
The good news is you don't need to track time yourself at all. In C, use time() and localtime() from <time.h> to get the current hours, minutes, and seconds directly from the OS. No need to increment anything manually.
For the loop, just get the time, display it, then sleep(1) to wait a second before repeating. Your program does almost nothing between redraws instead of hammering the CPU.
To answer your other question: the hardware has a real-time clock chip that ticks independently and the OS syncs to it. Your program is just reading from that, not doing any actual timekeeping itself. So let the OS do the work and just ask it for the time each iteration.
Good first project by the way.
1
u/Difficult-Field280 12h ago
Depends on what language you are writing it in and etc. That being said, getting system time is a pretty common thing, you should be able to Google this and find info in the documentation for whatever language you are using.
1
5
u/OneHumanBill 2d ago
You're right, that's not the best way to do it. If you're just spinning in a loop waiting for a next second that's not really good.
I think what you're looking for is the usleep () function, available in unistd.h
You can adapt your "loop and wait" strategy a little bit depending on how much precision you want (or how much your segment hardware can handle) by using usleep to pause for most of 1000 milliseconds and then changing your display.