Solved

Convert 32bit UTC timestamp to yr, mo, da, sec, etc.

Posted on 2000-02-22
10
615 Views
Last Modified: 2010-05-18
Hi there everyone.

I am trying to convert a 32 bit UTC timestamp, which represents the number of seconds from the year 1900, into the current year, month, , date, day, hr, min, se.  Does anyone have the algorithm to calculate this and can help explain how the algorithm works? Thanks.
0
Comment
Question by:sailwind
  • 3
  • 2
  • 2
  • +2
10 Comments
 
LVL 84

Expert Comment

by:ozo
ID: 2548287
#include <time.h>
struct tm *gmtime (const time_t *timer);
0
 
LVL 3

Author Comment

by:sailwind
ID: 2548474

Ozo, thanks for your interest again. I used your answer last time and it worked fine. This time around though, I would like to see the actual algorithm and understand exactly how the year, date, month, etc is calculated.

I tried looking at some of the standard C routines, but couldn't make heads or tail of the advanced stuff it was doing. Can anyone propose an efficient yet easy to understand algorithm for converting the timestamp to smaller time units? Thanks.
0
 
LVL 84

Expert Comment

by:ozo
ID: 2548559
0
 
LVL 3

Expert Comment

by:sumant032199
ID: 2550229
If the time is divided in a single 32 bit number i.e. if it is bitfield then let me know how the fields are divided in bits?

I mean,
hours ===   __ to __ bits
min   ===   __ to __ bits
sec   ===   __ to __ bits
0
 
LVL 18

Expert Comment

by:deighton
ID: 2550572
This converts seconds to date & time.  I think it can be readily interpreted.

#include<stdio.h>


void datum(unsigned long secs,long *year,long *month,long *day,long *hour,
 long *min, long *sec)
 {
      long tdays;
      int tyear;
      int year4;       \
      int leap = 0;

      tdays = secs / ((unsigned long) 24 * 3600);

      if (tdays < 1461)
      {
            tyear = tdays / 365;
            tdays = tdays - 365 * tyear;
            leap = 0;
      }
      else
      {
            year4 = (tdays - 1460) / 1461 + 1;
            tdays = (tdays -1460) % 1461;
            if (tdays > 366)
            {
               tyear = year4 * 4 + (tdays - 366)/365+1;
               tdays = (tdays - 366) % 365;
               leap = 0;
            }
            else
            {
               tyear = year4 * 4;
               leap = 1;
            }
      }

      if (tdays < 31)
      {
            *month = 1;
            *day = tdays;
      }
      else
      {
      if(tdays < 59 + leap)
      {
            *month = 2;
            *day = tdays - 31;
      }
      else
      {
      if(tdays < 90 + leap)
      {
            *month = 3;
            *day  = tdays - 59 - leap;
      }
      else
      {
      if(tdays < 120 + leap)

      {
            *month = 4;
            *day = tdays - 90 - leap;
      }
      else
      {
      if(tdays < 151 + leap)
      {
            *month = 5;
            *day = tdays - 120 - leap;
      }
      else
      {
      if(tdays < 181 + leap)
      {
            *month = 6;
            *day = tdays - 151 - leap;
      }
      else
      {
      if(tdays < 212 + leap)
      {
            *month = 7;
            *day = tdays - 181 - leap;
      }
      else
      {
      if(tdays < 243 + leap)
      {
            *month = 8;
            *day = tdays - 212 - leap;
      }
      else
      {
      if(tdays < 273 + leap)
      {
            *month = 9;
            *day = tdays - 243 - leap;
      }
      else
      {
      if(tdays < 304 + leap)
      {
            *month = 10;
            *day = tdays - 273 - leap;
      }
      else
      {
      if(tdays < 334 + leap)
      {
            *month = 11;
            *day = tdays - 304 - leap;
      }
      else
      {
      if(tdays < 365 + leap)
      {
            *month = 12;
            *day = tdays - 365 - leap;
      }
      }}}}}}}}}}}
      ++(*day);

      *sec = secs % 60;
      *min = (secs / 60) % 60;
      *hour = (secs / 3600) % 24;

      *year = tyear;
}


main()
{
      unsigned long s,y,m,d,h,min,sec;


      do{
      printf("\nSeconds ");
      scanf("%li",&s);

      datum(s,&y,&m,&d,&h,&min,&sec);
      printf("\n %li:%li:%li  %li/%li/%li\n",h,min,sec,m,d,y);
      } while(s!=0);
}

0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 3

Author Comment

by:sailwind
ID: 2551630
sumant, the timestamp is not a bit field. Rather, the 32bit timestamp is the number of seconds from the year 1900 to now. So you cannot just extract the time from the bitfield, but rather have to convert the seconds.
0
 
LVL 3

Author Comment

by:sailwind
ID: 2551637
Deighton, thanks for your suggestion, I believe it works. However, does anyone know of a smaller, more efficient algorithm? Ozo offered one last time which was about 18 lines, but I have a hard time understanding what it was doing.

I'm looking for an efficient algorithm, and someone to explain to me how that algorithm works. Ozo, if you could explain to me step by step how that algorithm worked it would be great too.

Sorry, opening up question to more suggestions
0
 
LVL 18

Expert Comment

by:deighton
ID: 2553674
ozo's formula was based on all sorts of mathematical trickery to implicitly adjust for leap years etc.

I've got a hard time explaining it too.

My algorithm is not inefficient, not as efficient as the ozo formula, but i developed it to be more readily understandable.


0
 
LVL 4

Expert Comment

by:Alex Curylo
ID: 2560410
Well, here's an implementation that I think is both pretty understandable and acceptably efficient, and it even works with Windows ;)

#define seconds_per_minute      (60L)
#define seconds_per_hour            (60L * seconds_per_minute)
#define seconds_per_day                  (24L * seconds_per_hour)

 const short __month_to_days[2][13] =
      {
      {0,31,59,90, 120, 151, 181, 212, 243, 273, 304,334, 365 },
      {0,31,60,91, 121, 152, 182, 213, 244, 274, 305,335, 366 }
      };

/*
 *      leap_year - return nonzero if year is a leap year, zero otherwise (year 0 = 1900)
 */

int __leap_year(int year);
int __leap_year(int year)
{
      return(__mod(year, 4) == 0 && (__mod(year, 100) != 0 || __mod(year, 400) == 100));
}

/*
 *      __time2tm - convert seconds since midnight, 1/1/1900 (or 1970 on Win32),
 *      to broken-down time
 */

#if (__dest_os == __win32_os  || __dest_os == __wince_os)
static void __time2tm(time_t inTime, struct tm * tm)
#else
static void __time2tm(time_t time, struct tm * tm)
#endif
{
      unsigned long      years, months, days, seconds;
      int                                    is_leap_year;

      #if (__dest_os == __win32_os  || __dest_os == __wince_os)
            /* Since Win32 time_t is relative to 1970 rather than 1900.
             * This must be of type unsigned long rather than a signed
             * time_t to prevent overflow */
            unsigned long time = inTime + ((365 * 70UL) + 17) * 24 * 60 * 60;
      #endif

      if (!tm)
            return;

      tm->tm_isdst = -1;

      days    = time / seconds_per_day;
      seconds = time % seconds_per_day;

      tm->tm_wday = (days + 1) % 7;
                  /* January 1, 1900 was a Monday */

      years = 0;

      for (;;)
      {
            unsigned long      days_this_year = __leap_year(years) ? 366 : 365;

            if (days < days_this_year)
                  break;

            days  -= days_this_year;
            years += 1;
      }

      tm->tm_year = years;
      tm->tm_yday = days;

      months = 0;

      is_leap_year = __leap_year(years);

      for (;;)
      {
            unsigned long days_thru_this_month = __month_to_days[is_leap_year][months+1];

            if (days < days_thru_this_month)
            {
                  days -= __month_to_days[is_leap_year][months];
                  break;
            }

            ++months;
      }

      tm->tm_mon  = months;
      tm->tm_mday = days + 1;

      tm->tm_hour = seconds / seconds_per_hour;

      seconds %= seconds_per_hour;

      tm->tm_min = seconds / seconds_per_minute;
      tm->tm_sec = seconds % seconds_per_minute;
}
0
 
LVL 4

Accepted Solution

by:
Alex Curylo earned 200 total points
ID: 2560418
Hrmph. I meant that last post to be an answer candidate.

I also meant it to keep the indentation. Sorry about that. Oh well, it's not that complicated.
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Suggested Solutions

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now