mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-28 20:43:36 +01:00
Some time manipulation. Added the targets to the .gitignore file.
This commit is contained in:
parent
1f223f807f
commit
58db663ae6
19 changed files with 268 additions and 71 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -10,3 +10,8 @@ build/**
|
||||||
|
|
||||||
# Some notes.
|
# Some notes.
|
||||||
LIBC
|
LIBC
|
||||||
|
|
||||||
|
# Output files
|
||||||
|
libc.a
|
||||||
|
libgint.a
|
||||||
|
gintdemo.g1a
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -14,7 +14,7 @@
|
||||||
# Modules
|
# Modules
|
||||||
modules-gint = core keyboard mmu mpu rtc screen timer \
|
modules-gint = core keyboard mmu mpu rtc screen timer \
|
||||||
bopti display gray tales
|
bopti display gray tales
|
||||||
modules-libc = setjmp string stdio stdlib
|
modules-libc = setjmp string stdio stdlib time
|
||||||
|
|
||||||
# Targets
|
# Targets
|
||||||
target-g1a = gintdemo.g1a
|
target-g1a = gintdemo.g1a
|
||||||
|
|
|
@ -38,7 +38,7 @@ register access and implements a few standard functions.
|
||||||
Building and installing
|
Building and installing
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
There a some dependencies:
|
There are some dependencies:
|
||||||
* The `sh3eb-elf` toolchain somewhere in the PATH
|
* The `sh3eb-elf` toolchain somewhere in the PATH
|
||||||
* The fxSDK installed and available in the PATH
|
* The fxSDK installed and available in the PATH
|
||||||
|
|
||||||
|
|
3
TODO
3
TODO
|
@ -18,11 +18,10 @@
|
||||||
+ partial transparency
|
+ partial transparency
|
||||||
+ gint vs. ML with 248x124 at (-60, -28)
|
+ gint vs. ML with 248x124 at (-60, -28)
|
||||||
+ call exit handlers
|
+ call exit handlers
|
||||||
+ compute frequencies
|
+ compute frequencies and CLOCKS_PER_SEC
|
||||||
+ test all font encodings
|
+ test all font encodings
|
||||||
|
|
||||||
- improve exception handler debugging information (if possible)
|
- improve exception handler debugging information (if possible)
|
||||||
- full rtc driver (time)
|
|
||||||
- callbacks and complete user API
|
- callbacks and complete user API
|
||||||
|
|
||||||
~ packed bit fields
|
~ packed bit fields
|
||||||
|
|
BIN
gintdemo.g1a
BIN
gintdemo.g1a
Binary file not shown.
16
include/internals/time.h
Normal file
16
include/internals/time.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef _INTERNALS_TIME_H
|
||||||
|
#define _INTERNALS_TIME_H 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
isLeap()
|
||||||
|
Determines whether the given year is a leap year.
|
||||||
|
*/
|
||||||
|
int isLeap(int year);
|
||||||
|
|
||||||
|
/*
|
||||||
|
daysInMonth()
|
||||||
|
Returns number of days for the given month (between 0 and 11) and year.
|
||||||
|
*/
|
||||||
|
int daysInMonth(int month, int year);
|
||||||
|
|
||||||
|
#endif // _INTERNALS_TIME_H
|
|
@ -15,9 +15,7 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
struct RTCTime
|
struct RTCTime
|
||||||
Defines a point in time. This structure *is* the standard struct tm to
|
Defines a point in time.
|
||||||
avoid useless data copy in the interface between this module and the
|
|
||||||
standard time module.
|
|
||||||
*/
|
*/
|
||||||
struct RTCTime
|
struct RTCTime
|
||||||
{
|
{
|
||||||
|
@ -26,21 +24,21 @@ struct RTCTime
|
||||||
int hours; // Hours in range 0-23
|
int hours; // Hours in range 0-23
|
||||||
int month_day; // Day of month in range 1-31
|
int month_day; // Day of month in range 1-31
|
||||||
int month; // Month in range 0-11
|
int month; // Month in range 0-11
|
||||||
int year; // Number of years since 1900
|
int year; // Years (full value)
|
||||||
int week_day; // Day of week in range 0(Sunday)-6(Saturday).
|
int week_day; // Day of week in range 0(Sunday)-6(Saturday).
|
||||||
int year_day; // Day of the year in range 0-365.
|
|
||||||
int daylight_saving; // As far as I known the RTC does not use DST.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
rtc_getTime()
|
rtc_getTime()
|
||||||
Reads the current time from the RTC.
|
Reads the current time from the RTC. There is no guarantee that the
|
||||||
|
week day is correct (use the time API for that).
|
||||||
*/
|
*/
|
||||||
struct RTCTime rtc_getTime(void);
|
struct RTCTime rtc_getTime(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
rtc_setTime()
|
rtc_setTime()
|
||||||
Sets the time in the RTC registers.
|
Sets the time in the RTC registers. The week day is set to 0 if greater
|
||||||
|
than 6. Other fields are not checked.
|
||||||
*/
|
*/
|
||||||
void rtc_setTime(struct RTCTime time);
|
void rtc_setTime(struct RTCTime time);
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ struct tm
|
||||||
int tm_year; // Number of years since 1900
|
int tm_year; // Number of years since 1900
|
||||||
int tm_wday; // Day of week in range 0(Sunday)-6(Saturday).
|
int tm_wday; // Day of week in range 0(Sunday)-6(Saturday).
|
||||||
int tm_yday; // Day of the year in range 0-365.
|
int tm_yday; // Day of the year in range 0-365.
|
||||||
int tm_isdst; // Always -1 (not available).
|
int tm_isdst; // This will always be 0.
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -57,6 +57,17 @@ typedef signed int time_t;
|
||||||
*/
|
*/
|
||||||
clock_t clock(void);
|
clock_t clock(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
time()
|
||||||
|
Returns the current time as calendar time. If you need a broken-down
|
||||||
|
time, either use the RTC API or gmtime(). However, this function is
|
||||||
|
already based on mktime() (for hardware reasons) so it would be much
|
||||||
|
faster to use the RTC API if possible.
|
||||||
|
If timeptr is not NULL, it is set to the current time, that is, the
|
||||||
|
value that is returned.
|
||||||
|
*/
|
||||||
|
time_t time(time_t *timeptr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
difftime()
|
difftime()
|
||||||
Returns the number of seconds between the given points.
|
Returns the number of seconds between the given points.
|
||||||
|
@ -71,15 +82,45 @@ double difftime(time_t end, time_t beginning);
|
||||||
// Time representation.
|
// Time representation.
|
||||||
//---
|
//---
|
||||||
|
|
||||||
|
/*
|
||||||
|
asctime()
|
||||||
|
Converts broken-down time to string representation on the form
|
||||||
|
"Wed Jun 30 21:49:08 1993\n". The returned string is statically
|
||||||
|
allocated and may be overwritten by any subsequent call to a time
|
||||||
|
function.
|
||||||
|
*/
|
||||||
|
char *asctime(const struct tm *time);
|
||||||
|
|
||||||
|
/*
|
||||||
|
ctime()
|
||||||
|
Converts calendar time to string representation on the form
|
||||||
|
"Wed Jun 30 21:49:08 1993\n". The returned string is statically
|
||||||
|
allocated and may be overwritten by any subsequent call to a time
|
||||||
|
function.
|
||||||
|
*/
|
||||||
|
char *ctime(const time_t *timer);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---
|
//---
|
||||||
//
|
// Time conversion.
|
||||||
//---
|
//---
|
||||||
|
|
||||||
/*
|
/*
|
||||||
mktime()
|
mktime()
|
||||||
Computes fields tm_wday and tm_yday using the other fields. Member
|
Converts broken-down time to calendar time. Computes structure fields
|
||||||
structures outside their range are normalized and tm_isdst is set.
|
tm_wday and tm_yday using the other fields. Member structures outside
|
||||||
|
their range are normalized (e.g. 40 October becomes 9 November) and
|
||||||
|
tm_isdst is set.
|
||||||
*/
|
*/
|
||||||
time_t mktime(struct tm *time);
|
time_t mktime(struct tm *time);
|
||||||
|
|
||||||
|
/*
|
||||||
|
gmtime()
|
||||||
|
Converts calendar time to broken-down time. The returned pointer is
|
||||||
|
statically allocated and may be overwritten by any subsequent call to
|
||||||
|
a time function.
|
||||||
|
*/
|
||||||
|
struct tm *gmtime(const time_t *t);
|
||||||
|
|
||||||
#endif // _TIME_H
|
#endif // _TIME_H
|
||||||
|
|
BIN
libc.a
BIN
libc.a
Binary file not shown.
BIN
libgint.a
BIN
libgint.a
Binary file not shown.
|
@ -16,23 +16,11 @@ static int integer16(int bcd)
|
||||||
+ 1000 * (bcd >> 12);
|
+ 1000 * (bcd >> 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int year_day(int year, int year_bcd, int month, int month_day)
|
/*
|
||||||
{
|
rtc_getTime()
|
||||||
int days_in_month[12] = {
|
Reads the current time from the RTC. There is no guarantee that the
|
||||||
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
week day is correct (use the time API for that).
|
||||||
int leap;
|
*/
|
||||||
int hundreds = integer8(year_bcd >> 8);
|
|
||||||
int day, i;
|
|
||||||
|
|
||||||
leap = !(year & 3); // Take multiples of 4
|
|
||||||
if(!((year_bcd >> 8) & 0xf)) leap = 0; // Remove multiples of 100
|
|
||||||
if(!(hundreds & 3)) leap = 1; // Take multiples of 400
|
|
||||||
|
|
||||||
day = leap && (month > 2);
|
|
||||||
for(i = 0; i < month - 1; i++) day += days_in_month[i];
|
|
||||||
return day + month_day - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct RTCTime rtc_getTime(void)
|
struct RTCTime rtc_getTime(void)
|
||||||
{
|
{
|
||||||
volatile struct mod_rtc *rtc = isSH3() ? RTC_SH7705 : RTC_SH7305;
|
volatile struct mod_rtc *rtc = isSH3() ? RTC_SH7705 : RTC_SH7305;
|
||||||
|
@ -43,11 +31,8 @@ struct RTCTime rtc_getTime(void)
|
||||||
time.hours = integer8(rtc->RHRCNT.BYTE);
|
time.hours = integer8(rtc->RHRCNT.BYTE);
|
||||||
time.month_day = integer8(rtc->RDAYCNT.BYTE);
|
time.month_day = integer8(rtc->RDAYCNT.BYTE);
|
||||||
time.month = integer8(rtc->RMONCNT.BYTE);
|
time.month = integer8(rtc->RMONCNT.BYTE);
|
||||||
time.year = integer16(rtc->RYRCNT.WORD) - 1900;
|
time.year = integer16(rtc->RYRCNT.WORD);
|
||||||
time.week_day = rtc->RWKCNT;
|
time.week_day = rtc->RWKCNT;
|
||||||
time.year_day = year_day(time.year + 1900, rtc->RYRCNT.WORD,
|
|
||||||
time.month, time.month_day);
|
|
||||||
|
|
||||||
time.daylight_saving = 0;
|
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,11 @@ static int bcd16(int integer)
|
||||||
return (bcd8(integer / 100) << 8) | bcd8(integer % 100);
|
return (bcd8(integer / 100) << 8) | bcd8(integer % 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
rtc_setTime()
|
||||||
|
Sets the time in the RTC registers. The week day is set to 0 if greater
|
||||||
|
than 6. Other fields are not checked.
|
||||||
|
*/
|
||||||
void rtc_setTime(struct RTCTime time)
|
void rtc_setTime(struct RTCTime time)
|
||||||
{
|
{
|
||||||
volatile struct mod_rtc *rtc = isSH3() ? RTC_SH7705 : RTC_SH7305;
|
volatile struct mod_rtc *rtc = isSH3() ? RTC_SH7705 : RTC_SH7305;
|
||||||
|
@ -26,6 +31,6 @@ void rtc_setTime(struct RTCTime time)
|
||||||
rtc->RHRCNT.BYTE = bcd8(time.hours);
|
rtc->RHRCNT.BYTE = bcd8(time.hours);
|
||||||
rtc->RDAYCNT.BYTE = bcd8(time.month_day);
|
rtc->RDAYCNT.BYTE = bcd8(time.month_day);
|
||||||
rtc->RMONCNT.BYTE = bcd8(time.month);
|
rtc->RMONCNT.BYTE = bcd8(time.month);
|
||||||
rtc->RYRCNT.WORD = bcd16(time.year + 1900);
|
rtc->RYRCNT.WORD = bcd16(time.year);
|
||||||
rtc->RWKCNT = time.week_day < 7 ? time.week_day : 0;
|
rtc->RWKCNT = time.week_day < 7 ? time.week_day : 0;
|
||||||
}
|
}
|
||||||
|
|
57
src/time/asctime.c
Normal file
57
src/time/asctime.c
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
static char str[26];
|
||||||
|
|
||||||
|
/*
|
||||||
|
asctime()
|
||||||
|
Converts broken-down time to string representation on the form
|
||||||
|
"Wed Jun 30 21:49:08 1993\n". The returned string is statically
|
||||||
|
allocated and may be overwritten by any subsequent call to a time
|
||||||
|
function.
|
||||||
|
*/
|
||||||
|
char *asctime(const struct tm *time)
|
||||||
|
{
|
||||||
|
const char *days[] = {
|
||||||
|
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
|
||||||
|
}, *months[] = {
|
||||||
|
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
|
||||||
|
"Sep", "Oct", "Nov", "Dec"
|
||||||
|
};
|
||||||
|
int year = time->tm_year + 1900;
|
||||||
|
|
||||||
|
str[0] = days[time->tm_wday][0];
|
||||||
|
str[1] = days[time->tm_wday][1];
|
||||||
|
str[2] = days[time->tm_wday][2];
|
||||||
|
str[3] = ' ';
|
||||||
|
|
||||||
|
str[4] = months[time->tm_mon][0];
|
||||||
|
str[5] = months[time->tm_mon][1];
|
||||||
|
str[6] = months[time->tm_mon][2];
|
||||||
|
str[7] = ' ';
|
||||||
|
|
||||||
|
str[8] = '0' + (time->tm_mday / 10);
|
||||||
|
str[9] = '0' + (time->tm_mday % 10);
|
||||||
|
str[10] = ' ';
|
||||||
|
|
||||||
|
str[11] = '0' + (time->tm_hour / 10);
|
||||||
|
str[12] = '0' + (time->tm_hour % 10);
|
||||||
|
str[13] = ':';
|
||||||
|
str[14] = '0' + (time->tm_min / 10);
|
||||||
|
str[15] = '0' + (time->tm_min % 10);
|
||||||
|
str[16] = ':';
|
||||||
|
str[17] = '0' + (time->tm_sec / 10);
|
||||||
|
str[18] = '0' + (time->tm_sec % 10);
|
||||||
|
str[19] = ' ';
|
||||||
|
|
||||||
|
str[20] = '0' + (year / 1000);
|
||||||
|
year %= 1000;
|
||||||
|
str[21] = '0' + (year / 100);
|
||||||
|
year %= 100;
|
||||||
|
str[22] = '0' + (year / 10);
|
||||||
|
str[23] = '0' + (year % 10);
|
||||||
|
|
||||||
|
str[24] = '\n';
|
||||||
|
str[25] = 0;
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
13
src/time/ctime.c
Normal file
13
src/time/ctime.c
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
ctime()
|
||||||
|
Converts calendar time to string representation on the form
|
||||||
|
"Wed Jun 30 21:49:08 1993\n". The returned string is statically
|
||||||
|
allocated and may be overwritten by any subsequent call to a time
|
||||||
|
function.
|
||||||
|
*/
|
||||||
|
char *ctime(const time_t *timer)
|
||||||
|
{
|
||||||
|
return asctime(gmtime(timer));
|
||||||
|
}
|
45
src/time/gmtime.c
Normal file
45
src/time/gmtime.c
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#include <time.h>
|
||||||
|
#include <internals/time.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static struct tm tm;
|
||||||
|
|
||||||
|
/*
|
||||||
|
gmtime()
|
||||||
|
Converts calendar time to broken-down time. The returned pointer is
|
||||||
|
statically allocated and may be overwritten by any subsequent call to
|
||||||
|
a time function.
|
||||||
|
*/
|
||||||
|
struct tm *gmtime(const time_t *timeptr)
|
||||||
|
{
|
||||||
|
time_t t = *timeptr;
|
||||||
|
div_t d;
|
||||||
|
int sec;
|
||||||
|
|
||||||
|
tm.tm_year = 1970;
|
||||||
|
tm.tm_mon = 0;
|
||||||
|
|
||||||
|
sec = daysInMonth(tm.tm_mon, tm.tm_year) * 24 * 3600;
|
||||||
|
while(t >= sec)
|
||||||
|
{
|
||||||
|
t -= sec;
|
||||||
|
if(++tm.tm_mon == 12)
|
||||||
|
{
|
||||||
|
tm.tm_year++;
|
||||||
|
tm.tm_mon = 0;
|
||||||
|
}
|
||||||
|
sec = daysInMonth(tm.tm_mon, tm.tm_year) * 24 * 3600;
|
||||||
|
}
|
||||||
|
tm.tm_year -= 1900;
|
||||||
|
|
||||||
|
d = div(sec, 24 * 3600);
|
||||||
|
tm.tm_mday = d.quot;
|
||||||
|
d = div(d.rem, 3600);
|
||||||
|
tm.tm_hour = d.quot;
|
||||||
|
d = div(d.rem, 60);
|
||||||
|
tm.tm_min = d.quot;
|
||||||
|
tm.tm_sec = d.rem;
|
||||||
|
|
||||||
|
mktime(&tm);
|
||||||
|
return &tm;
|
||||||
|
}
|
|
@ -1,42 +1,17 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <internals/time.h>
|
||||||
/*
|
|
||||||
isLeap()
|
|
||||||
Determines whether the given year is a leap year.
|
|
||||||
*/
|
|
||||||
int isLeap(int year)
|
|
||||||
{
|
|
||||||
int leap = !(year & 3); // Take multiples of 4
|
|
||||||
if(!(year % 100)) leap = 0; // Remove multiples of 100
|
|
||||||
if(!(year % 400)) leap = 1; // Take multiples of 400
|
|
||||||
|
|
||||||
return leap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
daysInMonth()
|
|
||||||
Returns number of days for the given month (between 0 and 11) and year.
|
|
||||||
*/
|
|
||||||
int daysInMonth(int month, int year)
|
|
||||||
{
|
|
||||||
int days[12] = {
|
|
||||||
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
|
||||||
};
|
|
||||||
|
|
||||||
if(month != 1) return days[month];
|
|
||||||
return days[month] + isLeap(year);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
mktime()
|
mktime()
|
||||||
Computes fields tm_wday and tm_yday using the other fields. Member
|
Converts broken-down time to calendar time. Computes structure fields
|
||||||
structures outside their range are normalized and tm_isdst is set.
|
tm_wday and tm_yday using the other fields. Member structures outside
|
||||||
|
their range are normalized (e.g. 40 October becomes 9 November) and
|
||||||
|
tm_isdst is set.
|
||||||
*/
|
*/
|
||||||
time_t mktime(struct tm *time)
|
time_t mktime(struct tm *time)
|
||||||
{
|
{
|
||||||
int first, leaps, yr;
|
int leaps, yr;
|
||||||
int days, i;
|
int days, i;
|
||||||
time_t elapsed;
|
|
||||||
|
|
||||||
// Normalizing time.
|
// Normalizing time.
|
||||||
time->tm_min += (time->tm_sec / 60);
|
time->tm_min += (time->tm_sec / 60);
|
||||||
|
@ -88,6 +63,6 @@ time_t mktime(struct tm *time)
|
||||||
// days may become negative, so add the calendar period.
|
// days may become negative, so add the calendar period.
|
||||||
if(days < 0) days += 146097;
|
if(days < 0) days += 146097;
|
||||||
|
|
||||||
return (24 * 3600) * days + 3600 * time->tm_hour + 60 * time->tm_min +
|
return (time_t)((24 * 3600) * days + 3600 * time->tm_hour +
|
||||||
time->tm_sec;
|
60 * time->tm_min + time->tm_sec);
|
||||||
}
|
}
|
||||||
|
|
29
src/time/time.c
Normal file
29
src/time/time.c
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#include <time.h>
|
||||||
|
#include <rtc.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
time()
|
||||||
|
Returns the current time as calendar time. If you need a broken-down
|
||||||
|
time, either use the RTC API or gmtime(). However, this function is
|
||||||
|
already based on mktime() (for hardware reasons) so it would be much
|
||||||
|
faster to use the RTC API if possible.
|
||||||
|
If timeptr is not NULL, it is set to the current time, that is, the
|
||||||
|
value that is returned.
|
||||||
|
*/
|
||||||
|
time_t time(time_t *timeptr)
|
||||||
|
{
|
||||||
|
struct RTCTime rtc = rtc_getTime();
|
||||||
|
struct tm tm;
|
||||||
|
time_t calendar;
|
||||||
|
|
||||||
|
tm.tm_sec = rtc.seconds;
|
||||||
|
tm.tm_min = rtc.minutes;
|
||||||
|
tm.tm_hour = rtc.hours;
|
||||||
|
tm.tm_mday = rtc.month_day;
|
||||||
|
tm.tm_mon = rtc.month;
|
||||||
|
tm.tm_year = rtc.year - 1900;
|
||||||
|
|
||||||
|
calendar = mktime(&tm);
|
||||||
|
if(timeptr) *timeptr = calendar;
|
||||||
|
return calendar;
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#undef difftime
|
||||||
|
|
||||||
/*
|
/*
|
||||||
clock()
|
clock()
|
||||||
|
|
28
src/time/time_util.c
Normal file
28
src/time/time_util.c
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#include <internals/time.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
isLeap()
|
||||||
|
Determines whether the given year is a leap year.
|
||||||
|
*/
|
||||||
|
int isLeap(int year)
|
||||||
|
{
|
||||||
|
int leap = !(year & 3); // Take multiples of 4
|
||||||
|
if(!(year % 100)) leap = 0; // Remove multiples of 100
|
||||||
|
if(!(year % 400)) leap = 1; // Take multiples of 400
|
||||||
|
|
||||||
|
return leap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
daysInMonth()
|
||||||
|
Returns number of days for the given month (between 0 and 11) and year.
|
||||||
|
*/
|
||||||
|
int daysInMonth(int month, int year)
|
||||||
|
{
|
||||||
|
int days[12] = {
|
||||||
|
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
||||||
|
};
|
||||||
|
|
||||||
|
if(month != 1) return days[month];
|
||||||
|
return days[month] + isLeap(year);
|
||||||
|
}
|
Loading…
Reference in a new issue