📄 jdate.cpp
字号:
/* * JDate date manipulation wrapper class using the Julian Day concept. * Copyright (C) 2002 Johnathan Ingram, jingram@rogueware.org * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 US */#include "jDate.h"#include <stdio.h>#include <limits.h>#include <math.h>#include <fstream>// Internal defines#define INVALID_FUNCTION_RES -31999#define MIN_JD_FOR_UNIXTIMESTAMP 2440587.5 // 1970-01-01 00:00:00#define MAX_JD_FOR_UNIXTIMESTAMP 2465442.5 // 2038-01-19 00:00:00#define MAX_JD_FOR_DATE 5373484.499988 // 9999-12-31 23:59:59#define JDATE_OFFSETTIME_FILE_ENV "JDATE_OFFSETTIME_FILE"
// Initialize the class static vars
const long JDate::SECS_ONE_MINUTE = 60;
const long JDate::SECS_ONE_HOUR = 3600;
const long JDate::SECS_ONE_DAY = 86400;
const string JDate::tropicalYearDef = "The time it takes the Sun to appear to travel around the sky from a given point of the tropical zodiac back to that same point in the tropical zodiac.";const char* JDate::DT_FMT_DATETIME_ISO = "%Y-%m-%d %H:%M:%S";const char* JDate::DT_FMT_DATE_ISO = "%Y-%m-%d";const char* JDate::DT_FMT_TIME_ISO = "%H:%M:%S";const char* JDate::DT_FMT_SERIAL_ISO = "%Y%m%d%H%M%S";const char* JDate::SET_FMT_DATETIME_ISO = "yyyy-mm-dd hh:nn:ss";const char* JDate::SET_FMT_DATETIME_ISO_TZ = "yyyy-mm-dd hh:nn:sszzz";const char* JDate::SET_FMT_DATE_ISO = "yyyy-mm-dd";const char* JDate::SET_FMT_TIME_ISO = "hh:nn:ss";const char* JDate::SET_FMT_TIME_ISO_TZ = "hh:nn:sszzz";const char* JDate::SET_FMT_SERIAL_ISO = "yyyymmddhhnnss";const char* JDate::SET_FMT_SERIAL_ISO_TZ = "yyyymmddhhnnsszzz";const char* JDate::shortDayOfWeek[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};const char* JDate::dayOfWeek[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};const char* JDate::shortNameOfMonth[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};const char* JDate::nameOfMonth[12] = {"January", "Febuary", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
string JDate::timeOffsetFile = "";
//------------------------------------------------------------------------------// Private Methods//------------------------------------------------------------------------------//------------------------------------------------------------------------------// JDate::_initialize//------------------------------------------------------------------------------voidJDate::_initialize(){ // Populate the average tropical year meanTropicalYear[-5000] = 365.24253; meanTropicalYear[-4000] = 365.24250; meanTropicalYear[-3000] = 365.24246; meanTropicalYear[-2000] = 365.24242; meanTropicalYear[-1000] = 365.24237; meanTropicalYear[0] = 365.24231; meanTropicalYear[1000] = 365.24225; meanTropicalYear[2000] = 365.24219; meanTropicalYear[3000] = 365.24213; meanTropicalYear[4000] = 365.24207; meanTropicalYear[5000] = 365.24201; // Populate the max days per month in a normal gregorian year. maxDaysInMonths[1] = 31; maxDaysInMonths[2] = 28; maxDaysInMonths[3] = 31; maxDaysInMonths[4] = 30; maxDaysInMonths[5] = 31; maxDaysInMonths[6] = 30; maxDaysInMonths[7] = 31; maxDaysInMonths[8] = 31; maxDaysInMonths[9] = 30; maxDaysInMonths[10] = 31; maxDaysInMonths[11] = 30; maxDaysInMonths[12] = 31; // Populate the max days per month in a leap gregorian year. maxDaysInMonthsLeap[1] = 31; maxDaysInMonthsLeap[2] = 29; maxDaysInMonthsLeap[3] = 31; maxDaysInMonthsLeap[4] = 30; maxDaysInMonthsLeap[5] = 31; maxDaysInMonthsLeap[6] = 30; maxDaysInMonthsLeap[7] = 31; maxDaysInMonthsLeap[8] = 31; maxDaysInMonthsLeap[9] = 30; maxDaysInMonthsLeap[10] = 31; maxDaysInMonthsLeap[11] = 30; maxDaysInMonthsLeap[12] = 31; } // JDate::_initialize//------------------------------------------------------------------------------// JDate::_getTimeOffsetParameters//------------------------------------------------------------------------------boolJDate::_getTimeOffsetParameters( unsigned long &startTimeStampUTC, unsigned long &secondInterval){ startTimeStampUTC = ULONG_MAX; secondInterval = 0; // Check if we need to overide the time UTC using the JDate virtual time feature const char *file = NULL; // RULE 1: Check the environment variable for the offset file to use // RULE 2: Check the manually configured offset time file and use that if the environment variable not set char *offsetFileEnv = getenv(JDATE_OFFSETTIME_FILE_ENV); if (offsetFileEnv && strlen(offsetFileEnv) > 0) { // RULE 1 file = offsetFileEnv; } else { // RULE 2 if (timeOffsetFile.length() > 0) file = timeOffsetFile.c_str(); } // If we have an offset file, try and get the settings and apply them to the time if (file) { /* * The file is in the format * xxx\n * yyy * xxx: Unix time stamp UTC to start the virtual time from * yyy: The number of virtual seconds each real second is equal to * */ // Try and read the contents of the file char *endptr1, *endptr2; char buf[512]; ifstream in; in.open(file); if (!in.fail()) { in.getline(buf, sizeof(buf)); startTimeStampUTC = strtol(buf, &endptr1, 10); in.getline(buf, sizeof(buf)); secondInterval = strtol(buf, &endptr2, 10); in.close(); } else return false; // Could not open the file, virtual time is disabled // If there are no errors then the time is offet if (endptr1 && endptr2 && startTimeStampUTC > 0 && secondInterval > 0) return true; } return false;} // JDate::_getTimeOffsetParameters//------------------------------------------------------------------------------// JDate::_makeJDFromGregorian//------------------------------------------------------------------------------voidJDate::_makeJDFromGregorian( register int year, register int month, register int day, register int hour, register int minute, register int second){ // TODO: Validate the date. register long a, y, m; // Calculate the Gregorian Julian Day Number. (Will be at noon) a = (14 - month) / 12; y = year + 4800 - a; m = month + (12 * a) -3; _JD = day + ( ((153 * m) + 2) / 5 ) + (365 * y) + (y / 4) - (y / 100) + (y / 400) - 32045; // Offset the JD with the given time. if (hour < 12) { // Falls on the previouse julian day. _JD -= 1; _SN = ((hour + 12) * 3600) + (minute * 60) + second; } else { // Falls on the current Julian Day. _SN = ((hour - 12) * 3600) + (minute * 60) + second; }} // JDate::_makeJDFromGregorian//------------------------------------------------------------------------------// JDate::_makeGregorianFromJD//------------------------------------------------------------------------------voidJDate::_makeGregorianFromJD( int& year, int& month, int& day, int& hour, int& minute, int& second){ register long a, b, c, d, e, m; long jd = _JD, sn = _SN; // Offset the current JD given the time. if (sn >= 43200) // Seconds since miday. 43200 is midnight of next day. { jd++; sn -= 43200; } else { sn += 43200; } a = jd + 32044; b = ((4 * a) + 3) / 146097; c = a - ((146097*b) / 4); d = ((4*c) + 3) / 1461; e = c - ((1461 * d) / 4); m = ((5 * e) + 2) / 153; day = e - (((153 * m) + 2) / 5) + 1; month = m + 3 - 12 * (m / 10); year = (100 * b) + d - 4800 + (m / 10); hour = sn / 3600; minute = (sn - hour * 3600) / 60; second = sn - ((hour * 3600) + (minute * 60)); if (24 == hour) hour = 0;} // JDate::_makeGregorianFromJD//------------------------------------------------------------------------------// JDate::_makeJDFromJulian//------------------------------------------------------------------------------voidJDate::_makeJDFromJulian( register int year, register int month, register int day, register int hour, register int minute, register int second){ // TODO: Validate the date. register long a, y, m; // Calculate the Gregorian Julian Day Number. (Will be at noon) a = (14 - month) / 12; y = year + 4800 - a; m = month + (12 * a) -3; _JD = day + ( ((153 * m) + 2) / 5 ) + (365 * y) + (y / 4) - 32083; // Offset the JD with the given time. if (hour < 12) { // Falls on the previouse julian day. _JD -= 1; _SN = ((hour + 12) * 3600) + (minute * 60) + second; } else { // Falls on the current Julian Day. _SN = ((hour - 12) * 3600) + (minute * 60) + second; }} // JDate::_makeJDFromJulian//------------------------------------------------------------------------------// JDate::_makeDayOfWeek//------------------------------------------------------------------------------intJDate::_makeDayOfWeek( register int year, register int month, register int day){ // ISO-8601 states that monday is the first day of the week. // We use sunday as the first day of the week. register long a, d, m, y; a = (14 - month) / 12; y = year - a; m = month + (12 * a) - 2; d = (day + y + (y / 4) - (y / 100) + (y / 400) + ((31 * m) / 12)) % 7; return d; } // JDate::_makeDayOfWeek//------------------------------------------------------------------------------// JDate::_makeWeekOfYear//------------------------------------------------------------------------------intJDate::_makeWeekOfYear(){ // Calculate using ISO-8601 register long d1, L, d4; int w; d4 = (_JD + 31741 - (_JD % 7)) % 146097 % 36524 % 1461; L = d4 / 1460; d1 = ((d4 - L) % 365) + L; w = (d1 / 7) + 1; return w;} // JDate::_makeWeekOfYear//------------------------------------------------------------------------------// Public Methods//------------------------------------------------------------------------------//------------------------------------------------------------------------------// JDate::JDate//------------------------------------------------------------------------------JDate::JDate() :
_JD(0),
_SN(0), _TZ(0),
_DST(0){ // Initialize the class _initialize();
// Assign the current date & time UTC using the operator=(time_t)
time_t t;
time(&t);
// Check if we need to offset the virtual time unsigned long startTimeStampUTC, secondInterval; if (_getTimeOffsetParameters(startTimeStampUTC, secondInterval)) { if (t >= startTimeStampUTC) { unsigned long numSecondIntervals = t - startTimeStampUTC; t = startTimeStampUTC + (numSecondIntervals * secondInterval); } } // Assign the current date & time UTC using the setDate(time_t) setDate(t);} // JDate::JDate//------------------------------------------------------------------------------// JDate::JDate//------------------------------------------------------------------------------JDate::JDate( const string &dateStr, const string &fmt) : _JD(0),
_SN(0),
_TZ(0),
_DST(0){ // Initialize the class _initialize(); setDate(dateStr, fmt);} // JDate::JDate//------------------------------------------------------------------------------// JDate::JDate//------------------------------------------------------------------------------JDate::JDate( const time_t unixTime, const int timeZone) : _JD(0),
_SN(0),
_TZ(0),
_DST(0)
{ // Initialize the class _initialize(); setDate(unixTime, timeZone);} // JDate::JDate//------------------------------------------------------------------------------// JDate::JDate//------------------------------------------------------------------------------JDate::JDate( const double julianDayNumber) : _JD(0),
_SN(0),
_TZ(0),
_DST(0){ // Initialize the class _initialize(); setDate(julianDayNumber);} // JDate::JDate
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -