date_tim.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,709 行 · 第 1/5 页

C
1,709
字号
//
// Copyright (C) 1991 Texas Instruments Incorporated.
//
// Permission is granted to any individual or institution to use, copy, modify,
// and distribute this software, provided that this complete copyright and
// permission notice is maintained, intact, in all copies and supporting
// documentation.
//
// Texas Instruments Incorporated provides this software "as is" without
// express or implied warranty.
//
//
// Created: MBN 04/11/89 -- Initial design and implementation
// Updated: MNF 07/25/89 -- Add the parse member function 
// Updated: MBN 09/05/89 -- Added conditional exception handling
// Updated: MBN 01/03/90 -- Adjusted strfind() calls to match new syntax
// Updated: MBN 01/17/90 -- Fixed parsing algorithms to be GMT relative
// Updated: MBN 02/06/90 -- Support years prior to the epoch (1/1/1970)
// Updated: MBN 02/12/90 -- Changed all ascii() functions to return const char*
// Updated: MBN 02/13/90 -- Made ascii_duration() a member function for epoch
// Updated: MJF 03/12/90 -- Added group names to RAISE
// Updated: MJF 01/17/91 -- Fixed parse to use ANSI function mktime()
// Updated: DAN 01/21/91 -- Added adjust_dst() for OS/2 DST adjustment.
// Updated: DLS 03/22/91 -- New lite version
// Updated: JAM 08/12/92 -- removed DOS specifics, stdized #includes
// Updated: JAM 08/12/92 -- added defs for static data members
// Updated: JAM 08/12/92 -- removed timelocal()/mktime() defs (undid OS/2&SUN hacks)
// Updated: JAM 10/03/92 -- removed "delete t" in funcs because ANSI C
//                          localtime() returns pointer *static* |struct tm|
//
// This file  contains member and friend function  implementation  code for the
// CoolDate_Time class defined  in the Date_Time.h header file.   Where appropriate
// and possible, interfaces to,  and us of, existing  system functions has been
// incorporated.  An overview  of the CoolDate_Time   class structor  along with  a
// synopsis of each member and friend function, can be found in the Date_Time.h
// header file.  Two static  char* tables are defined  within  this  file to be
// used only by member functions of the CoolDate_Time class.  The first is the date
// format table that is indexed by the enum  symbolic values in the <country.h>
// header  file.  This table contains  format  strings for  sscanf()   used  to
// implement the  formatted  ASCII  date output according  to  the rules of the
// appropriate country.  The second is the time table that is  again indexed by
// the enum symbolic values  in the <country.h> header  file and   performs the
// same function for sscanf() output of the time.
//

#ifndef DATETIMEH               // If DateTime class has not been defined
#include <cool/Date_Time.h>     // Include class specification header file
#endif

#include <ctype.h>              // ANSI C character macros
#include <stdlib.h>             // Include standard c library support


static int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

static const char* date_format_s[] = {          // Date formatting table
"* UNKNOWN *",                                  // Unknown country code
"%02d-%02d-%4d",                                // 03-29-1989 UNITED STATES   
"%4d-%02d-%02d",                                // 1989-29-03 FRENCH CANADIAN 
"%02d-%02d/%4d",                                // 03/29/1989 LATIN AMERICA   
"%02d-%02d-%4d",                                // 03-29-1989 NETHERLANDS     
"%02d-%02d/%4d",                                // 03/29/1989 BELGIUM         
"%02d-%02d/%4d",                                // 03/29/1989 FRANCE          
"%02d-%02d/%4d",                                // 03/29/1989 SPAIN           
"%02d-%02d/%4d",                                // 03/29/1989 ITALY           
"%02d-%02d.%4d",                                // 03.29.1989 SWITZERLAND     
"%02d-%02d-%4d",                                // 29-03-1989 UNITED KINGDOM  
"%02d-%02d/%4d",                                // 03/29/1989 DENMARK         
"%4d-%02d-%02d",                                // 1989-29-03 SWEDEN          
"%02d/%02d/%4d",                                // 03/29/1989 NORWAY          
"%02d.%02d.%4d",                                // 03.29.1989 GERMANY         
"%02d/%02d/%4d",                                // 03/29/1989 PORTUGAL        
"%02d.%02d.%4d",                                // 03.29.1989 FINLAND         
"%02d/%02d/%4d",                                // 03/29/1989 ARABIC COUNTRIES
"%02d %02d %4d"                                 // 03 29 1989 ISRAEL          
};

static const char* time_format_s[] = {          // Time formatting table
"* UNKNOWN *",                                  // Unknown country code
"%02d:%02d:%02d %s",                            // 17:35:00 UNITED STATES   
"%02d:%02d:%02d %s",                            // 17:35:00 FRENCH CANADIAN 
"%02d:%02d:%02d %s",                            // 17:35:00 LATIN AMERICA   
"%02d:%02d:%02d %s",                            // 17:35:00 NETHERLANDS     
"%02d:%02d:%02d %s",                            // 17:35:00 BELGIUM         
"%02d:%02d:%02d %s",                            // 17:35:00 FRANCE          
"%02d:%02d:%02d %s",                            // 17:35:00 SPAIN           
"%02d:%02d:%02d %s",                            // 17:35:00 ITALY           
"%02d.%02d.%02d %s",                            // 17.35.00 SWITZERLAND     
"%02d:%02d:%02d %s",                            // 17:35:00 UNITED KINGDOM  
"%02d:%02d:%02d %s",                            // 17:35:00 DENMARK         
"%02d.%02d.%02d %s",                            // 17.35.00 SWEDEN          
"%02d:%02d:%02d %s",                            // 17:35:00 NORWAY          
"%02d.%02d.%02d %s",                            // 17.35.00 GERMANY         
"%02d:%02d:%02d %s",                            // 17:35:00 PORTUGAL        
"%02d.%02d.%02d %s",                            // 17.35.00 FINLAND         
"%02d:%02d:%02d %s",                            // 17:35:00 ARABIC COUNTRIES
"%02d:%02d:%02d %s"                             // 17:35:00 ISRAEL          
};

#define TIME_VALUES this->dt.tm_hour, this->dt.tm_min, this->dt.tm_sec, \
            tz_table[this->tz_code]
#define MONTH_DATE_VALUES this->dt.tm_mon+1, this->dt.tm_mday, \
            this->get_year (), tz_table[this->tz_code]
#define DATE_MONTH_VALUES this->dt.tm_mday, this->dt.tm_mon+1, \
            this->get_year (), tz_table[this->tz_code]
#define YEAR_MONTH_VALUES this->get_year(), this->dt.tm_mday, \
            this->dt.tm_mon+1, tz_table[this->tz_code]

// default_tz_code_s -- Default time zone
time_zone CoolDate_Time::default_tz_code_s;

// default_c_code_s -- Default country
country CoolDate_Time::default_c_code_s;

// adjust_tz -- Calculate adjustment for time zone from GMT in seconds
// Input:       None
// Output:      None

void CoolDate_Time::adjust_tz () {
  long local_secs = 0;
  tm* t;                                        // Temporary variable
  time_t sys_seconds = time ((time_t*)0);               // System GMT time in seconds
  set_tz (this->tz_code);                       // Setup local time conversion
  t = localtime (&sys_seconds);                 // Convert to local time
  int i;
  for (i = 70; i < t->tm_year; i++) {
    local_secs += (YEAR + DAY);
    if (IS_LEAP_YEAR (i)) local_secs += DAY;
  }
  for (i = 0; i < t->tm_mon; i++) {
    local_secs += (DAY * days_in_month[i]);
    if (i == FEBRUARY && IS_LEAP_YEAR (t->tm_year))
      local_secs += DAY;
  }
  t->tm_mday--;
  local_secs += (DAY * t->tm_mday);
  local_secs += (HOUR * t->tm_hour);
  local_secs += (MINUTE * t->tm_min);
  local_secs += t->tm_sec;
  this->time_adjust = sys_seconds - local_secs; // TZ offset in seconds
}


// adjust_year -- Calculate offset from epoch to support years before 1/1/1970
// Input:         None
// Output:        None
//
// The CoolDate_Time class is  based upon the ANSI  C time(2) function. This
// calculates time/date in seconds since the  epoch (1/1/1970). To allow
// the CoolDate_Time class to support dates before the epoch we need to find
// which year  after 1970 has the same  day of week/dates correlation as
// the one specified. To determine this, we make use of the  fact that a
// yearly periodic cycle of 28 years exists such that 1/1/1970 fell on a
// Thursday and 1/1/1998 is also a Thursday.
//

