⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tzset.c

📁 C语言库函数的原型,有用的拿去
💻 C
📖 第 1 页 / 共 2 页
字号:
/***
*tzset.c - set timezone information and see if we're in daylight time
*
*       Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
*       defines _tzset() - set timezone and daylight saving time vars
*
*******************************************************************************/

#include <cruntime.h>
#include <ctype.h>
#include <ctime.h>
#include <time.h>
#include <stdlib.h>
#include <internal.h>
#include <mtdll.h>
#include <windows.h>
#include <setlocal.h>
#include <string.h>
#include <dbgint.h>



/*
 * Number of milliseconds in one day
 */
#define DAY_MILLISEC    (24 * 60 * 60 * 1000)

/*
 * Pointer to a saved copy of the TZ value obtained in the previous call
 * to tzset() set (if any).
 */
static char * lastTZ = NULL;

/*
 * Flag indicating that time zone information came from GetTimeZoneInformation
 * API call.
 */
static int tzapiused;

static TIME_ZONE_INFORMATION tzinfo;

/*
 * Structure used to represent DST transition date/times.
 */
typedef struct {
        int  yr;        /* year of interest */
        int  yd;        /* day of year */
        int  ms;        /* milli-seconds in the day */
        } transitiondate;

/*
 * DST start and end structs.
 */
static transitiondate dststart = { -1, 0, 0 };
static transitiondate dstend   = { -1, 0, 0 };

static int __cdecl _isindst_nolock(struct tm *);



/***
*void tzset() - sets timezone information and calc if in daylight time
*
*Purpose:
*       Sets the timezone information from the TZ environment variable
*       and then sets _timezone, _daylight, and _tzname. If we're in daylight
*       time is automatically calculated.
*
*Entry:
*       None, reads TZ environment variable.
*
*Exit:
*       sets _daylight, _timezone, and _tzname global vars, no return value
*
*Exceptions:
*
*******************************************************************************/


static void __cdecl _tzset_nolock(void);

void __cdecl __tzset(void)
{
        static int first_time = 0;

        if ( !first_time ) {

            _mlock( _TIME_LOCK );
            __TRY

                if ( !first_time ) {
                    _tzset_nolock();
                    first_time++;
                }

            __FINALLY
                _munlock(_TIME_LOCK );
            __END_TRY_FINALLY

        }
}


void __cdecl _tzset (
        void
        )
{
        _mlock( _TIME_LOCK );
        __TRY

            _tzset_nolock();

        __FINALLY
            _munlock( _TIME_LOCK );
        __END_TRY_FINALLY
}


