📄 prmjtime.c
字号:
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * 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 Mozilla Communicator client code, released * March 31, 1998. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** *//* * PR time code. */#include "jsstddef.h"#ifdef SOLARIS#define _REENTRANT 1#endif#include <string.h>#include <time.h>#include "jstypes.h"#include "jsutil.h"#include "jsprf.h"#include "prmjtime.h"#define PRMJ_DO_MILLISECONDS 1#ifdef XP_OS2#include <sys/timeb.h>#endif#ifdef XP_WIN#include <windef.h>#include <winbase.h>#endif#ifdef XP_MAC#include <OSUtils.h>#include <TextUtils.h>#include <Resources.h>#include <Timer.h>#include <UTCUtils.h>#include <Power.h>#include <CodeFragments.h>#if !TARGET_CARBON#include <Traps.h>#endif#endif#if defined(XP_UNIX) || defined(XP_BEOS)#ifdef _SVID_GETTOD /* Defined only on Solaris, see Solaris <sys/types.h> */extern int gettimeofday(struct timeval *tv);#endif#include <sys/time.h>#endif /* XP_UNIX */#ifdef XP_MACstatic uint64 dstLocalBaseMicroseconds;static unsigned long gJanuaryFirst1970Seconds;static void MacintoshInitializeTime(void){ uint64 upTime; unsigned long currentLocalTimeSeconds, startupTimeSeconds; uint64 startupTimeMicroSeconds; uint32 upTimeSeconds; uint64 oneMillion, upTimeSecondsLong, microSecondsToSeconds; DateTimeRec firstSecondOfUnixTime; /* * Figure out in local time what time the machine started up. This information can be added to * upTime to figure out the current local time as well as GMT. */ Microseconds((UnsignedWide*)&upTime); GetDateTime(¤tLocalTimeSeconds); JSLL_I2L(microSecondsToSeconds, PRMJ_USEC_PER_SEC); JSLL_DIV(upTimeSecondsLong, upTime, microSecondsToSeconds); JSLL_L2I(upTimeSeconds, upTimeSecondsLong); startupTimeSeconds = currentLocalTimeSeconds - upTimeSeconds; /* Make sure that we normalize the macintosh base seconds to the unix base of January 1, 1970. */ firstSecondOfUnixTime.year = 1970; firstSecondOfUnixTime.month = 1; firstSecondOfUnixTime.day = 1; firstSecondOfUnixTime.hour = 0; firstSecondOfUnixTime.minute = 0; firstSecondOfUnixTime.second = 0; firstSecondOfUnixTime.dayOfWeek = 0; DateToSeconds(&firstSecondOfUnixTime, &gJanuaryFirst1970Seconds); startupTimeSeconds -= gJanuaryFirst1970Seconds; /* Now convert the startup time into a wide so that we can figure out GMT and DST. */ JSLL_I2L(startupTimeMicroSeconds, startupTimeSeconds); JSLL_I2L(oneMillion, PRMJ_USEC_PER_SEC); JSLL_MUL(dstLocalBaseMicroseconds, oneMillion, startupTimeMicroSeconds);}static SleepQRec gSleepQEntry = { NULL, sleepQType, NULL, 0 };static JSBool gSleepQEntryInstalled = JS_FALSE;static pascal long MySleepQProc(long message, SleepQRecPtr sleepQ){ /* just woke up from sleeping, so must recompute dstLocalBaseMicroseconds. */ if (message == kSleepWakeUp) MacintoshInitializeTime(); return 0;}/* Because serial port and SLIP conflict with ReadXPram calls, * we cache the call here */static void MyReadLocation(MachineLocation * loc){ static MachineLocation storedLoc; /* InsideMac, OSUtilities, page 4-20 */ static JSBool didReadLocation = JS_FALSE; if (!didReadLocation) { MacintoshInitializeTime(); ReadLocation(&storedLoc); /* install a sleep queue routine, so that when the machine wakes up, time can be recomputed. */ if (&SleepQInstall != (void*)kUnresolvedCFragSymbolAddress#if !TARGET_CARBON && NGetTrapAddress(0xA28A, OSTrap) != NGetTrapAddress(_Unimplemented, ToolTrap)#endif ) { if ((gSleepQEntry.sleepQProc = NewSleepQUPP(MySleepQProc)) != NULL) { SleepQInstall(&gSleepQEntry); gSleepQEntryInstalled = JS_TRUE; } } didReadLocation = JS_TRUE; } *loc = storedLoc;}#ifndef XP_MACOSX/* CFM library init and terminate routines. We'll use the terminate routine to clean up the sleep Q entry. On Mach-O, the sleep Q entry gets cleaned up for us, so nothing to do there.*/extern pascal OSErr __NSInitialize(const CFragInitBlock* initBlock);extern pascal void __NSTerminate();pascal OSErr __JSInitialize(const CFragInitBlock* initBlock);pascal void __JSTerminate(void);pascal OSErr __JSInitialize(const CFragInitBlock* initBlock){ return __NSInitialize(initBlock);}pascal void __JSTerminate(){ /* clean up the sleepQ entry */ if (gSleepQEntryInstalled) SleepQRemove(&gSleepQEntry); __NSTerminate();}#endif /* XP_MACOSX */#endif /* XP_MAC */#define IS_LEAP(year) \ (year != 0 && ((((year & 0x3) == 0) && \ ((year - ((year/100) * 100)) != 0)) || \ (year - ((year/400) * 400)) == 0))#define PRMJ_HOUR_SECONDS 3600L#define PRMJ_DAY_SECONDS (24L * PRMJ_HOUR_SECONDS)#define PRMJ_YEAR_SECONDS (PRMJ_DAY_SECONDS * 365L)#define PRMJ_MAX_UNIX_TIMET 2145859200L /*time_t value equiv. to 12/31/2037 *//* function prototypes */static void PRMJ_basetime(JSInt64 tsecs, PRMJTime *prtm);/* * get the difference in seconds between this time zone and UTC (GMT) */JSInt32PRMJ_LocalGMTDifference(){#if defined(XP_UNIX) || defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) struct tm ltime; /* get the difference between this time zone and GMT */ memset((char *)<ime,0,sizeof(ltime)); ltime.tm_mday = 2; ltime.tm_year = 70;#ifdef SUNOS4 ltime.tm_zone = 0; ltime.tm_gmtoff = 0; return timelocal(<ime) - (24 * 3600);#else return mktime(<ime) - (24L * 3600L);#endif#endif#if defined(XP_MAC) static JSInt32 zone = -1L; MachineLocation machineLocation; JSInt32 gmtOffsetSeconds; /* difference has been set no need to recalculate */ if (zone != -1) return zone; /* Get the information about the local machine, including * its GMT offset and its daylight savings time info. * Convert each into wides that we can add to * startupTimeMicroSeconds. */ MyReadLocation(&machineLocation); /* Mask off top eight bits of gmtDelta, sign extend lower three. */ gmtOffsetSeconds = (machineLocation.u.gmtDelta << 8); gmtOffsetSeconds >>= 8; /* Backout OS adjustment for DST, to give consistent GMT offset. */ if (machineLocation.u.dlsDelta != 0) gmtOffsetSeconds -= PRMJ_HOUR_SECONDS; return (zone = -gmtOffsetSeconds);#endif}/* Constants for GMT offset from 1970 */#define G1970GMTMICROHI 0x00dcdcad /* micro secs to 1970 hi */#define G1970GMTMICROLOW 0x8b3fa000 /* micro secs to 1970 low */#define G2037GMTMICROHI 0x00e45fab /* micro secs to 2037 high */#define G2037GMTMICROLOW 0x7a238000 /* micro secs to 2037 low *//* Convert from base time to extended time */static JSInt64PRMJ_ToExtendedTime(JSInt32 base_time){ JSInt64 exttime; JSInt64 g1970GMTMicroSeconds; JSInt64 low; JSInt32 diff; JSInt64 tmp; JSInt64 tmp1; diff = PRMJ_LocalGMTDifference(); JSLL_UI2L(tmp, PRMJ_USEC_PER_SEC); JSLL_I2L(tmp1,diff); JSLL_MUL(tmp,tmp,tmp1); JSLL_UI2L(g1970GMTMicroSeconds,G1970GMTMICROHI); JSLL_UI2L(low,G1970GMTMICROLOW);#ifndef JS_HAVE_LONG_LONG JSLL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,16); JSLL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,16);#else JSLL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,32);#endif JSLL_ADD(g1970GMTMicroSeconds,g1970GMTMicroSeconds,low); JSLL_I2L(exttime,base_time); JSLL_ADD(exttime,exttime,g1970GMTMicroSeconds); JSLL_SUB(exttime,exttime,tmp); return exttime;}JSInt64PRMJ_Now(void){#ifdef XP_OS2 JSInt64 s, us, ms2us, s2us; struct timeb b;#endif#ifdef XP_WIN JSInt64 s, us, win2un = JSLL_INIT(0x19DB1DE, 0xD53E8000), ten = JSLL_INIT(0, 10); FILETIME time, midnight;#endif#if defined(XP_UNIX) || defined(XP_BEOS) struct timeval tv; JSInt64 s, us, s2us;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -