$treeview $search $mathjax $extrastylesheet
avr-libc  2.0.0
$projectbrief
$projectbrief
$searchbox

AVR Libc Home Page

AVRs

AVR Libc Development Pages

Main Page

User Manual

Library Reference

FAQ

Example Projects

time.h

Go to the documentation of this file.
00001 /*
00002  * (C)2012 Michael Duane Rice All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions are
00006  * met:
00007  *
00008  * Redistributions of source code must retain the above copyright notice, this
00009  * list of conditions and the following disclaimer. Redistributions in binary
00010  * form must reproduce the above copyright notice, this list of conditions
00011  * and the following disclaimer in the documentation and/or other materials
00012  * provided with the distribution. Neither the name of the copyright holders
00013  * nor the names of contributors may be used to endorse or promote products
00014  * derived from this software without specific prior written permission.
00015  *
00016  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00019  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00020  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00021  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00022  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00023  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00024  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00025  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00026  * POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00029 /* $Id$ */
00030 
00031 /** \file */
00032 
00033 /**    \defgroup avr_time <time.h>: Time
00034     \code #include <time.h> \endcode
00035     <h3>Introduction to the Time functions</h3>
00036     This file declares the time functions implemented in \c avr-libc.
00037 
00038     The implementation aspires to conform with ISO/IEC 9899 (C90). However, due to limitations of the
00039     target processor and the nature of its development environment, a practical implementation must
00040     of necessity deviate from the standard.
00041 
00042 
00043 
00044     Section 7.23.2.1 clock()
00045     The type clock_t, the macro CLOCKS_PER_SEC, and the function clock() are not implemented. We
00046     consider these items belong to operating system code, or to application code when no operating
00047     system is present.
00048 
00049     Section 7.23.2.3 mktime()
00050     The standard specifies that mktime() should return (time_t) -1, if the time cannot be represented.
00051     This implementation always returns a 'best effort' representation.
00052 
00053     Section 7.23.2.4 time()
00054     The standard specifies that time() should return (time_t) -1, if the time is not available.
00055     Since the application must initialize the time system, this functionality is not implemented.
00056 
00057     Section 7.23.2.2, difftime()
00058     Due to the lack of a 64 bit double, the function difftime() returns a long integer. In most cases
00059     this change will be invisible to the user, handled automatically by the compiler.
00060 
00061     Section 7.23.1.4 struct tm
00062     Per the standard, struct tm->tm_isdst is greater than zero when Daylight Saving time is in effect.
00063     This implementation further specifies that, when positive, the value of tm_isdst represents
00064     the amount time is advanced during Daylight Saving time.
00065 
00066     Section 7.23.3.5 strftime()
00067     Only the 'C' locale is supported, therefore the modifiers 'E' and 'O' are ignored.
00068     The 'Z' conversion is also ignored, due to the lack of time zone name.
00069 
00070     In addition to the above departures from the standard, there are some behaviors which are different
00071     from what is often expected, though allowed under the standard.
00072 
00073     There is no 'platform standard' method to obtain the current time, time zone, or
00074     daylight savings 'rules' in the AVR environment. Therefore the application must initialize
00075     the time system with this information. The functions set_zone(), set_dst(), and
00076     set_system_time() are provided for initialization. Once initialized, system time is maintained by
00077     calling the function system_tick() at one second intervals.
00078 
00079     Though not specified in the standard, it is often expected that time_t is a signed integer
00080     representing an offset in seconds from Midnight Jan 1 1970... i.e. 'Unix time'. This implementation
00081     uses an unsigned 32 bit integer offset from Midnight Jan 1 2000. The use of this 'epoch' helps to
00082     simplify the conversion functions, while the 32 bit value allows time to be properly represented
00083     until Tue Feb 7 06:28:15 2136 UTC. The macros UNIX_OFFSET and NTP_OFFSET are defined to assist in
00084     converting to and from Unix and NTP time stamps.
00085 
00086     Unlike desktop counterparts, it is impractical to implement or maintain the 'zoneinfo' database.
00087     Therefore no attempt is made to account for time zone, daylight saving, or leap seconds in past dates.
00088     All calculations are made according to the currently configured time zone and daylight saving 'rule'.
00089 
00090     In addition to C standard functions, re-entrant versions of ctime(), asctime(), gmtime() and
00091     localtime() are provided which, in addition to being re-entrant, have the property of claiming
00092     less permanent storage in RAM. An additional time conversion, isotime() and its re-entrant version,
00093     uses far less storage than either ctime() or asctime().
00094 
00095     Along with the usual smattering of utility functions, such as is_leap_year(), this library includes
00096     a set of functions related the sun and moon, as well as sidereal time functions.
00097 */
00098 
00099 #ifndef TIME_H
00100 #define TIME_H
00101 
00102 #ifdef __cplusplus
00103 extern          "C" {
00104 #endif
00105 
00106 #include <inttypes.h>
00107 #include <stdlib.h>
00108 
00109     /** \ingroup avr_time */
00110     /* @{ */
00111 
00112     /**
00113         time_t represents seconds elapsed from Midnight, Jan 1 2000 UTC (the Y2K 'epoch').
00114         Its range allows this implementation to represent time up to Tue Feb 7 06:28:15 2136 UTC.
00115     */
00116     typedef uint32_t time_t;
00117 
00118     /**
00119     The time function returns the systems current time stamp.
00120     If timer is not a null pointer, the return value is also assigned to the object it points to.
00121     */
00122     time_t          time(time_t *timer);
00123 
00124     /**
00125     The difftime function returns the difference between two binary time stamps,
00126     time1 - time0.
00127     */
00128     int32_t         difftime(time_t time1, time_t time0);
00129 
00130 
00131     /**
00132         The tm structure contains a representation of time 'broken down' into components of the
00133         Gregorian calendar.
00134 
00135         The value of tm_isdst is zero if Daylight Saving Time is not in effect, and is negative if
00136         the information is not available.
00137 
00138         When Daylight Saving Time is in effect, the value represents the number of
00139         seconds the clock is advanced.
00140 
00141         See the set_dst() function for more information about Daylight Saving.
00142 
00143     */
00144     struct tm {
00145         int8_t          tm_sec; /**< seconds after the minute - [ 0 to 59 ] */
00146         int8_t          tm_min; /**< minutes after the hour - [ 0 to 59 ] */
00147         int8_t          tm_hour; /**< hours since midnight - [ 0 to 23 ] */
00148         int8_t          tm_mday; /**< day of the month - [ 1 to 31 ] */
00149         int8_t          tm_wday; /**< days since Sunday - [ 0 to 6 ] */
00150         int8_t          tm_mon; /**< months since January - [ 0 to 11 ] */
00151         int16_t         tm_year; /**< years since 1900 */
00152         int16_t         tm_yday; /**< days since January 1 - [ 0 to 365 ] */
00153         int16_t         tm_isdst; /**< Daylight Saving Time flag */
00154     };
00155 
00156 #ifndef __DOXYGEN__
00157     /* We have to provide clock_t / CLOCKS_PER_SEC so that libstdc++-v3 can
00158        be built.  We define CLOCKS_PER_SEC via a symbol _CLOCKS_PER_SEC_
00159        so that the user can provide the value on the link line, which should
00160        result in little or no run-time overhead compared with a constant.  */
00161     typedef unsigned long clock_t;
00162     extern char *_CLOCKS_PER_SEC_;
00163 #define CLOCKS_PER_SEC ((clock_t) _CLOCKS_PER_SEC_)
00164     extern clock_t clock(void);
00165 #endif  /* !__DOXYGEN__ */
00166 
00167     /**
00168     This function 'compiles' the elements of a broken-down time structure, returning a binary time stamp.
00169     The elements of timeptr are interpreted as representing Local Time.
00170 
00171     The original values of the tm_wday and tm_yday elements of the structure are ignored,
00172     and the original values of the other elements are not restricted to the ranges stated for struct tm.
00173 
00174     On successful completion, the values of all elements of timeptr are set to the appropriate range.
00175     */
00176     time_t          mktime(struct tm * timeptr);
00177 
00178     /**
00179     This function 'compiles' the elements of a broken-down time structure, returning a binary time stamp.
00180     The elements of timeptr are interpreted as representing UTC.
00181 
00182     The original values of the tm_wday and tm_yday elements of the structure are ignored,
00183     and the original values of the other elements are not restricted to the ranges stated for struct tm.
00184 
00185     Unlike mktime(), this function DOES NOT modify the elements of timeptr.
00186     */
00187     time_t          mk_gmtime(const struct tm * timeptr);
00188 
00189     /**
00190     The gmtime function converts the time stamp pointed to by timer into broken-down time,
00191     expressed as UTC.
00192     */
00193     struct tm      *gmtime(const time_t * timer);
00194 
00195     /**
00196         Re entrant version of gmtime().
00197     */
00198     void            gmtime_r(const time_t * timer, struct tm * timeptr);
00199 
00200     /**
00201     The localtime function converts the time stamp pointed to by timer into broken-down time,
00202     expressed as Local time.
00203     */
00204     struct tm      *localtime(const time_t * timer);
00205 
00206     /**
00207         Re entrant version of localtime().
00208     */
00209     void            localtime_r(const time_t * timer, struct tm * timeptr);
00210 
00211     /**
00212     The asctime function converts the broken-down time of timeptr, into an ascii string in the form
00213 
00214         Sun Mar 23 01:03:52 2013
00215     */
00216     char           *asctime(const struct tm * timeptr);
00217 
00218     /**
00219         Re entrant version of asctime().
00220     */
00221     void            asctime_r(const struct tm * timeptr, char *buf);
00222 
00223     /**
00224         The ctime function is equivalent to asctime(localtime(timer))
00225     */
00226     char           *ctime(const time_t * timer);
00227 
00228     /**
00229         Re entrant version of ctime().
00230     */
00231     void            ctime_r(const time_t * timer, char *buf);
00232 
00233     /**
00234     The isotime function constructs an ascii string in the form
00235         \code2013-03-23 01:03:52\endcode
00236     */
00237     char           *isotime(const struct tm * tmptr);
00238 
00239     /**
00240         Re entrant version of isotime()
00241     */
00242     void            isotime_r(const struct tm *, char *);
00243 
00244     /**
00245     A complete description of strftime() is beyond the pale of this document.
00246     Refer to ISO/IEC document 9899 for details.
00247 
00248     All conversions are made using the 'C Locale', ignoring the E or O modifiers. Due to the lack of
00249     a time zone 'name', the 'Z' conversion is also ignored.
00250     */
00251     size_t          strftime(char *s, size_t maxsize, const char *format, const struct tm * timeptr);
00252 
00253     /**
00254         Specify the Daylight Saving function.
00255 
00256         The Daylight Saving function should examine its parameters to determine whether
00257         Daylight Saving is in effect, and return a value appropriate for tm_isdst.
00258 
00259         Working examples for the USA and the EU are available..
00260 
00261             \code #include <util/eu_dst.h>\endcode
00262             for the European Union, and
00263             \code #include <util/usa_dst.h>\endcode
00264             for the United States
00265 
00266         If a Daylight Saving function is not specified, the system will ignore Daylight Saving.
00267     */
00268     void            set_dst(int (*) (const time_t *, int32_t *));
00269 
00270     /**
00271         Set the 'time zone'. The parameter is given in seconds East of the Prime Meridian.
00272         Example for New York City:
00273         \code set_zone(-5 * ONE_HOUR);\endcode
00274 
00275         If the time zone is not set, the time system will operate in UTC only.
00276     */
00277     void            set_zone(int32_t);
00278 
00279     /**
00280         Initialize the system time. Examples are...
00281 
00282         From a Clock / Calendar type RTC:
00283         \code
00284         struct tm rtc_time;
00285 
00286         read_rtc(&rtc_time);
00287         rtc_time.tm_isdst = 0;
00288         set_system_time( mktime(&rtc_time) );
00289         \endcode
00290 
00291         From a Network Time Protocol time stamp:
00292         \code
00293         set_system_time(ntp_timestamp - NTP_OFFSET);
00294         \endcode
00295 
00296         From a UNIX time stamp:
00297          \code
00298         set_system_time(unix_timestamp - UNIX_OFFSET);
00299         \endcode
00300 
00301     */
00302     void            set_system_time(time_t timestamp);
00303 
00304     /**
00305         Maintain the system time by calling this function at a rate of 1 Hertz.
00306 
00307         It is anticipated that this function will typically be called from within an
00308         Interrupt Service Routine, (though that is not required). It therefore includes code which
00309         makes it simple to use from within a 'Naked' ISR, avoiding the cost of saving and restoring
00310         all the cpu registers.
00311 
00312         Such an ISR may resemble the following example...
00313         \code
00314             ISR(RTC_OVF_vect, ISR_NAKED)
00315             {
00316                 system_tick();
00317                 reti();
00318             }
00319         \endcode
00320     */
00321     void            system_tick(void);
00322 
00323     /**
00324         Enumerated labels for the days of the week.
00325     */
00326     enum _WEEK_DAYS_ {
00327         SUNDAY,
00328         MONDAY,
00329         TUESDAY,
00330         WEDNESDAY,
00331         THURSDAY,
00332         FRIDAY,
00333         SATURDAY
00334     };
00335 
00336     /**
00337         Enumerated labels for the months.
00338     */
00339     enum _MONTHS_ {
00340         JANUARY,
00341         FEBRUARY,
00342         MARCH,
00343         APRIL,
00344         MAY,
00345         JUNE,
00346         JULY,
00347         AUGUST,
00348         SEPTEMBER,
00349         OCTOBER,
00350         NOVEMBER,
00351         DECEMBER
00352     };
00353 
00354     /**
00355         Return 1 if year is a leap year, zero if it is not.
00356     */
00357     uint8_t         is_leap_year(int16_t year);
00358 
00359     /**
00360         Return the length of month, given the year and month, where month is in the range 1 to 12.
00361      */
00362     uint8_t         month_length(int16_t year, uint8_t month);
00363 
00364     /**
00365         Return the calendar week of year, where week 1 is considered to begin on the
00366         day of week specified by 'start'. The returned value may range from zero to 52.
00367     */
00368     uint8_t         week_of_year(const struct tm * timeptr, uint8_t start);
00369 
00370     /**
00371         Return the calendar week of month, where the first week is considered to begin on the
00372         day of week specified by 'start'. The returned value may range from zero to 5.
00373     */
00374     uint8_t         week_of_month(const struct tm * timeptr, uint8_t start);
00375 
00376     /**
00377         Structure which represents a date as a year, week number of that year, and day of week.
00378         See http://en.wikipedia.org/wiki/ISO_week_date for more information.
00379     */
00380     struct week_date {
00381         int year; /**< year number (Gregorian calendar) */
00382         int week; /**< week number (#1 is where first Thursday is in) */
00383         int day; /**< day within week */
00384     };
00385 
00386     /**
00387         Return a week_date structure with the ISO_8601 week based date corresponding to the given
00388         year and day of year. See http://en.wikipedia.org/wiki/ISO_week_date for more
00389         information.
00390     */
00391     struct week_date * iso_week_date( int year, int yday);
00392 
00393     /**
00394         Re-entrant version of iso-week_date.
00395     */
00396     void iso_week_date_r( int year, int yday, struct week_date *);
00397 
00398     /**
00399         Convert a Y2K time stamp into a FAT file system time stamp.
00400     */
00401     uint32_t        fatfs_time(const struct tm * timeptr);
00402 
00403     /** One hour, expressed in seconds */
00404 #define ONE_HOUR 3600
00405 
00406     /** Angular degree, expressed in arc seconds */
00407 #define ONE_DEGREE 3600
00408 
00409     /** One day, expressed in seconds */
00410 #define ONE_DAY 86400
00411 
00412     /** Difference between the Y2K and the UNIX epochs, in seconds. To convert a Y2K
00413         timestamp to UNIX...
00414         \code
00415         long unix;
00416         time_t y2k;
00417 
00418         y2k = time(NULL);
00419         unix = y2k + UNIX_OFFSET;
00420         \endcode
00421     */
00422 #define UNIX_OFFSET 946684800
00423 
00424     /** Difference between the Y2K and the NTP epochs, in seconds. To convert a Y2K
00425         timestamp to NTP...
00426         \code
00427         unsigned long ntp;
00428         time_t y2k;
00429 
00430         y2k = time(NULL);
00431         ntp = y2k + NTP_OFFSET;
00432         \endcode
00433     */
00434 #define NTP_OFFSET 3155673600
00435 
00436     /*
00437      * ===================================================================
00438      *                              Ephemera
00439      */
00440 
00441     /**
00442         Set the geographic coordinates of the 'observer', for use with several of the
00443         following functions. Parameters are passed as seconds of North Latitude, and seconds
00444         of East Longitude.
00445 
00446         For New York City...
00447         \code set_position( 40.7142 * ONE_DEGREE, -74.0064 * ONE_DEGREE); \endcode
00448     */
00449     void            set_position(int32_t latitude, int32_t longitude);
00450 
00451     /**
00452         Computes the difference between apparent solar time and mean solar time.
00453         The returned value is in seconds.
00454     */
00455     int16_t         equation_of_time(const time_t * timer);
00456 
00457     /**
00458         Computes the amount of time the sun is above the horizon, at the location of the observer.
00459 
00460         NOTE: At observer locations inside a polar circle, this value can be zero during the winter,
00461         and can exceed ONE_DAY during the summer.
00462 
00463         The returned value is in seconds.
00464     */
00465     int32_t         daylight_seconds(const time_t * timer);
00466 
00467     /**
00468         Computes the time of solar noon, at the location of the observer.
00469     */
00470     time_t          solar_noon(const time_t * timer);
00471 
00472     /**
00473         Return the time of sunrise, at the location of the observer. See the note about daylight_seconds().
00474     */
00475     time_t          sun_rise(const time_t * timer);
00476 
00477     /**
00478         Return the time of sunset, at the location of the observer. See the note about daylight_seconds().
00479     */
00480     time_t          sun_set(const time_t * timer);
00481 
00482     /** Returns the declination of the sun in radians. */
00483     double          solar_declination(const time_t * timer);
00484 
00485     /**
00486         Returns an approximation to the phase of the moon.
00487         The sign of the returned value indicates a waning or waxing phase.
00488         The magnitude of the returned value indicates the percentage illumination.
00489     */
00490     int8_t          moon_phase(const time_t * timer);
00491 
00492     /**
00493         Returns Greenwich Mean Sidereal Time, as seconds into the sidereal day.
00494         The returned value will range from 0 through 86399 seconds.
00495     */
00496     unsigned long   gm_sidereal(const time_t * timer);
00497 
00498     /**
00499         Returns Local Mean Sidereal Time, as seconds into the sidereal day.
00500         The returned value will range from 0 through 86399 seconds.
00501     */
00502     unsigned long   lm_sidereal(const time_t * timer);
00503 
00504     /* @} */
00505 #ifdef __cplusplus
00506 }
00507 #endif
00508 
00509 #endif              /* TIME_H  */
 All Data Structures Files Functions Variables Typedefs Enumerations Defines