static void __cdecl _tzset_nolock (
        void
        )
{
    const char *TZ;
    int defused;
    int negdiff = 0;
    unsigned int lc_cp;
        int nochange=FALSE;
    long timezone = 0;
    int daylight = 0;
    long dstbias = 0;
    char **tzname = NULL;

    _mlock(_ENV_LOCK);
    __TRY

_BEGIN_SECURE_CRT_DEPRECATION_DISABLE
        tzname = _tzname;
_END_SECURE_CRT_DEPRECATION_DISABLE

        _ERRCHECK(_get_timezone(&timezone));
        _ERRCHECK(_get_daylight(&daylight));
        _ERRCHECK(_get_dstbias(&dstbias));

        /*
         * Copy codepage to local (only really necessary for multithread case)
         */
        lc_cp = ___lc_codepage_func();

        /*
         * Clear the flag indicated whether GetTimeZoneInformation was used.
         */
        tzapiused = 0;

        /*
         * Set year fields of dststart and dstend structures to -1 to ensure
         * they are recomputed as after this
         */
        dststart.yr = dstend.yr = -1;

        /*
         * Fetch the value of the TZ environment variable.
         */
        if ( ((TZ = _getenv_helper_nolock("TZ")) == NULL) || (*TZ =='\0') ) {
            /*
             * There is no TZ environment variable, try to use the time zone
             * information from the system.
             */

            /*
             * If there is a lastTZ, discard it
             */
            if ( lastTZ != NULL ) {
                _free_crt(lastTZ);
                lastTZ = NULL;
            }

            if ( GetTimeZoneInformation( &tzinfo ) != 0xFFFFFFFF ) {
                /*
                 * Note that the API was used.
                 */
                tzapiused = 1;

                /*
                 * Derive _timezone value from Bias and StandardBias fields.
                 */
                timezone = tzinfo.Bias * 60;

                if ( tzinfo.StandardDate.wMonth != 0 )
                    timezone += (tzinfo.StandardBias * 60);

                /*
                 * Check to see if there is a daylight time bias. Since the
                 * StandardBias has been added into _timezone, it must be
                 * compensated for in the value computed for _dstbias.
                 */
                if ( (tzinfo.DaylightDate.wMonth != 0) &&
                     (tzinfo.DaylightBias != 0) )
                {
                    daylight = 1;
                    dstbias = (tzinfo.DaylightBias - tzinfo.StandardBias) *
                               60;
                }
                else {
                        daylight = 0;

                    /*
                     * Set daylight bias to 0 because GetTimeZoneInformation
                     * may return TIME_ZONE_ID_DAYLIGHT even though there is
                     * no DST (in NT 3.51, just turn off the automatic DST
                     * adjust in the control panel)!
                     */
                    dstbias = 0;
                }

                /*
                 * Try to grab the name strings for both the time zone and the
                 * daylight zone. Note the wide character strings in tzinfo
                 * must be converted to multibyte characters strings. The
                 * locale codepage, __lc_codepage, is used for this. Note that
                 * if setlocale() with LC_ALL or LC_CTYPE has not been called,
                 * then __lc_codepage will be 0 (_CLOCALECP), which is CP_ACP
                 * (which means use the host's default ANSI codepage).
                 */
                if ( (WideCharToMultiByte( lc_cp,
                                           0,
                                           tzinfo.StandardName,
                                           -1,
                                           tzname[0],
                                           _TZ_STRINGS_SIZE - 1,
                                           NULL,
                                           &defused ) != 0) &&
                     (!defused) )
                    tzname[0][_TZ_STRINGS_SIZE - 1] = '\0';
                else
                    tzname[0][0] = '\0';

                if ( (WideCharToMultiByte( lc_cp,
                                           0,
                                           tzinfo.DaylightName,
                                           -1,
                                           tzname[1],
                                           _TZ_STRINGS_SIZE - 1,
                                           NULL,
                                           &defused ) != 0) &&
                     (!defused) )
                    tzname[1][_TZ_STRINGS_SIZE - 1] = '\0';
                else
                    tzname[1][0] = '\0';
            }

            /*
             * Time zone information is unavailable, just return.
             */
            nochange=TRUE;
        }
                else
                {
                        if ( (lastTZ != NULL) && (strcmp(TZ, lastTZ) == 0) )
                        {
                                /*
                                * TZ is unchanged from a earlier call (to this function). Just
                                * return.
                                */
                                nochange=TRUE;
                        }
                        else
                        {

                                /*
                                * Update lastTZ
                                */
                                if ( lastTZ != NULL )
                                        _free_crt(lastTZ);

                                if ((lastTZ = _malloc_crt(strlen(TZ)+1)) == NULL)
                                {
                                        nochange=TRUE;
                                }
                                else
                                {
                                        _ERRCHECK(strcpy_s(lastTZ, strlen(TZ) + 1, TZ));
                                }
                        }
                }

                _set_timezone(timezone);
                _set_daylight(daylight);
                _set_dstbias(dstbias);

    __FINALLY
        _munlock(_ENV_LOCK);
    __END_TRY_FINALLY

        if(!nochange)
        {
                /*
                * Process TZ value and update _tzname, _timezone and _daylight.
                */
                _ERRCHECK(strncpy_s(tzname[0], _TZ_STRINGS_SIZE, TZ, 3));

                /*
                * time difference is of the form:
                *
                *      [+|-]hh[:mm[:ss]]
                *
                * check minus sign first.
                */
                if ( *(TZ += 3) == '-' ) {
                        negdiff++;
                        TZ++;
                }

                /*
                * process, then skip over, the hours
                */
                timezone = atol(TZ) * 3600;

                while ( (*TZ == '+') || ((*TZ >= '0') && (*TZ <= '9')) ) TZ++;

                /*
                * check if minutes were specified
                */
                if ( *TZ == ':' ) {
                        /*
                        * process, then skip over, the minutes
                        */
                        timezone += atol(++TZ) * 60;
                        while ( (*TZ >= '0') && (*TZ <= '9') ) TZ++;

                        /*
                        * check if seconds were specified
                        */
                        if ( *TZ == ':' ) {
                                /*
                                * process, then skip over, the seconds
                                */
                                timezone += atol(++TZ);
                                while ( (*TZ >= '0') && (*TZ <= '9') ) TZ++;
                        }
                }

                if ( negdiff )
                        timezone = -timezone;

                /*
                * finally, check for a DST zone suffix
                */
                daylight = *TZ;
                if ( daylight ) {
                        _ERRCHECK(strncpy_s(tzname[1], _TZ_STRINGS_SIZE, TZ, 3));
                }
                else
                        *tzname[1] = '\0';

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -