📄 tclwintime.c
字号:
/* * tclWinTime.c -- * * Contains Windows specific versions of Tcl functions that * obtain time values from the operating system. * * Copyright 1995 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tclWinTime.c 1.6 97/04/14 17:25:56 */#include "tclInt.h"#include "tclPort.h"#define SECSPERDAY (60L * 60L * 24L)#define SECSPERYEAR (SECSPERDAY * 365L)#define SECSPER4YEAR (SECSPERYEAR * 4L + SECSPERDAY)/* * The following arrays contain the day of year for the last day of * each month, where index 1 is January. */static int normalDays[] = { -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364};static int leapDays[] = { -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};/* * Declarations for functions defined later in this file. */static struct tm * ComputeGMT _ANSI_ARGS_((const time_t *tp));/* *---------------------------------------------------------------------- * * TclpGetSeconds -- * * This procedure returns the number of seconds from the epoch. * On most Unix systems the epoch is Midnight Jan 1, 1970 GMT. * * Results: * Number of seconds from the epoch. * * Side effects: * None. * *---------------------------------------------------------------------- */unsigned longTclpGetSeconds(){ return (unsigned long) time((time_t *) NULL);}/* *---------------------------------------------------------------------- * * TclpGetClicks -- * * This procedure returns a value that represents the highest * resolution clock available on the system. There are no * guarantees on what the resolution will be. In Tcl we will * call this value a "click". The start time is also system * dependant. * * Results: * Number of clicks from some start time. * * Side effects: * None. * *---------------------------------------------------------------------- */unsigned longTclpGetClicks(){ return GetTickCount();}/* *---------------------------------------------------------------------- * * TclpGetTimeZone -- * * Determines the current timezone. The method varies wildly * between different Platform implementations, so its hidden in * this function. * * Results: * Minutes west of GMT. * * Side effects: * None. * *---------------------------------------------------------------------- */intTclpGetTimeZone (currentTime) unsigned long currentTime;{ int timeZone; tzset(); timeZone = _timezone / 60; return timeZone;}/* *---------------------------------------------------------------------- * * TclpGetTime -- * * Gets the current system time in seconds and microseconds * since the beginning of the epoch: 00:00 UCT, January 1, 1970. * * Results: * Returns the current time in timePtr. * * Side effects: * None. * *---------------------------------------------------------------------- */voidTclpGetTime(timePtr) Tcl_Time *timePtr; /* Location to store time information. */{ struct timeb t; ftime(&t); timePtr->sec = t.time; timePtr->usec = t.millitm * 1000;}/* *---------------------------------------------------------------------- * * TclpGetTZName -- * * Gets the current timezone string. * * Results: * Returns a pointer to a static string, or NULL on failure. * * Side effects: * None. * *---------------------------------------------------------------------- */char *TclpGetTZName(){ tzset(); if (_daylight && _tzname[1] != NULL) { return _tzname[1]; } else { return _tzname[0]; }}/* *---------------------------------------------------------------------- * * TclpGetDate -- * * This function converts between seconds and struct tm. If * useGMT is true, then the returned date will be in Greenwich * Mean Time (GMT). Otherwise, it will be in the local time zone. * * Results: * Returns a static tm structure. * * Side effects: * None. * *---------------------------------------------------------------------- */struct tm *TclpGetDate(tp, useGMT) const time_t *tp; int useGMT;{ struct tm *tmPtr; long time; if (!useGMT) { tzset(); /* * If we are in the valid range, let the C run-time library * handle it. Otherwise we need to fake it. Note that this * algorithm ignores daylight savings time before the epoch. */ time = *tp - _timezone; if (time >= 0) { return localtime(tp); } /* * If we aren't near to overflowing the long, just add the bias and * use the normal calculation. Otherwise we will need to adjust * the result at the end. */ if (*tp < (LONG_MAX - 2 * SECSPERDAY) && *tp > (LONG_MIN + 2 * SECSPERDAY)) { tmPtr = ComputeGMT(&time); } else { tmPtr = ComputeGMT(tp); tzset(); /* * Add the bias directly to the tm structure to avoid overflow. * Propagate seconds overflow into minutes, hours and days. */ time = tmPtr->tm_sec - _timezone; tmPtr->tm_sec = (int)(time % 60); if (tmPtr->tm_sec < 0) { tmPtr->tm_sec += 60; time -= 60; } time = tmPtr->tm_min + time/60; tmPtr->tm_min = (int)(time % 60); if (tmPtr->tm_min < 0) { tmPtr->tm_min += 60; time -= 60; } time = tmPtr->tm_hour + time/60; tmPtr->tm_hour = (int)(time % 24); if (tmPtr->tm_hour < 0) { tmPtr->tm_hour += 24; time -= 24; } time /= 24; tmPtr->tm_mday += time; tmPtr->tm_yday += time; tmPtr->tm_wday = (tmPtr->tm_wday + time) % 7; } } else { tmPtr = ComputeGMT(tp); } return tmPtr;}/* *---------------------------------------------------------------------- * * ComputeGMT -- * * This function computes GMT given the number of seconds since * the epoch (midnight Jan 1 1970). * * Results: * Returns a statically allocated struct tm. * * Side effects: * Updates the values of the static struct tm. * *---------------------------------------------------------------------- */static struct tm *ComputeGMT(tp) const time_t *tp;{ static struct tm tm; /* This should be allocated per thread.*/ long tmp, rem; int isLeap; int *days; /* * Compute the 4 year span containing the specified time. */ tmp = *tp / SECSPER4YEAR; rem = *tp % SECSPER4YEAR; /* * Correct for weird mod semantics so the remainder is always positive. */ if (rem < 0) { tmp--; rem += SECSPER4YEAR; } /* * Compute the year after 1900 by taking the 4 year span and adjusting * for the remainder. This works because 2000 is a leap year, and * 1900/2100 are out of the range. */ tmp = (tmp * 4) + 70; isLeap = 0; if (rem >= SECSPERYEAR) { /* 1971, etc. */ tmp++; rem -= SECSPERYEAR; if (rem >= SECSPERYEAR) { /* 1972, etc. */ tmp++; rem -= SECSPERYEAR; if (rem >= SECSPERYEAR + SECSPERDAY) { /* 1973, etc. */ tmp++; rem -= SECSPERYEAR + SECSPERDAY; } else { isLeap = 1; } } } tm.tm_year = tmp; /* * Compute the day of year and leave the seconds in the current day in * the remainder. */ tm.tm_yday = rem / SECSPERDAY; rem %= SECSPERDAY; /* * Compute the time of day. */ tm.tm_hour = rem / 3600; rem %= 3600; tm.tm_min = rem / 60; tm.tm_sec = rem % 60; /* * Compute the month and day of month. */ days = (isLeap) ? leapDays : normalDays; for (tmp = 1; days[tmp] < tm.tm_yday; tmp++) { } tm.tm_mon = --tmp; tm.tm_mday = tm.tm_yday - days[tmp]; /* * Compute day of week. Epoch started on a Thursday. */ tm.tm_wday = (*tp / SECSPERDAY) + 4; if ((*tp % SECSPERDAY) < 0) { tm.tm_wday--; } tm.tm_wday %= 7; if (tm.tm_wday < 0) { tm.tm_wday += 7; } return &tm;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -