| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- /*
- * Copyright (C) 2001-2003 by egnite Software GmbH. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * For additional information see http://www.ethernut.de/
- *
- * Portions of the following functions are derived from material which is
- * Copyright (c) 1985 by Microsoft Corporation. All rights are reserved.
- */
- /*
- * $Log$
- * Revision 1.3 2008/08/11 06:59:41 haraldkipp
- * BSD types replaced by stdint types (feature request #1282721).
- *
- * Revision 1.2 2003/12/19 22:26:38 drsung
- * Dox written.
- *
- * Revision 1.1 2003/11/24 18:07:37 drsung
- * first release
- *
- *
- */
- #include <stdint.h>
- #include <time.h>
- #include "ctime.h"
- typedef struct {
- int yr; /* year of interest */
- int yd; /* day of year */
- long ms; /* milli-seconds in the day */
- } transitiondate;
- /*
- * DST start and end structs.
- */
- static transitiondate dststart = { -1, 0, 0L };
- static transitiondate dstend = { -1, 0, 0L };
- int _daylight = 1; /* daylight saving default enabled */
- long _dstbias = -1 * 60L * 60L; /* bias for daylight saving in seconds */
- long _timezone = 5L * 60L * 60L; /* default time zone is EST = -05:00:00 */
- /*
- * The macro below is valid for years between 1901 and 2099, which easily
- * includes all years representable by the current implementation of time_t.
- */
- #define IS_LEAP_YEAR(year) ( (year & 3) == 0 )
- #define DAY_MILLISEC (24L * 60L * 60L * 1000L)
- static void cvtdate(int trantype,
- int datetype, int year, int month, int week, int dayofweek, int date, int hour, int min, int sec, int msec)
- {
- int yearday;
- int monthdow;
- if (datetype == 1) {
- /*
- * Transition day specified in day-in-month format.
- */
- /*
- * Figure the year-day of the start of the month.
- */
- yearday = 1 + (IS_LEAP_YEAR(year) ? _lpdays[month - 1] : _days[month - 1]);
- /*
- * Figure the day of the week of the start of the month.
- */
- monthdow = (yearday + ((year - 70) * 365) + ((year - 1) >> 2) - _LEAP_YEAR_ADJUST + _BASE_DOW) % 7;
- /*
- * Figure the year-day of the transition date
- */
- if (monthdow <= dayofweek)
- yearday += (dayofweek - monthdow) + (week - 1) * 7;
- else
- yearday += (dayofweek - monthdow) + week * 7;
- /*
- * May have to adjust the calculation above if week == 5 (meaning
- * the last instance of the day in the month). Check if year falls
- * beyond after month and adjust accordingly.
- */
- if ((week == 5) && (yearday > (IS_LEAP_YEAR(year) ? _lpdays[month] : _days[month]))) {
- yearday -= 7;
- }
- } else {
- /*
- * Transition day specified as an absolute day
- */
- yearday = IS_LEAP_YEAR(year) ? _lpdays[month - 1] : _days[month - 1];
- yearday += date;
- }
- if (trantype == 1) {
- /*
- * Converted date was for the start of DST
- */
- dststart.yd = yearday;
- dststart.ms = (long) msec + (1000L * (sec + 60L * (min + 60L * hour)));
- /*
- * Set year field of dststart so that unnecessary calls to
- * cvtdate() may be avoided.
- */
- dststart.yr = year;
- } else {
- /*
- * Converted date was for the end of DST
- */
- dstend.yd = yearday;
- dstend.ms = (long) msec + (1000L * (sec + 60L * (min + 60L * hour)));
- /*
- * The converted date is still a DST date. Must convert to a
- * standard (local) date while being careful the millisecond field
- * does not overflow or underflow.
- */
- if ((dstend.ms += (_dstbias * 1000L)) < 0) {
- dstend.ms += DAY_MILLISEC;
- dstend.yd--;
- } else if (dstend.ms >= DAY_MILLISEC) {
- dstend.ms -= DAY_MILLISEC;
- dstend.yd++;
- }
- /*
- * Set year field of dstend so that unnecessary calls to cvtdate()
- * may be avoided.
- */
- dstend.yr = year;
- }
- return;
- }
- int _isindst(tm * tb)
- {
- long ms;
- if (_daylight == 0)
- return 0;
- /*
- * Compute (recompute) the transition dates for daylight saving time
- * if necessary.The yr (year) fields of dststart and dstend is
- * compared to the year of interest to determine necessity.
- */
- if ((tb->tm_year != dststart.yr) || (tb->tm_year != dstend.yr)) {
- cvtdate(1, 1, tb->tm_year, 3, /* March */
- 5, /* last... */
- 0, /* ...Sunday */
- 0, 2, /* 02:00 (2 AM) */
- 0, 0, 0);
- cvtdate(0, 1, tb->tm_year, 10, /* October */
- 5, /* last... */
- 0, /* ...Sunday */
- 0, 2, /* 02:00 (2 AM) */
- 0, 0, 0);
- }
- /*
- * Handle simple cases first.
- */
- if (dststart.yd < dstend.yd) {
- /*
- * Northern hemisphere ordering
- */
- if ((tb->tm_yday < dststart.yd) || (tb->tm_yday > dstend.yd))
- return 0;
- if ((tb->tm_yday > dststart.yd) && (tb->tm_yday < dstend.yd))
- return 1;
- } else {
- /*
- * Southern hemisphere ordering
- */
- if ((tb->tm_yday < dstend.yd) || (tb->tm_yday > dststart.yd))
- return 1;
- if ((tb->tm_yday > dstend.yd) && (tb->tm_yday < dststart.yd))
- return 0;
- }
- ms = 1000L * (tb->tm_sec + 60L * tb->tm_min + 3600L * tb->tm_hour);
- if (tb->tm_yday == dststart.yd) {
- if (ms >= dststart.ms)
- return 1;
- else
- return 0;
- } else {
- if (ms < dstend.ms)
- return 1;
- else
- return 0;
- }
- }
|