CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Date and time routines

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
VanHauser



Joined: 03 Oct 2005
Posts: 88
Location: Ploiesti, Romania

View user's profile Send private message

Date and time routines
PostPosted: Sun Jan 08, 2006 4:45 am     Reply with quote

Here's a library that I have developed over time for my projects. It contains functions for calculating the day of week, ISO week number of a year, number of seconds between two dates/times, and some other minor functions.

Code:

/************************************************/
/*                                              */
/*  Date and time routines for CCS C Compiler   */
/*  Version 2.00                                */
/*                                              */
/*  Years are considered in short form, for ex. */
/*  year 2006 is 6 and so on. Functions are     */
/*  generally adapted for years 1 to 98.        */
/*                                              */
/*  Author:  Aurelian Nichita                   */ 
/*  Contact: aurelian.info@gmail.com            */
/*                                              */
/************************************************/


/* ISO day numbers */
#define MONDAY    1
#define TUESDAY   2
#define WEDNESDAY 3
#define THURSDAY  4
#define FRIDAY    5
#define SATURDAY  6
#define SUNDAY    7

const int monthDays[2][13] = { {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
                               {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} };

const int ZellerDOW[7] = {6, 7, 1, 2, 3, 4, 5};

#define SECONDS_IN_DAY 86400

#define SECONDS_IN_HOUR 3600
#define SECONDS_IN_MINUTE 60
#define MINUTES_IN_DAY 1440
#define MINUTES_IN_HOUR 60
#define HOURS_IN_DAY 24


/*** Some functions that are used below ***/

#inline
short isLeapYear(int y) {
  return (y % 4 == 0);
}

#separate
int32 daysSinceYear1(int y, int m, int d) {
  int32 days = 0;
  int i;
  short leap_y;

  leap_y = isLeapYear(y);
  for (i=1; i<y; i++) {
    if (isLeapYear(i))
      days += 366;
    else
      days += 365;
  }
  for (i=1; i<m; i++)
    days += monthDays[leap_y][i];
  days += d;

  return days;
}

#separate
int32 secondsSinceHour0(int h, int m, int s) {
  int32 seconds;
  seconds = (int32)h * SECONDS_IN_HOUR;
  seconds += (int32)m * SECONDS_IN_MINUTE;
  seconds += s;
  return seconds;
}

#separate
int32 secondsSinceYear1(int yr, mo, dy, hr, mi, se) {
  int32 seconds;
  seconds = daysSinceYear1(yr, mo, dy) * SECONDS_IN_DAY;
  seconds += secondsSinceHour0(hr, mi, se);
  return seconds;
}

/******* Calculate the number of seconds between two dates and times ******/
/******* Adapted for years 2001 to 2135 (limited by size of int32)   ******/

#separate
int32 secondsBetween(int yr1, mo1, dy1, hr1, mi1, se1, yr2, mo2, dy2, hr2, mi2, se2) {
  int32 start;
  int32 end;
  start = secondsSinceYear1(yr1, mo1, dy1, hr1, mi1, se1);
  end = secondsSinceYear1(yr2, mo2, dy2, hr2, mi2, se2);
  if (start > end)
    return start-end;
  else
    return end-start;
}

/******* Weekday computation. Adapted ONLY for years 2000 to 2099  ********/

#separate
int ISODayOfWeek(int YY, int MM, int DD) {
  signed long dayOfWeek;
  int cent = 20;  // YYYY / 100

  // Zeller's Congruence algorythm

  if (MM < 3) {
    MM = MM + 12;
    if (YY > 0)
      YY--;
    else {
      YY = 99;
      cent--;
    }
  }

  dayOfWeek = DD;
  dayOfWeek += (((signed long)MM + 1) * 26) / 10;
  dayOfWeek += YY;
  dayOfWeek += YY / 4;
  dayOfWeek += cent / 4;
  dayOfWeek -= cent * 2;

  while (dayOfWeek < 0)
    dayOfWeek += 7;

  dayOfWeek %= 7;

  return ZellerDOW[(int)dayOfWeek]; // Now we have ISO day of week
}

/**** ISO Weeknumber computation. Adapted ONLY for years 2001 to 2098  ****/

#separate
void ISOWeekNumber(int YY, int MM, int DD, int& weekOfYear, int& actualYear) {
  signed long dayOfYear;
  int startDayOfWeek;
  int endDayOfWeek;
  short leap;
  signed int i;

  do {
    leap = isLeapYear(YY);
    dayOfYear = 0;

    for (i=1; i<=MM; i++) {
      if (i < MM)
        dayOfYear += monthDays[leap][i];
      else
        dayOfYear += DD;
    }
    actualYear = YY;
    startDayOfWeek = ISODayOfWeek(actualYear, 1, 1);

    if (startDayOfWeek > THURSDAY)
      dayOfYear -= 8 - startDayOfWeek;
    else
      dayOfYear += startDayOfWeek - 1;

    if (dayOfYear <= 0)
      weekOfYear = 0xFF;
    else {
      weekOfYear = dayOfYear / 7;
      if (dayOfYear % 7 != 0)
        weekOfYear++;
      if (weekOfYear > 52) {
        endDayOfWeek = startDayOfWeek;
        if (leap) {
          if (endDayOfWeek == SUNDAY)
            endDayOfWeek = MONDAY;
          else
            endDayOfWeek++;
        }
        if (endDayOfWeek < THURSDAY) {
          actualYear++;
          weekOfYear = 1;
        }
      }
    }

    if (weekOfYear == 0xFF) {
      if ((--DD)==0) {
        if ((--MM)==0) {
          YY--;
          MM = 12;
        }
        DD = monthDays[isLeapYear(YY)][MM];
      }
    }

  } while (weekOfYear == 0xFF);
}


Last edited by VanHauser on Wed Aug 24, 2016 4:00 am; edited 1 time in total
John Morley



Joined: 09 Aug 2004
Posts: 97

View user's profile Send private message

PostPosted: Wed Feb 08, 2006 4:56 pm     Reply with quote

Sorry, brain freeze!

John
_________________
John Morley


Last edited by John Morley on Thu Feb 09, 2006 9:26 am; edited 1 time in total
VanHauser



Joined: 03 Oct 2005
Posts: 88
Location: Ploiesti, Romania

View user's profile Send private message

PostPosted: Thu Feb 09, 2006 2:16 am     Reply with quote

Windows XP's clock shows february 1996 with 29 days, so it must be a leap year. Also everybody I asked says that. I know that formula, but the whole library is valid only for the 21'st century so the simplified formula is perfectly valid. See the notice at the top regarding also the simplified year notation. The library is thoroughly tested, I assure you.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed Mar 22, 2006 5:19 pm     Reply with quote

Nice functions. Thanks for sharing!

For the leap year calculation I save a few bytes by using the following optimized code
Code:
////////////////////////////////////////////////////////////////////////////////
// Test whether a given year is a leap year.
// This optimized version only works for the period 1901 - 2099
////////////////////////////////////////////////////////////////////////////////
#define IS_LEAP(year) (!(year & 4))
VanHauser



Joined: 03 Oct 2005
Posts: 88
Location: Ploiesti, Romania

View user's profile Send private message

PostPosted: Fri Mar 31, 2006 9:45 am     Reply with quote

So for example 2027 is a leap year? Wink That #define would return so.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu May 18, 2006 5:50 am     Reply with quote

VanHauser wrote:
So for example 2027 is a leap year? Wink That #define would return so.
You are right, my macro is shorter but wrong. Thanks for mentioning, gives me time till 2008 to fix the bug.
ben fem



Joined: 18 May 2006
Posts: 3

View user's profile Send private message

PostPosted: Thu May 18, 2006 8:37 am     Reply with quote

Code:

#define IS_LEAP(year) ((year % 4 == 0) &&( (year % 100 != 0) || (year % 400 == 0) ) )


I think it's better Wink

EDIT : This routine works if year is a long ( 1999, 2006... etc).
In this lib, as the year is a short (6 for 2006 for ex) code
#define IS_LEAP(year) (year % 4 == 0) is right. So sorry for my mistake.


Last edited by ben fem on Mon May 22, 2006 1:43 am; edited 1 time in total
VanHauser



Joined: 03 Oct 2005
Posts: 88
Location: Ploiesti, Romania

View user's profile Send private message

PostPosted: Fri May 19, 2006 4:41 am     Reply with quote

Nope. Read the comment preceding the library code.
cagdasyet



Joined: 06 Aug 2011
Posts: 2

View user's profile Send private message

Thanks
PostPosted: Fri Mar 16, 2012 6:56 am     Reply with quote

Thank you VanHauser
I will use this in my project
Eduardo__



Joined: 23 Nov 2011
Posts: 197
Location: Brazil

View user's profile Send private message

PostPosted: Fri Jun 22, 2012 12:30 pm     Reply with quote

Thank you a lot Mr. Aurelian Nichita!
Your library is great.
_________________
Eduardo Guilherme Brandt
lucasromeiro



Joined: 27 Mar 2010
Posts: 167

View user's profile Send private message

Re: Date and time routines
PostPosted: Tue Sep 22, 2015 3:44 pm     Reply with quote

VanHauser wrote:
Here's a library that I have developed over time for my projects. It contains functions for calculating the day of week, ISO week number of a year, number of seconds between two dates/times, and some other minor functions.

Code:

/************************************************/
/*                                              */
/*  Date and time routines for CCS C Compiler   */
/*  Version 2.00                                */
/*                                              */
/*  Years are considered in short form, for ex. */
/*  year 2006 is 6 and so on. Functions are     */
/*  generally adapted for years 1 to 98.        */
/*                                              */
/*  Author:  Aurelian Nichita                   */ 
/*  Contact: nicksubzero@yahoo.com              */
/*                                              */
/************************************************/


}



How can I do the reverse?
convert to seconds, then upload to my server, then convert to date. Not managed to recover. I could not convert again
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group