void CoolDate_Time::adjust_year (long& year) {
  if (year > 99 && year < 1970) {
    this->year_adjust = int(1970 - year);
    year += NEW_YEAR (this->year_adjust);
  }
  else if (year < 70) {
    this->year_adjust = int(70 - year);
    year += NEW_YEAR (this->year_adjust);
  }
  else
    this->year_adjust = 0;
}


// set_tz -- Set the local time zone before conversion
//           of object from GMT seconds to tm structure
// Input:    Time zone
// Output:   None

void set_tz (time_zone tz) {
  static char tz_name[50];                              // Temporary variable
  strcpy (tz_name, "TZ=");                      // TZ envionmental symbol
  strcpy (&tz_name[3], tz_table[tz]);           // Concatenate time zone name
  putenv (tz_name);                             // Set environment TZ variable
}


// resolve -- This private method takes a long representing the
//            number of seconds since 01/01/1970 00:00:00 GMT
//            and converts that into local time, placing the 
//            result into the date/time structure
// Input:     this*
// Output:    None -- date/time structure updated

void CoolDate_Time::resolve () {
  tm* t;                                        // Temporary variable
  set_tz (this->tz_code);                       // Set local time zone
  adjust_tz ();                                 // Calculate time zone offset
  t = localtime (&(this->time_seconds));        // Convert to local time zone
  this->dt.tm_sec = t->tm_sec;                  // Copy seconds value
  this->dt.tm_min = t->tm_min;                  // Copy minutes value
  this->dt.tm_hour = t->tm_hour;                // Copy hours value
  this->dt.tm_mday = t->tm_mday;                // Copy day of month value
  this->dt.tm_mon = t->tm_mon;                  // Copy month value
  this->dt.tm_year = t->tm_year;                // Copy year value
  this->dt.tm_wday = t->tm_wday;                // Copy day of week value
  this->dt.tm_yday = t->tm_yday;                // Copy day of year value
  this->dt.tm_isdst = t->tm_isdst;              // Copy day light savings flag
}


// CoolDate_Time() -- Simple constructor for empty CoolDate_Time object
// Input:         None
// Output:        CoolDate_Time reference

CoolDate_Time::CoolDate_Time () {
  this->time_seconds = time((time_t*)0);                // Zero seconds
#ifdef ERROR_CHECKING
  if (this->default_c_code_s == NULL) {         // If no country code set
    //RAISE (Warning, SYM(CoolDate_Time), SYM(No_C_Code),
    printf ("CoolDate_Time::CoolDate_Time(): Default country code not set but used.\n");
  }
  if (this->default_tz_code_s == NULL) {        // If no time zone code set
    //RAISE (Warning, SYM(CoolDate_Time), SYM(No_Tz_Code),
    printf ("CoolDate_Time::CoolDate_Time(): Default time zone code not set but used.\n");
  }
#endif
  this->c_code = this->default_c_code_s;        // Set country code
  this->tz_code = this->default_tz_code_s;      // Set time zone code
  set_tz (default_tz_code_s);                   // Set local time zone
}


// CoolDate_Time(tz,c) -- Simple constructor for empty CoolDate_Time object
//                    that also sets the time zone and country
// Input:             Time zone, country codes
// Output:            CoolDate_Time reference

CoolDate_Time::CoolDate_Time (time_zone tz, country c) {
  this->time_seconds = time((time_t*)0);                // Zero seconds
  this->c_code = c;                             // Set country code
  this->tz_code = tz;                           // Set time zone code
  set_tz (tz);                                  // Set local time zone
}


// CoolDate_Time(const CoolDate_Time&) -- Constructor to duplicate a CoolDate_Time object
// Input:                        CoolDate_Time reference
// Output:                       CoolDate_Time reference

CoolDate_Time::CoolDate_Time (const CoolDate_Time& d) {
  this->time_seconds = d.time_seconds;
  this->tz_code = d.tz_code;
  this->c_code = d.c_code;
  this->dt.tm_sec = d.dt.tm_sec;
  this->dt.tm_min = d.dt.tm_min;
  this->dt.tm_hour = d.dt.tm_hour;
  this->dt.tm_mday = d.dt.tm_mday;
  this->dt.tm_mon = d.dt.tm_mon;
  this->dt.tm_year = d.dt.tm_year;
  this->dt.tm_wday = d.dt.tm_wday;
  this->dt.tm_yday = d.dt.tm_yday;
  this->dt.tm_isdst = d.dt.tm_isdst;
  this->time_adjust = d.time_adjust;
  this->year_adjust = d.year_adjust;
  this->century = d.century;
}


// ~CoolDate_Time -- CoolDate_Time class destructor
// Input:        this*
// Output:       None

CoolDate_Time::~CoolDate_Time () { 
}
                                       

// set_local_time -- Sets the time zone and DST adjusted local time
// Input:            this*
// Output:           CoolDate_Time reference with slots updated for local time

void CoolDate_Time::set_local_time () {
  tm* t;                                        // Temporary pointer variable
  time_t sys_seconds = time ((time_t*)0);               // System GMT time in seconds
  this->time_seconds = sys_seconds;             // Save time for future use
  set_tz (this->tz_code);                       // Setup local time conversion
  t = localtime (&sys_seconds);                 // Convert secs to local time
  this->dt.tm_sec = t->tm_sec;                  // Copy seconds value
  this->dt.tm_min = t->tm_min;                  // Copy minutes value
  this->dt.tm_hour = t->tm_hour;                // Copy hours value
  this->dt.tm_mday = t->tm_mday;                // Copy day of month value
  this->dt.tm_mon = t->tm_mon;                  // Copy month value
  this->dt.tm_year = t->tm_year;                // Copy year value
  this->dt.tm_wday = t->tm_wday;                // Copy day of week value
  this->dt.tm_yday = t->tm_yday;                // Copy day of year value
  this->dt.tm_isdst = t->tm_isdst;              // Copy day light savings flag
  this->year_adjust = 0;
  this->century = 1900;
}


// set_gm_time -- Set the Greenwich Mean Time
// Input:         this*
// Output:        CoolDate_Time reference with slots updated for GMT

void CoolDate_Time::set_gm_time () {
  tm* t;                                        // Temporary pointer variable
  time_t sys_seconds = time ((time_t*)0);               // System GMT time in seconds
  this->tz_code = GB_EIRE;                      // GMT time zone
  set_tz (this->tz_code);                       // Setup GMT conversion
  t = localtime (&sys_seconds);                 // Convert seconds to local time
  this->dt.tm_sec = t->tm_sec;                  // Copy seconds value
  this->dt.tm_min = t->tm_min;                  // Copy minutes value
  this->dt.tm_hour = t->tm_hour;                // Copy hours value
  this->dt.tm_mday = t->tm_mday;                // Copy day of month value
  this->dt.tm_mon = t->tm_mon;                  // Copy month value
  this->dt.tm_year = t->tm_year;                // Copy year value
  this->dt.tm_wday = t->tm_wday;                // Copy day of week value
  this->dt.tm_yday = t->tm_yday;                // Copy day of year value
  this->dt.tm_isdst = t->tm_isdst;              // Copy day light savings flag
  this->year_adjust = 0;
  this->century = 1900;
}


// operator= -- Assignment operator to duplicate a CoolDate_Time object
// Input:       CoolDate_Time reference
// Output:      CoolDate_Time reference

CoolDate_Time& CoolDate_Time::operator= (const CoolDate_Time& d) {
  this->time_seconds = d.time_seconds;
  this->tz_code = d.tz_code;
  this->c_code = d.c_code;
  this->dt.tm_sec = d.dt.tm_sec;
  this->dt.tm_min = d.dt.tm_min;
  this->dt.tm_hour = d.dt.tm_hour;
  this->dt.tm_mday = d.dt.tm_mday;
  this->dt.tm_mon = d.dt.tm_mon;
  this->dt.tm_year = d.dt.tm_year;
  this->dt.tm_wday = d.dt.tm_wday;
  this->dt.tm_yday = d.dt.tm_yday;
  this->dt.tm_isdst = d.dt.tm_isdst;
  this->time_adjust = d.time_adjust;
  this->year_adjust = d.year_adjust;
  this->century = d.century;
  return *this;

⌨️ 快捷键说明

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