Getting the time/date

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
crxgames

Getting the time/date

Post by crxgames »

I cannot find a single piece of code on how to do this, nor an article.
How do I get the time/date?
Also, how would I get something like the unix epoch?
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:Getting the time/date

Post by Brendan »

Hi,
crxgames wrote:I cannot find a single piece of code on how to do this, nor an article.
How do I get the time/date?
Download this file:
http://www.contactor.se/~daniel/links/Pctim003.txt

The part you're after is in section 7.35.7, section 7.35.8 and the example source code in section 7.35.8.
crxgames wrote:IAlso, how would I get something like the unix epoch?
You need to calculate it: seconds + minutes*60 + hours*360 + days*360*24, etc

To do this properly you have to make sure you get your leap years right - February might have an extra day, the length of a year depends on which year, etc.

The other problem is that you won't know if the RTC is set to local time or UTC/GMT. It should always be set to UTC - if multiple OS's are installed there's no way for one OS to know if the other OS has made daylight savings changes or not if local time is used. Unfortunately Microsoft are too stupid - if you install 2 different Microsoft OS's they'll both add or subtract an hour to the RTC when daylight savings starts or ends, which messes up the time.

As far as I'm concerned MS OS's are buggy, so my OS expects the RTC to be set to UTC/GMT. Linux tries to work with either but UTC/GMT is strongly recommended (Linux's time will be messed up by MS's OS's too).

Generally the OS needs code to convert UTC to local time and local time to UTC, plus code to convert calendar time (second, minute, hour, day, month, year) into "seconds since 1970" and back.

Timestamps should be in UTC/GMT too, otherwise things get messed up when your sharing files between different time zones.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Getting the time/date

Post by Candy »

Brendan wrote: You need to calculate it: seconds + minutes*60 + hours*360 + days*360*24, etc

To do this properly you have to make sure you get your leap years right - February might have an extra day, the length of a year depends on which year, etc.
Unix time considers each 4 years to have a leap day. As far as I know, that's enough within the 32-bit timespan to never overflow badly. If you are doing 64-bit, know that each century doesn't have a leap year (years 100,200,300 etc.), but every 4th century does have one. So:

4,8,12...92,96,104,108...196,204,208...296,304,308..396,400,404,408...492,496,504 etc.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Getting the time/date

Post by Solar »

Brendan wrote:
Unfortunately Microsoft are too stupid - if you install 2 different Microsoft OS's they'll both add or subtract an hour to the RTC when daylight savings starts or ends, which messes up the time.
Note you can disable the DST adjustions to the RTC in Windows, but - AFAIK - not set it to use a UTC RTC. Which, when you're multiple-booting, means you're more or less stuck with setting RTC to local time (/etc/rc.conf...) and making sure only one OS makes the DST adjustments.

@ Candy:

> Unix time considers each 4 years to have a leap day.

Are you sure about that? They really leave such a gross miscalculation in there?

Edit: Holy Cow! I can't believe my eyes! It's true!
Every good solution is obvious once you've found it.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:Getting the time/date

Post by Brendan »

Hi,
Candy wrote: Unix time considers each 4 years to have a leap day. As far as I know, that's enough within the 32-bit timespan to never overflow badly. If you are doing 64-bit, know that each century doesn't have a leap year (years 100,200,300 etc.), but every 4th century does have one. So:

4,8,12...92,96,104,108...196,204,208...296,304,308..396,400,404,408...492,496,504 etc.
You're right of course (my OS's have done this for the last 4 years). Quite frankly I'm surprised Unix time is so crappy, although seconds since 1970 as a signed 32 bit value overflows in the year 2038 which should give some clue as to how "good" Unix is (or rather how bad it was - I think they've fixed it for most things now)...

I use mS since 2000 as a signed 64 bit number (negative numbers represent time before 2000) - much better accuracy and it's good for millions of years in both directions. I read the RTC during boot and initialize the system timer tick with it - with my last OS you could convert the time/date of your birth into 64 bit format and subtract the OS's system timer tick to find out exactly how many mS old you are. I still haven't ported this to my current OS yet though..

The only problem here is for times/dates before leap year corrections were made to the Gregorian calander (which occured at different times in different countries) and the dodgy calendars that existed well before that. My code just uses todays calendar for all dates (including those of a million years ago), which makes my code less and less accurate the further back you go (everything after the leap year correction is accurate though). I also don't bother with leap seconds - the computer's PIT isn't accurate enough anyway.

If anyone's interested there's a great reference for this sort of thing at: http://www.exit109.com/~ghealton/y2k/yrexamples.html


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Chris Giese

Re:Getting the time/date

Post by Chris Giese »

How to read the real-time clock (RTC) in BCD and binary modes, Gregorian calendar, leap-year calculations, Julian Day Number, yadda, yadda, yadda:

http://my.execpc.com/~geezer/temp/time.c
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Getting the time/date

Post by Solar »

...and if you want to get a real headache about GMT, UTC, TAI, the Roman / Julian / Gregorian calendar, leap seconds, time zone offsets of +00:19:32:1300 (Dutch, 1909-05-01 through 1937-06-30), and other niceties of dates, I recently found this website:

http://www.exit109.com/~ghealton/y2k/yrexamples.html
Every good solution is obvious once you've found it.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Getting the time/date

Post by Candy »

Solar wrote: ...and if you want to get a real headache about GMT, UTC, TAI, the Roman / Julian / Gregorian calendar, leap seconds, time zone offsets of +00:19:32:1300 (Dutch, 1909-05-01 through 1937-06-30), and other niceties of dates, I recently found this website:
So my grandmother was 19 minutes older than I thought she was? Damn... (born in holland in 1929 :))

Never knew our country did something THAT weird. Esp. the 13/100s of a second.
srg_13

Re:Getting the time/date

Post by srg_13 »

Chris Giese wrote: How to read the real-time clock (RTC) in BCD and binary modes, Gregorian calendar, leap-year calculations, Julian Day Number, yadda, yadda, yadda:

http://my.execpc.com/~geezer/temp/time.c
Can you put a link to threads.c?

Or does anyone just have the

Code: Select all

int sleep_on(wait_queue_t *queue, unsigned *timeout);
void wake_up(wait_queue_t *queue);
commands?

Thanks,

Stephen
User avatar
bubach
Member
Member
Posts: 1223
Joined: Sat Oct 23, 2004 11:00 pm
Location: Sweden
Contact:

Re:Getting the time/date

Post by bubach »

Code: Select all

int sleep_on(wait_queue_t *queue, unsigned *timeout)
{
   task_t *prev;

/* mark thread blocked */
   g_curr_task->status = TS_BLOCKED;
/* splice into wait queue at queue->tail */
   prev = queue->tail;
   queue->tail = g_curr_task;
   if(prev == NULL)
   {
      queue->head = g_curr_task;
      g_curr_task->prev = NULL;
   }
   else
   {
      g_curr_task->prev = prev;
      prev->next = g_curr_task;
   }
   g_curr_task->next = NULL;
/* set the timeout, if there is one */
   if(timeout != NULL)
      g_curr_task->timeout = *timeout;
   else
      g_curr_task->timeout = 0;
/* go do something else until something wakes us */
   schedule();
/* now: why did we return? */
   if(timeout != NULL)
   {
      *timeout = g_curr_task->timeout;
/* there was a timeout, so timer_irq() awoke us. Return -1 */
      if(*timeout == 0)
         return -1;
   }
/* someone called wake_up(), making us TS_RUNNABLE again. Return 0 */
   return 0;
}

void wake_up(wait_queue_t *queue)
{
   task_t *thread, *next;

/* make sure queue is not empty */
   thread = queue->head;
   if(thread == NULL)
      return;
/* mark head thread in queue runnable */
   thread->status = TS_RUNNABLE;
/* remove head thread from queue */
   next = thread->next;
   queue->head = next;
   if(next != NULL)
      next->prev = NULL;
   else
      queue->tail = NULL;
}
http://my.execpc.com/CE/AC/geezer/os/boreal11.zip
"Simplicity is the ultimate sophistication."
http://bos.asmhackers.net/ - GitHub
Post Reply