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

📄 prtime.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//*  * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is the Netscape Portable Runtime (NSPR). *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 1998-2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. *//* * prtime.c -- * *     NSPR date and time functions * */#include "prinit.h"#include "prtime.h"#include "prlock.h"#include "prprf.h"#include "prlog.h"#include <string.h>#include <ctype.h>#ifdef XP_MAC#include <time.h>#endif/* * Static variables used by functions in this file *//* * The following array contains the day of year for the last day of * each month, where index 1 is January, and day 0 is January 1. */static const int lastDayOfMonth[2][13] = {    {-1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364},    {-1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}};/* * The number of days in a month */static const PRInt8 nDays[2][12] = {    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},    {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};/* * Declarations for internal functions defined later in this file. */static void        ComputeGMT(PRTime time, PRExplodedTime *gmt);static int        IsLeapYear(PRInt16 year);static void        ApplySecOffset(PRExplodedTime *time, PRInt32 secOffset);/* *------------------------------------------------------------------------ * * ComputeGMT -- * *     Caveats: *     - we ignore leap seconds *     - our leap-year calculation is only correct for years 1901-2099 * *------------------------------------------------------------------------ */static voidComputeGMT(PRTime time, PRExplodedTime *gmt){    PRInt32 tmp, rem;    PRInt32 numDays;    PRInt64 numDays64, rem64;    int isLeap;    PRInt64 sec;    PRInt64 usec;    PRInt64 usecPerSec;    PRInt64 secPerDay;    /*     * We first do the usec, sec, min, hour thing so that we do not     * have to do LL arithmetic.     */    LL_I2L(usecPerSec, 1000000L);    LL_DIV(sec, time, usecPerSec);    LL_MOD(usec, time, usecPerSec);    LL_L2I(gmt->tm_usec, usec);    /* Correct for weird mod semantics so the remainder is always positive */    if (gmt->tm_usec < 0) {        PRInt64 one;        LL_I2L(one, 1L);        LL_SUB(sec, sec, one);        gmt->tm_usec += 1000000L;    }    LL_I2L(secPerDay, 86400L);    LL_DIV(numDays64, sec, secPerDay);    LL_MOD(rem64, sec, secPerDay);    /* We are sure both of these numbers can fit into PRInt32 */    LL_L2I(numDays, numDays64);    LL_L2I(rem, rem64);    if (rem < 0) {        numDays--;        rem += 86400L;    }    /* Compute day of week.  Epoch started on a Thursday. */    gmt->tm_wday = (numDays + 4) % 7;    if (gmt->tm_wday < 0) {        gmt->tm_wday += 7;    }    /* Compute the time of day. */        gmt->tm_hour = rem / 3600;    rem %= 3600;    gmt->tm_min = rem / 60;    gmt->tm_sec = rem % 60;    /* Compute the four-year span containing the specified time */    tmp = numDays / (4 * 365 + 1);    rem = numDays % (4 * 365 + 1);    if (rem < 0) {        tmp--;        rem += (4 * 365 + 1);    }    /*     * Compute the year after 1900 by taking the four-year span and     * adjusting for the remainder.  This works because 2000 is a      * leap year, and 1900 and 2100 are out of the range.     */        tmp = (tmp * 4) + 1970;    isLeap = 0;    /*     * 1970 has 365 days     * 1971 has 365 days     * 1972 has 366 days (leap year)     * 1973 has 365 days     */    if (rem >= 365) {                                /* 1971, etc. */        tmp++;        rem -= 365;        if (rem >= 365) {                        /* 1972, etc. */            tmp++;            rem -= 365;            if (rem >= 366) {                        /* 1973, etc. */                tmp++;                rem -= 366;            } else {                isLeap = 1;            }        }    }    gmt->tm_year = tmp;    gmt->tm_yday = rem;    /* Compute the month and day of month. */    for (tmp = 1; lastDayOfMonth[isLeap][tmp] < gmt->tm_yday; tmp++) {    }    gmt->tm_month = --tmp;    gmt->tm_mday = gmt->tm_yday - lastDayOfMonth[isLeap][tmp];    gmt->tm_params.tp_gmt_offset = 0;    gmt->tm_params.tp_dst_offset = 0;}/* *------------------------------------------------------------------------ * * PR_ExplodeTime -- * *     Cf. struct tm *gmtime(const time_t *tp) and *         struct tm *localtime(const time_t *tp) * *------------------------------------------------------------------------ */PR_IMPLEMENT(void)PR_ExplodeTime(        PRTime usecs,        PRTimeParamFn params,        PRExplodedTime *exploded){    ComputeGMT(usecs, exploded);    exploded->tm_params = params(exploded);    ApplySecOffset(exploded, exploded->tm_params.tp_gmt_offset            + exploded->tm_params.tp_dst_offset);}/* *------------------------------------------------------------------------ * * PR_ImplodeTime -- * *     Cf. time_t mktime(struct tm *tp) *     Note that 1 year has < 2^25 seconds.  So an PRInt32 is large enough. * *------------------------------------------------------------------------ */#if defined(HAVE_WATCOM_BUG_2)PRTime __pascal __export __loadds#elsePR_IMPLEMENT(PRTime)#endifPR_ImplodeTime(const PRExplodedTime *exploded){    PRExplodedTime copy;    PRTime retVal;    PRInt64 secPerDay, usecPerSec;    PRInt64 temp;    PRInt64 numSecs64;    PRInt32 fourYears;    PRInt32 remainder;    PRInt32 numDays;    PRInt32 numSecs;    /* Normalize first.  Do this on our copy */    copy = *exploded;    PR_NormalizeTime(&copy, PR_GMTParameters);    fourYears = (copy.tm_year - 1970) / 4;    remainder = (copy.tm_year - 1970) % 4;    if (remainder < 0) {        remainder += 4;        fourYears--;    }    numDays = fourYears * (4 * 365 + 1);    switch (remainder) {        case 0:            break;        case 1:  /* 1970 */            numDays += 365;            break;        case 2:  /* 1970-1 */            numDays += 365 * 2;            break;        case 3:  /* 1970-2 */            numDays += 365 * 3 + 1;            break;    }    numSecs = copy.tm_yday * 86400 + copy.tm_hour * 3600            + copy.tm_min * 60 + copy.tm_sec;    LL_I2L(temp, numDays);    LL_I2L(secPerDay, 86400);    LL_MUL(temp, temp, secPerDay);    LL_I2L(numSecs64, numSecs);    LL_ADD(numSecs64, numSecs64, temp);    /* apply the GMT and DST offsets */    LL_I2L(temp,  copy.tm_params.tp_gmt_offset);    LL_SUB(numSecs64, numSecs64, temp);    LL_I2L(temp,  copy.tm_params.tp_dst_offset);    LL_SUB(numSecs64, numSecs64, temp);    LL_I2L(usecPerSec, 1000000L);    LL_MUL(temp, numSecs64, usecPerSec);    LL_I2L(retVal, copy.tm_usec);    LL_ADD(retVal, retVal, temp);    return retVal;}/* *------------------------------------------------------------------------- * * IsLeapYear -- * *     Returns 1 if the year is a leap year, 0 otherwise. * *------------------------------------------------------------------------- */static int IsLeapYear(PRInt16 year){    if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)        return 1;    else        return 0;}/* * 'secOffset' should be less than 86400 (i.e., a day). * 'time' should point to a normalized PRExplodedTime. */static voidApplySecOffset(PRExplodedTime *time, PRInt32 secOffset){    time->tm_sec += secOffset;    /* Note that in this implementation we do not count leap seconds */    if (time->tm_sec < 0 || time->tm_sec >= 60) {        time->tm_min += time->tm_sec / 60;        time->tm_sec %= 60;        if (time->tm_sec < 0) {            time->tm_sec += 60;            time->tm_min--;        }    }    if (time->tm_min < 0 || time->tm_min >= 60) {        time->tm_hour += time->tm_min / 60;        time->tm_min %= 60;        if (time->tm_min < 0) {            time->tm_min += 60;            time->tm_hour--;        }    }    if (time->tm_hour < 0) {        /* Decrement mday, yday, and wday */        time->tm_hour += 24;        time->tm_mday--;        time->tm_yday--;        if (time->tm_mday < 1) {            time->tm_month--;            if (time->tm_month < 0) {                time->tm_month = 11;                time->tm_year--;                if (IsLeapYear(time->tm_year))                    time->tm_yday = 365;                else                    time->tm_yday = 364;

⌨️ 快捷键说明

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