|
|
View previous topic :: View next topic |
Author |
Message |
VanHauser
Joined: 03 Oct 2005 Posts: 88 Location: Ploiesti, Romania
|
Date and time routines |
Posted: Sun Jan 08, 2006 4:45 am |
|
|
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
|
|
Posted: Wed Feb 08, 2006 4:56 pm |
|
|
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
|
|
Posted: Thu Feb 09, 2006 2:16 am |
|
|
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
|
|
Posted: Wed Mar 22, 2006 5:19 pm |
|
|
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
|
|
Posted: Fri Mar 31, 2006 9:45 am |
|
|
So for example 2027 is a leap year? That #define would return so. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu May 18, 2006 5:50 am |
|
|
VanHauser wrote: | So for example 2027 is a leap year? 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
|
|
Posted: Thu May 18, 2006 8:37 am |
|
|
Code: |
#define IS_LEAP(year) ((year % 4 == 0) &&( (year % 100 != 0) || (year % 400 == 0) ) )
|
I think it's better
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
|
|
Posted: Fri May 19, 2006 4:41 am |
|
|
Nope. Read the comment preceding the library code. |
|
|
cagdasyet
Joined: 06 Aug 2011 Posts: 2
|
Thanks |
Posted: Fri Mar 16, 2012 6:56 am |
|
|
Thank you VanHauser
I will use this in my project |
|
|
Eduardo__
Joined: 23 Nov 2011 Posts: 197 Location: Brazil
|
|
Posted: Fri Jun 22, 2012 12:30 pm |
|
|
Thank you a lot Mr. Aurelian Nichita!
Your library is great. _________________ Eduardo Guilherme Brandt |
|
|
lucasromeiro
Joined: 27 Mar 2010 Posts: 167
|
Re: Date and time routines |
Posted: Tue Sep 22, 2015 3:44 pm |
|
|
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 |
|
|
|
|
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
|