You are on page 1of 33

Journal of Image Processing and Artificial Intelligence

Volume 1 Issue 3

YK- 2038 Bug

Vikash Chandra Sharma


Department of Computer Science and Engineering, Kashi Institute of Technology, Varanasi, U.P,
India
E-mail: vikash.cse.iu@gmail.com

Abstract
This paper talks about the problem we all will be facing precisely on 19th Jan. 2038.
Digital world has been vulnerable by several bugs however, solely a couple of looked as if it
would cause a good danger. The bug that got most famed was Y2K. Somehow, we tend to got
over it, then, there was Y2K10. It too was resolved and currently we tend to have Y2K38. The
Y2K38 bug, if not resolved, will make sure that the predictions that were created for the Y2K
bug come true this point. On 19th Jan. 2038 within all UNIX supported Operating system
Time and Date would began to work incorrectly. This produces a big problem which is
critical for all Software’s and basically a threat to embedded systems. Hence afterwards it
basically shows possible solutions which we can take to avoid Unix Millennium 2038
problem. By doing research I have developed a patch. Now I have moved this patch to
GitHub. This patch can enable the 32bit S/W to use 64bit time_t on a 32bit computer.
This patch is still under development but it is current state has been shown in this paper
along with all the codes and brief description of each and every function and files. I think
to quickies way to solve this problem is by using patch which Software developers who
are having 32bit S/w simply needs to include all header files and implementation files
within their software and use the function I along with other open source community has
made. Coding has been done in C language.

Keywords: Unix, unix 2038 problem, unix 2038 bug, unix 2038 millennium bug, unix
2038 millennium problem, unix future, time_t, time_t 32bit, embedded computer
future, embedded computer 2038, operating system in 2038, operating system in 2038,
pathes, unix patch, unix 2038 program

1 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

INTRODUCTION
Sign out from your Yahoo Messenger or
Google Talk. Change your Calendar year
beyond 2038 say 2040 in your Windows
O.S. then log in once again to these
messengers what happens? [1, 2].

Messengers would fail! Unix


Millennium 2038 Bug is a problem which
may seems to be a small but can cause a
problem to wide range of devices and
Machines. Unix was built in 1969
specifically on 20th April 1969. During
that period Unix developer did not know
that Software Fig. 1: Evolution of UNIX.

can live for such a long time (greater So this diagram describes the
than 100 years). But today we have some evolution of Unix. You can clearly see that
geeks software available for, e.g., Mac osx, Linux all have evolved from
Microsoft office Notepad which simply Unix. However, Windows is not Unix
seems to live even greater than hundreds of based.
year from now on [3–7].

Company/Developer- Ken Thompson,


What is Unix Operating system? Brian Kernighan, Douglas Mcllroy, Dennis
Unix officially trademark as UNIX Ritchie, Joe Ossanna at Bell Labs.
developed in Bell Labs by Geeks-“Ken Programmed In- C and Assembly
Thompson, Dennis Ritchie, Brian Language.
Kernighan, Douglas McIlroy, Michael OS Family- UNIX.
Lesk and Joe Ossanna” [8, 9]. Source Model- Historically closed
source, now some UNIX projects (BSD
family and illumos) are open sourced.

2 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

Initial Release- April 20, 1969; 44 Years features of the software so it’s
ago. pretty important . After 19th Jan.
Available Language(s)- English. 2038 it will fail.
Kernel Type- Monolithic.
Default User Interface- Command Line What are the major technical areas in
interface and Graphical (X Window which Y2038 issues may exist?
System). To be specific all those areas
License- Proprietary which would use 32bit signed time value
Official Website- www.unix.org would fall under this category.
What is time_t ?
time_t is a variable of 32 bit. Basically it These include:-
was developed by UNIX developers during  32bit CPUs
1970. In all the UNIX based 32bit  Firmware/BIOS
operating system you will probably see  32bit Operating systems
Calendar starting from 1901–2038. This  Web-based applications and web
is because time_t is of 32bit which implises contents
it can contain 2^32 int value which is  Databases
basically 4294967296 days equivalent to  Computer bus
137 years. So time_t can possess years  Communication protocols
from 1970 till 2107. But time_t is
 Communication and networking
unsigned variable this makes it range +68
equipment for e.g., Satellites,
th
and -69. Hence forth its limit is 19
Routers, Switches, Mobile electronics,
Jan. of 2038 (1970 + 68). 1970–69
including tablets, netbooks etc.
gives 1901 hence time_t ranges from
 Will affect all transportation services.
1901–2038(19th Jan.). After 19th Jan.
 Home electronics, such as game
2038 time_t will get roll back to 1901.
consoles.
time_t is used by all major software’s
drivers running on Unix enabled
How big is Y2038? How much will it cost
operating system for storing
to prepare for it?
into database for updating there
To answer this question considers the cost
software automatically within certain
wasted to remove the bog. The digital age
time period (like Antivirus) and
before 2000; and now within 2000–2038.
to carry out all other basic
In this digital age equipments are a lot

3 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

more expensive. Henceforth, experts embedded devices may malfunction.


believe that cost will easily exceed more Fortunately there is plenty of time to
than 10trillion $. The most vulnerable resolve these issues.
are embedded computers. This is because
embedded computer are time specific. Can I just recompile my 32-bit program
They need to be accurate and embedded on a 64-bit compiler to fix the problem?
computers are used everywhere like we use It depends on the targeted
embedded computers in clock, airplane. machines and nature of programs.
If they began to work incorrectly they can So, probably the problem may not get
pose a huge loss for instance airplane may resolved by simply recompiling the 32-bit
get crash, clock may stop working program on a 64bit compiler.
correctly. But it is not only limited to
embedded computers but also to How much of my code will likely be
communication protocols, file system affected by Y2038?
database etc. So Vulnerability of Y2038 Roughly it is estimated that 6% of all
problem is really wide and source code need to be reviewed. But to
complicated. say it precisely it depends on the
software. Some software which
What's the worst that could happen? depends on time more frequently would
The worst-case scenario for Y2038 is be pretty much more affected than
much more severe than Y2K. Y2K was just others who are less dependent on time.
a problem related to human
interpretation of dates. But Y2038 is a Are there any software tools that can
fundamental problem of time related help me finding and correcting Y2038
operations for all Unix capable machine. issues?
Hence worst-case of Y2038 can be much Yes it is pretty much believed that before
more severe than Y2K. For instance 2038 there will be patches available
airplane may get crash, entire which developers simply need to use inside
global communication can come to halt, there software so as to make it work
Electric power lines can go offline, Cars correctly even after 2038. One patch is
may stop working or behave being made by me and is discussed
erratically and Satellite may stop working afterwards in this paper.
and possibly can fall out of orbit. Many

4 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

How can we prepare and adapt to Steps...


Y2038 Bug? 1. Login to yahoo traveller.
First of all there is no universal 2. Send instant message to anyone-fine its
solution. The cheapest and most effective operating.
solution is to use 64bit computers. This 3. Now, modification your system dates to
will introduce 64bit time_t. 64 time_t can 19-Jan-2038, 03:14:07 AM or on top of.
contain a lot more year even greater than 4. Make sure weather your date is
10 times universe life. Hence this will modified.
eliminate the problem forever. Looking 5. Once more send instant message to
today’s digital media growth it may anyone. Your YM crashes.
be possible that during 2038 very few
devices will be of 32bit most of them will
be of 64bit. But this makes the light fall MY RESEARCH
over to embedded devices. Even today we Patch
use 16bit, 32bit embedded devices. Using internet resources and references I
Actually embedded devices are really have made a patch. This patch is right now
typical to program (Since they 10 in its development phase because there
are new bugs discovered as we test
For example, the output of this script on it on different machine.
Debian GNU/Linux (kernel This is an implementation of POSIX
2.4.22) (An affected system) are time.h which solves time_t 32bit
# ./2038.pl portability problem. It uses system native
Tue January nineteen 03:14:01 2038 code to develop its own time zone and
Tue January nineteen 03:14:02 2038 daylight saving time calcutions and
Tue January nineteen 03:14:03 2038 thus does not required to be shipped with
Tue January nineteen 03:14:04 2038 its own time zone table.
Tue January nineteen 03:14:05 2038
Tue January nineteen 03:14:06 2038 How to use my Patch?
Tue January nineteen 03:14:07 2038 Basically you need to use header files
Fri Dec thirteen 20:45:52 1901 made by me. This header files contains
Fri Dec thirteen 20:45:52 1901 64bit time representation functions which
Fri Dec thirteen 20:45:52 1901 we can use on 32bit function. So using
Test it currently... find and replace dialog box find all the

5 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

time_t related function which can pose  sec_in_gregorian_cycle= No. of


problems after Y2038 and and replace seconds in Gregorian cycle
them with the function made by me.  MAX_SAFE_YEAR = 2037
This patch has two major header files  MIN_SAFE_YEAR = 1971
 SOLAR_CYCLE_LENGTH = 28
time64.h time.h  safe_years_low[SOLAR_CYCLE_LE
-------- ------ NGTH]
localtime64_r localtime_r  CHEAT_DAYS - Total no. of days
localtime64 localtime in 108 years
gmtime64_r gmtime_r  CHEAT_YEAR- Total no. of years
gmtime64 gmtime
asctime64_r asctime_r Functions used are:-
asctime64 asctime
 IS_LEAP() –
ctime64_r ctime_r
 is the year leap or not
ctime64 ctime
 USE_SYSTEM_LOCALTIME() –
timelocal64 mktime
 Use system local time
mktime64 mktime
 SHOULD_USE_SYSTEM_GMTIME
timegm64 timegm (a GNU

extension)
 To use system gm time if possible
Among these header files major
 cmp_date( const struct
operations performed in header file is
TIME_PERIOD* left, const struct
in time64.h these operations are Variable
time_period* right ) –
used are:-
 Compare two dates. Compares two
 days_in_month - No. of days in the
dates specifically left and right section
month
days like Monday, time ( like min.)
 julian_days_in_month Sum of days
Ignores things like gmtoffset and dst
after each consecutive months
 date_in_safe_range( const struct
 wday_name - weekdays name
TIME_PERIOD* date, const struct
 mon_name- Months name
time_period* min) –
 length_of_year - No. of days in Year
 date range after 2038 which can be
 years_in_gregorian_cycle = 400 used
 days_in_gregorian_cycle= No. of  const struct time_period* max ) -
days in Gregorian cycle

6 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

 Check range of date is it valid or  copy_TIME_PERIOD64_to_time_peri


not using cmp_date function od (const struct TIME_PERIOD
 Time64_T timegm64(const struct *src, struct time_period *dest) –
TIME_PERIOD *date)-  Copies time period 64bit data
 returns total sec. according to into time period.
time64_T  time_period * fake_localtime_r (const
 check_time_period() – time_t *time, struct time_period
 checks limits of days, min etc. *result) –
 Year cycle_offset() –  Fetches local time from inbuilt
 The exceptional centuries time_t and tires to store it within
without leap years cause the cycle to time_t of 64bit
shift by 16. For a given year after  time_period * fake_gmtime_r
y2038 find the the next correct year (const time_t *time, struct time_period
(Matching Year). *result)) –
A matching year...  Fetches local time gm from inbuilt
o Starts on the same day of the week. time_t and tires to store it within
o Has the same leap year status. time_t of 64bit
Over here a previous year must match.  Time64_T seconds_between_years
For eg. When doing 1st Jan we (Year leftYear, Year rightYear) -
might end up over to dec. 31st.  returns no. of sec. b/w left and right
Similarly next year must have the same section of year
day of the week.
 safe_year(Year) > returns safe  Time64_T mktime64 ( struct
year, i.e., next year which software can TIME_PERIOD *input_date ) -
use (after 2038)  Interprete this input_date to be of
 copy_time_period_to_TIME_PERIOD time_t 64bit
64 (const struct time_period *src,  Time64_T timelocal64 (struct
struct TIME_PERIOD *dest) – TIME_PERIOD *date) –
 Copies all data of time_period(older  Interprete date to be of time64_T
time version) like minutes, days, into  struct TIME_PERIOD *gmtime64_r
64bit time_t (const Time64_T *in_time, struct
TIME_PERIOD *p) –

7 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

 Operating to be performed over here  struct time_period *


are - If time_t is small then use check_to_time_min --
system gmtime(). returns an date  check exact failure point for minimum
object. This date object contains value of time instead of exact failure
month, year, day,min...etc. attributes. point for minimum value of time
These attributes are modified  void
according to Gregorian calendar - "On guess_time_limits_from_types(void)
the basis of cycles (cycles is the  this function shows that we cant
month/days in Gregorian calendar + 1), have negative value,,we have to use
whether leap year or not and hence positive value
forth some optimization is performed.  char * time_period_as_json(const
 struct TIME_PERIOD *localtime64_r struct time_period* date)
(const Time64_T *time, struct  used for time zone
TIME_PERIOD *local_time_period) –  check_max
 finds a safe time( Valid time after  check for maximum
2038 ) within which it would be  char *dump = malloc(80 *
going to save local_time data char sizeof(char))
*asctime64_r( const struct  Creats variable of 80bytes
TIME_PERIOD* date, char *result ) –  double my_difftime
simply checks when time, week days,  This function returns d/f of two years
months etc. goes out of range like  time_t check_date_max
25th hour and when that  Checks When time maximum,
happens simply trigger or when time is overflow
arrayOutOfindexError  time_t check_date_min
 time_t check_date_min  When time minimum,or when time is
 When time minimum,or when time is underflow
underflow  struct time_period *
 struct time_period * check_to_time_max
check_to_time_max  Check exact failure point for
 check exact failure point for maximum value of time instead of
maximum value of time instead of exact failure point for maximum
exact failure point for maximum value of time
value of time

8 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

 struct time_period * Source Code


check_to_time_min Files
 Check exact failure point for 1.time64.c
minimum value of time instead of #include <assert.h>
exact failure point for minimum value #include <stdlib.h>
of time #include <stdio.h>
 void #include <string.h>
guess_time_limits_from_types(void) #include <time.h>
 This function shows that we cannot #include <errno.h>
have negative value, we have to use #include "time64.h"
positive value #include "time64_limits.h"
 char * time_period_as_json(const /* 28 year Julian calendar cycle */
struct time_period* date) #define SOLAR_CYCLE_LENGTH
 used for time zone 28
4. Header files /* Year cycle from

 time64_config.h MAX_SAFE_YEAR down. */

 this header file used for time static const int

configuration of the system. safe_yearshigh[SOLAR_CYCLE_LE

 time.h NGTH] = {

 this file used to declares the time types 2016, 2017, 2018, 2019,

or structures. 2020, 2021, 2022, 2023,

 stdio.h 2024, 2025, 2026, 2027,

 used for standard input/output 2028, 2029, 2030, 2031,

math.h 2032, 2033, 2034, 2035,

 used for mathematical expression or 2036, 2037, 2010, 2011,

syntaxes. 2012, 2013, 2014, 2015


};
 stdlib.h
/* Year cycle from
 used for genral purpose functions like-
MIN_SAFE_YEAR up */
macro,dynamic memory management
static const int
etc.
safe_yearslow[SOLAR_CYCLE_LEN
 string.h
GTH] = {
 that header file used for a character
1996, 1997, 1998, 1971,
type or for a string.

9 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

1972, 1973, 1974, 1975, #ifdef USE_SYSTEM_LOCALTIME


1976, 1977, 1978, 1979, # define
1980, 1981, 1982, 1983, SHOULD_USE_SYSTEM_LOCALTI
1984, 1985, 1986, 1987, ME(a) ( \
1988, 1989, 1990, 1991, (a) <=
1992, 1993, 1994, 1995, SYSTEM_LOCALTIME_MAX &&
}; \
/* This isn't used, but it's handy to look (a) >=
at */ SYSTEM_LOCALTIME_MIN
static const int \
dow_yearstart[SOLAR_CYCLE_LEN )
GTH] = { int cmp_date( const struct
5, 0, 1, 2, /* 0 2016 - 2019 */ TIME_PERIOD* left, const struct
3, 5, 6, 0, /* 4 */ time_period* right ) {
1, 3, 4, 5, /* 8 1996 - 1998, if( left->time_period_year > right-
1971*/ >time_period_year )
6, 1, 2, 3, /* 12 1972 - 1975 */ return 1;
4, 6, 0, 1, /* 16 */ else if( left->time_period_year <
2, 4, 5, 6, /* 20 2036, 2037, right->time_period_year )
2010, 2011 */ return -1;
0, 2, 3, 4 /* 24 2012, 2013, If (left->time_period_mon > right-
2014, 2015 */ >time_period_mon)
}; return 1;
/*Days from epoch on Jan 1st*/ else if (left->time_period_mon <
#define CHEAT_DAYS (1199145600 right->time_period_mon)
/ 24 / 60 / 60) return -1;
#define CHEAT_YEARS 108 If (left->time_period_mday > right-
#define IS_LEAP(n) ((!(((n) + >time_period_mday)
1900) % 400) || (!(((n) + 1900) % 4) return 1;
&& (((n) + 1900) % 100))) != 0) Else if (left->time_period_mday <
#define WRAP(a,b,m) ((a) = ((a) < right->time_period_mday)
0 ) ? ((b)--, (a) + (m)) : (a)) return -1;

10 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

if ( left->time_period_hour > right- /* timegm() is not in the C or POSIX


>time_period_hour ) spec, but it is such a useful
return 1; extension I would be remiss in
else if( left->time_period_hour < leaving it out. Also I need it
right->time_period_hour ) for localtime64 ()
return -1; */
if( left->time_period_min > right- Time64_T timegm64 (const struct
>time_period_min ) TIME_PERIOD *date) {
return 1; Time64_T days = 0;
else if( left->time_period_min < Time64_T seconds = 0;
right->time_period_min ) Year year;
return -1; Year orig_year = (Year) date-
if( left->time_period_sec > right- >time_period_year;
>time_period_sec ) int cycles = 0;
return 1; If (orig_year > 100) {
else if( left->time_period_sec < cycles = (orig_year - 100) / 400;
right->time_period_sec ) orig_year -= cycles * 400;
return -1; days += (Time64_T)cycles *
return 0; days_in_gregorian_cycle;
} }
/* Checking whether date is inside or else if(orig_year < -300 ) {
not Cycles = (orig_year - 100) / 400;
*/ orig_year -= cycles * 400;
int date_in_safe_range( const struct days += (Time64_T) cycles *
TIME_PERIOD* date, const struct days_in_gregorian_cycle;
time_period* min, const struct }
time_period* max ) { TIME64_TRACE3("# timegm/
if( cmp_date(date, min) == -1 ) cycles: %d, days: %lld, orig_year:
return 0; %lld\n", cycles, days, orig_year);
if( cmp_date(date, max) == 1 ) If (orig_year > 70 ) {
return 0; year = 70;
return 1; while( year < orig_year ) {
}

11 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

days += assert(time_period-
length_of_year[IS_LEAP(year)]; >time_period_sec <= 61);
year++; assert(time_period-
} >time_period_min >= 0);
} assert(time_period-
else if ( orig_year < 70 ) { >time_period_min <= 59);
year = 69; assert(time_period-
do { >time_period_hour >= 0);
days -= assert(time_period-
length_of_year[IS_LEAP(year)]; >time_period_hour <= 23);
year--; assert(time_period-
} while( year >= orig_year ); >time_period_mday >= 1);
} assert(time_period-
days += >time_period_mday <=
julian_days_by_month[IS_LEAP(orig days_in_month[IS_LEAP(time_period
_year)][date->time_period_mon]; ->time_period_year)][time_period-
days += date->time_period_mday - >time_period_mon]);
1; assert(time_period-
seconds = days * 60 * 60 * 24; >time_period_mon >= 0);
seconds += date->time_period_hour assert(time_period-
* 60 * 60; >time_period_mon <= 11);
seconds += date->time_period_min assert(time_period-
* 60; >time_period_wday >= 0);
seconds += date->time_period_sec; assert(time_period-
return(seconds); >time_period_wday <= 6);
} assert(time_period-
static int check_time_period(struct >time_period_yday >= 0);
TIME_PERIOD *time_period) assert(time_period-
{ >time_period_yday <=
/* Don't forget leap seconds */ length_of_year[IS_LEAP(time_period-
assert(time_period- >time_period_year)]);
>time_period_sec >= 0);

12 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

#ifdef This is so the calendars match up.


HAS_TIME_PERIOD_TIME_PERIO Also the previous year must match.
D_GMTOFF When doing Jan 1st you might
assert(time_period- wind up on Dec 31st the previous
>time_period_gmtoff >= -24 * 60 * year when doing a -UTC time zone.
60); Finally, the next year must have the
assert(time_period- same start day of week. This
>time_period_gmtoff <= 24 * 60 * is for Dec 31st with a +UTC time
60); zone.
#endif It doesn't need the same leap year
return 1; status since we only care about
} January 1st.
static Year cycle_offset(Year year) */
{ static int safe_year(const Year year)
const Year start_year = 2000; {
Year year_diff = year - start_year; int safe_year;
Year exceptions; Year year_cycle;
if( year > start_year ) if( year >= MIN_SAFE_YEAR &&
year_diff--; year <= MAX_SAFE_YEAR ) {
exceptions = year_diff / 100; return (int)year;
exceptions -= year_diff / 400; }
TIME64_TRACE3("# year: %lld, year_cycle = year +
exceptions: %lld, year_diff: %lld\n", cycle_offset(year);
year, exceptions, year_diff); if( year < MIN_SAFE_YEAR )
return exceptions * 16; year_cycle -= 8;
} if( is_exception_century(year) )
/* For a given year after 2038, pick the year_cycle += 11;
latest possible matching /* Also xx01 years, since the
year in the 28 year calendar cycle. previous year will be wrong */
A matching year... if( is_exception_century(year - 1) )
1) Starts on the same day of the year_cycle += 17;
week.
2) Has the same leap year status.

13 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

year_cycle %= dest->time_period_sec =
SOLAR_CYCLE_LENGTH; src->time_period_sec;
if( year_cycle < 0 ) dest->time_period_min =
year_cycle = src->time_period_min;
SOLAR_CYCLE_LENGTH + dest->time_period_hour =
year_cycle; src->time_period_hour;
assert( year_cycle >= 0 ); dest->time_period_mday =
assert( year_cycle < src->time_period_mday;
SOLAR_CYCLE_LENGTH ); dest->time_period_mon =
if( year < MIN_SAFE_YEAR ) src->time_period_mon;
safe_year = dest->time_period_year =
safe_years_low[year_cycle]; (Year)src->time_period_year;
else if( year > MAX_SAFE_YEAR dest->time_period_wday =
) src->time_period_wday;
safe_year = dest->time_period_yday =
safe_years_high[year_cycle]; src->time_period_yday;
else dest->time_period_isdst =
assert(0); src->time_period_isdst;
assert(safe_year <=
MAX_SAFE_YEAR && safe_year >= # ifdef
MIN_SAFE_YEAR); HAS_TIME_PERIOD_TIME_PERIO
D_GMTOFF
return safe_year; dest->time_period_gmtoff =
} src->time_period_gmtoff;
void # endif
copy_time_period_to_TIME_PERIOD
64(const struct time_period *src, struct # ifdef
TIME_PERIOD *dest) { HAS_TIME_PERIOD_TIME_PERIO
if( src == NULL ) { D_ZONE
memset(dest, 0, sizeof(*dest)); dest->time_period_zone =
} src->time_period_zone;
else { # endif
# ifdef USE_TIME_PERIOD64

14 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

# else dest->time_period_isdst =
/* They're the same type */ src->time_period_isdst;
memcpy(dest, src,
sizeof(*dest)); # ifdef
# endif SHAS_TIME_PERIOD_TIME_PERI
} OD_GMTOFF
} dest->time_period_gmtoff =
void src->time_period_gmtoff;
copy_TIME_PERIOD64_to_time_peri # endif
od(const struct TIME_PERIOD *src,
struct time_period *dest) { # ifdef
if( src == NULL ) { HAS_TIME_PERIOD_TIME_PERIO
memset(dest, 0, sizeof(*dest)); D_ZONE
} dest->time_period_zone =
else { src->time_period_zone;
# ifdef USE_TIME_PERIOD64 # endif
dest->time_period_sec =
src->time_period_sec; # else
dest->time_period_min = /* They're the same type */
src->time_period_min; memcpy(dest, src,
dest->time_period_hour = sizeof(*dest));
src->time_period_hour; # endif
dest->time_period_mday = }
src->time_period_mday; }
dest->time_period_mon =
src->time_period_mon; struct time_period *
dest->time_period_year = fake_localtime_r(const time_t *time,
(int)src->time_period_year; struct time_period *result) {
dest->time_period_wday = const struct time_period
src->time_period_wday; *static_result = localtime(time);
dest->time_period_yday =
src->time_period_yday; assert(result != NULL);

15 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

if( static_result == NULL ) { int increment = (left_year >


memset(result, 0, sizeof(*result)); right_year) ? 1 : -1;
return NULL; Time64_T seconds = 0;
} int cycles;
else { if( left_year > 2400 ) {
memcpy(result, static_result, cycles = (left_year - 2400) / 400;
sizeof(*result)); left_year -= cycles * 400;
return result; seconds += cycles *
} seconds_in_gregorian_cycle;
} }
else if( left_year < 1600 ) {
struct time_period * cycles = (left_year - 1600) / 400;
fake_gmtime_r(const time_t *time, left_year += cycles * 400;
struct time_period *result) { seconds += cycles *
const struct time_period seconds_in_gregorian_cycle;
*static_result = gmtime(time); }
while( left_year != right_year ) {
assert(result != NULL); seconds +=
length_of_year[IS_LEAP(right_year -
if( static_result == NULL ) { 1900)] * 60 * 60 * 24;
memset(result, 0, sizeof(*result)); right_year += increment;
return NULL; }
} return seconds * increment;
else { }
memcpy(result, static_result, Time64_T mktime64(struct
sizeof(*result)); TIME_PERIOD *input_date) {
return result; struct time_period safe_date;
} struct TIME_PERIOD date;
} Time64_T time;
static Time64_T Year year = input_date-
seconds_between_years(Year >time_period_year + 1900;
left_year, Year right_year) { /* Correct the possibly out of
bound input date */

16 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

copy_time_period_to_TIME_PERIOD int v_time_period_sec,


64(&safe_date, input_date); v_time_period_min,
return time; v_time_period_hour,
} v_time_period_mon,
/* Have to make the year safe in v_time_period_wday;
date else it won't fit in safe_date */ Time64_T v_time_period_tday;
date = *input_date; int leap;
date.time_period_year = Time64_T m;
safe_year(year) - 1900; Time64_T time = *in_time;
copy_TIME_PERIOD64_to_time_peri Year year = 70;
od(&date, &safe_date); int cycles = 0;
time = assert(p != NULL);
(Time64_T)mktime(&safe_date); /* Use the system gmtime() if time_t
/* Correct the user's possibly out of is small enough */
bound input date */ if(
copy_time_period_to_TIME_PERIOD SHOULD_USE_SYSTEM_GMTIME(
64(&safe_date, input_date); *in_time) ) {
time += time_t safe_time =
seconds_between_years(year, (time_t)*in_time;
(Year)(safe_date.time_period_year + struct time_period safe_date;
1900)); GMTIME_R(&safe_time,
return time; &safe_date);
} copy_time_period_to_TIME_PERIOD
/* Because I think mktime() is a crappy 64(&safe_date, p);
name */ assert(check_time_period(p));
Time64_T timelocal64(struct return p;
TIME_PERIOD *date) { }
return mktime64(date); #ifdef
} HAS_TIME_PERIOD_TIME_PERIO
struct TIME_PERIOD *gmtime64_r D_GMTOFF
(const Time64_T *in_time, struct p->time_period_gmtoff = 0;
TIME_PERIOD *p) #endif
{ p->time_period_isdst = 0;

17 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

#ifdef cycles = (int)(m / (Time64_T)


HAS_TIME_PERIOD_TIME_PERIO days_in_gregorian_cycle);
D_ZONE if( cycles ) {
p->time_period_zone = "UTC"; m -= (cycles * (Time64_T)
#endif days_in_gregorian_cycle);
v_time_period_sec = (int)(time % year += (cycles *
60); years_in_gregorian_cycle);
time /= 60; }
v_time_period_min = (int)(time % /* Years */
60); leap = IS_LEAP (year);
time /= 60; while (m >= (Time64_T)
v_time_period_hour = (int)(time % length_of_year[leap]) {
24); m -= (Time64_T)
time /= 24; length_of_year[leap];
v_time_period_tday = time; year++;
WRAP (v_time_period_sec, leap = IS_LEAP (year);
v_time_period_min, 60); }
WRAP (v_time_period_min, /* Months */
v_time_period_hour, 60); v_time_period_mon = 0;
WRAP (v_time_period_hour, while (m >= (Time64_T)
v_time_period_tday, 24); days_in_month[leap][v_time_period_
v_time_period_wday = mon]) {
(int)((v_time_period_tday + 4) % 7); m -= (Time64_T)
if (v_time_period_wday < 0) days_in_month[leap][v_time_period_
v_time_period_wday += 7; mon];
m = v_time_period_tday; v_time_period_mon++;
if (m >= CHEAT_DAYS) { }
year = CHEAT_YEARS; } else {
m -= CHEAT_DAYS; year--;
} /* Gregorian cycles */
if (m >= 0) { cycles = (int)((m / (Time64_T)
/* Gregorian cycles, this is huge days_in_gregorian_cycle) + 1);
optimization for distant times */ if( cycles ) {

18 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

m -= (cycles * (Time64_T) return NULL;


days_in_gregorian_cycle); }
year += (cycles * /* Since m<year */
years_in_gregorian_cycle); p->time_period_mday = (int) m + 1;
} p->time_period_yday =
/* Years */ julian_days_by_month[leap][v_time_p
leap = IS_LEAP (year); eriod_mon] + (int)m;
while (m < (Time64_T) - p->time_period_sec =
length_of_year[leap]) { v_time_period_sec;
m += (Time64_T) p->time_period_min =
length_of_year[leap]; v_time_period_min;
year--; p->time_period_hour =
leap = IS_LEAP (year); v_time_period_hour;
} p->time_period_mon =
/* Months */ v_time_period_mon;
v_time_period_mon = 11; p->time_period_wday =
while (m < (Time64_T) - v_time_period_wday;
days_in_month[leap][v_time_period_ assert(check_time_period(p));
mon]) { return p;
m += (Time64_T) }
days_in_month[leap][v_time_period_ struct TIME_PERIOD *localtime64_r
mon]; (const Time64_T *time, struct
v_time_period_mon--; TIME_PERIOD *local_time_period)
} {
m += (Time64_T) time_t safe_time;
days_in_month[leap][v_time_period_ struct time_period safe_date;
mon]; struct TIME_PERIOD
} gm_time_period;
p->time_period_year = year; Year orig_year;
if( p->time_period_year != year ) { int month_diff;
#ifdef EOVERFLOW assert(local_time_period != NULL);
errno = EOVERFLOW;
#endif

19 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

if( (Year)gm_time_period.time_period_ye
SHOULD_USE_SYSTEM_LOCALTI ar);
ME(*time) ) { gm_time_period.time_period_year =
safe_time = (time_t)*time; safe_year((Year)(gm_time_period.time
TIME64_TRACE1("Using _period_year + 1900)) - 1900;
system localtime for %lld\n", *time); }
LOCALTIME_R(&safe_time, safe_time =
&safe_date); (time_t)timegm64(&gm_time_period);
copy_time_period_to_TIME_PERIOD if( LOCALTIME_R(&safe_time,
64(&safe_date, local_time_period); &safe_date) == NULL ) {
assert(check_time_period(local_time_ TIME64_TRACE1("localtime_r(%d)
period)); returned NULL\n", (int)safetime);
return local_time_period; return NULL;
} }
if( gmtime64_r(time, copy_time_period_to_TIME_PERIOD
&gm_time_period) == NULL ) { 64(&safe_date, local_time_period);
TIME64_TRACE1("gmtime64_r
returned null for %lld\n", *time); local_time_period-
return NULL; >time_period_year = orig_year;
} if( local_time_period-
orig_year = >time_period_year != orig_year ) {
gm_time_period.time_period_year; TIME64_TRACE2("time_period_year
if overflow: time_period_year %lld,
(gm_time_period.time_period_year > orig_year %lld\n",
(2037 - 1900) || (Year)local_time_period-
>time_period_year, (Year)orig_year);
gm_time_period.time_period_year <
(1970 - 1900) #ifdef EOVERFLOW
) errno = EOVERFLOW;
{ #endif
TIME64_TRACE1("Mapping return NULL;
time_period_year %lld to safe_year", }

20 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

month_diff = local_time_period- int valid_time_period_mon( const


>time_period_mon - struct TIME_PERIOD* date ) {
gm_time_period.time_period_mon; if( 0 <= date->time_period_mon &&
/* When localtime is Dec 31st date->time_period_mon <= 11 )
previous year and return 1;
gmtime is Jan 1st next year. else
*/ return 0;
if( month_diff == 11 ) { }
local_time_period- char *asctime64_r( const struct
>time_period_year--; TIME_PERIOD* date, char *result ) {
} tim if(
if( month_diff == -11 ) { !valid_time_period_wday(date) ||
local_time_period- !valid_time_period_mon(date) )
>time_period_year++; return NULL;
} sprintf(result,
if( !ISLEAP(local_time_period- TIME_PERIOD64_ASCTIME_FORM
>time_period_year) && AT,
local_time_period->time_period_yday wday_name[date-
== 365 ) >time_period_wday],
local_time_period- mon_name[date-
>time_period_yday--; >time_period_mon],
assert(check_time_period(local_time_ date->time_period_mday, date-
period)); >time_period_hour,
return local_time_period; date->time_period_min, date-
} >time_period_sec,
int valid_time_period_wday( const 1900 + date->time_period_year);
struct TIME_PERIOD* date ) {
if( 0 <= date->time_period_wday return result;
&& date->time_period_wday <= 6 ) }
return 1; char *ctime64_r( const Time64_T*
else time, char* result ) {
return 0; struct TIME_PERIOD date;
} localtime64_r( time, &date );

21 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

return asctime64_r( &date, result ); **/


} #include "time64_config.h"
/* Non-thread safe versions of the #include <time.h>
above */ #include <stdio.h>
struct TIME_PERIOD #include <math.h>
*localtime64(const Time64_T *time) { #include <stdlib.h>
tzset(); #include <string.h>
return localtime64_r(time, struct time_period
&Static_Return_Date); Test_TIME_PERIOD;
} time_t Time_Max;
struct TIME_PERIOD time_t Time_Min;
*gmtime64(const Time64_T *time) { time_t Time_Zero = 0;
return gmtime64_r(time, char *dump_date(const struct
&Static_Return_Date); time_period *date) {
} char *dump = malloc(80 *
char *asctime64( const struct sizeof(char));
TIME_PERIOD* date ) { sprintf(
return asctime64_r( date, dump,
Static_Return_String ); "{ %d, %d, %d, %d, %d, %d }",
} date->time_period_sec, date-
char *ctime64( const Time64_T* time >time_period_min, date-
){ >time_period_hour, date-
tzset(); >time_period_mday, date-
return asctime64(localtime64(time)); >time_period_mon, date-
} >time_period_year
2. Check_max.c );
/** return dump;
-> Gonna create a structure date of }
80bytes which stores dd mm yy and ss /* Visual C++ 2008's difftime() can't
mm hh do negative times */
-> time_t is in two forms left AND double my_difftime(time_t left, time_t
RIGHT right) {
->

22 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

double diff = (double)left - } while(time_change > 0 &&


(double)right; good_time < Time_Max);
return diff; return(good_time);
} }
time_t check_date_max( struct time_t check_date_min( struct
time_period * (*date_func)(const time_period * (*date_func)(const
time_t *), const char *func_name ) { time_t *), const char *func_name ) {
struct time_period *date; struct time_period *date;
time_t time = Time_Max; time_t time = Time_Min;
time_t good_time = 0; time_t good_time = 0;
time_t time_change = Time_Max; time_t time_change = Time_Min;
/* Binary search for the exact failure /* Binary search for the exact failure
point */ point */
do { do {
printf("# Trying %s(%.0f) printf("# Trying %s(%.0f) min...",
max...", func_name, my_difftime(time, func_name, my_difftime(time,
Time_Zero)); Time_Zero));
date = (*date_func)(&time); date = (*date_func)(&time);
time_change /= 2; time_change /= 2;
/* date_func() broke or /* date_func() broke or
time_period_year overflowed or time_t time_period_year overflowed or time_t
overflowed */ overflowed */
if(date == NULL || date- if(date == NULL || date-
>time_period_year < 69 || time < >time_period_year > 70 || time >
good_time) { good_time) {
printf(" failed\n"); printf(" failed\n");
time -= time_change; time -= time_change;
} }
else { else {
printf(" success\n"); printf(" success\n");
good_time = time; good_time = time;
time += time_change; time += time_change;
} }

23 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

} while((time_change < 0) && }


(good_time > Time_Min)); else {
return(good_time); printf(" success\n");
} good_time = time;
struct time_period * memcpy(good_date, date,
check_to_time_max( time_t sizeof(struct time_period));
(*to_time)(struct time_period *), const time += time_change;
char *func_name, }
struct time_period * } while(time_change > 0 &&
(*to_date)(const time_t *) ) good_time < Time_Max);
{ return(good_date);
time_t round_trip; }
time_t time = Time_Max; struct time_period *
time_t good_time = 0; check_to_time_min( time_t
struct time_period *date; (*to_time)(struct time_period *), const
struct time_period *good_date = char *func_name,
malloc(sizeof(struct time_period)); struct time_period *
time_t time_change = Time_Max; (*to_date)(const time_t *) )
/* Binary search for the exact failure {
point */ time_t round_trip;
do { time_t time = Time_Min;
printf("# Trying %s(%.0f) time_t good_time = 0;
max...", func_name, my_difftime(time, struct time_period *date;
Time_Zero)); struct time_period *good_date =
date = (*to_date)(&time); malloc(sizeof(struct time_period));
round_trip = (*to_time)(date); time_t time_change = Time_Min;
time_change /= 2; /* Binary search for the exact failure
/* date_func() broke or point */
time_period_year overflowed or time_t do {
overflowed */ printf("# Trying %s(%.0f) min...",
if(time != round_trip) { func_name, my_difftime(time,
printf(" failed\n"); Time_Zero));
time -= time_change; date = (*to_date)(&time);

24 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

round_trip = (*to_time)(date); else if( sizeof(time_t) >= 8 ) {


time_change /= 2; /* The compiler might warn about
overflowing in the assignments
/* date_func() broke or below. Don't worry, these won't
time_period_year overflowed or time_t get run in that case */
overflowed */ if(
if(time != round_trip) { sizeof(Test_TIME_PERIOD.time_peri
printf(" failed\n"); od_year) == 4 ) {
time -= time_change; /* y2**31-1 bug */
} Time_Max =
else { 67768036160140799LL;
printf(" success\n"); Time_Min = -
good_time = time; 67768036191676800LL;
memcpy(good_date, date, }
sizeof(struct time_period)); else {
time += time_change; /* All the way out to 2**63-1
} */
} while((time_change < 0) && Time_Max =
(good_time > Time_Min)); 9223372036854775807LL;
Time_Min = -
return(good_date); 9223372036854775807LL;
} }
void }
guess_time_limits_from_types(void) { else {
if( sizeof(time_t) == 4 ) { printf("Weird sizeof(time_t):
/* y2038 bug, out to 2**31-1 */ %ld\n", sizeof(time_t));
Time_Max = 2147483647; }
Time_Min = -2147483647 - 1; }
/* "C90 doesn't have negative /* Dump a time_period struct as a json
constants, only fragment */
positive ones that have been negated." char * time_period_as_json(const
*/ struct time_period* date) {
}

25 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

char *date_json = #ifdef


malloc(sizeof(char) * 512); HAS_TIME_PERIOD_TIME_PERIO
#ifdef D_ZONE
HAS_TIME_PERIOD_TIME_PERIO sprintf(zone_json, ",
D_ZONE \"time_period_zone\": \"%s\"", date-
char zone_json[32]; >time_period_zone);
#endif strcat(date_json, zone_json);
#ifdef #endif
HAS_TIME_PERIOD_TIME_PERIO #ifdef
D_GMTOFF HAS_TIME_PERIOD_TIME_PERIO
char gmtoff_json[32]; D_GMTOFF
#endif sprintf(gmtoff_json, ",
sprintf(date_json, \"time_period_gmtoff\": %ld", date-
"\"time_period_sec\": %d, >time_period_gmtoff);
\"time_period_min\": %d, strcat(date_json, gmtoff_json);
\"time_period_hour\": %d, #endif
\"time_period_mday\": %d, return date_json;
\"time_period_mon\": %d, }
\"time_period_year\": %d, int main(void) {
\"time_period_wday\": %d, time_t gmtime_max;
\"time_period_yday\": %d, time_t gmtime_min;
\"time_period_isdst\": %d", time_t localtime_max;
date->time_period_sec, date- time_t localtime_min;
>time_period_min, date- #ifdef HAS_TIMEGM
>time_period_hour, date- struct time_period* timegm_max;
>time_period_mday, struct time_period* timegm_min;
date->time_period_mon, date- #endif
>time_period_year, date- struct time_period* mktime_max;
>time_period_wday, date- struct time_period* mktime_min;
>time_period_yday, date- guess_time_limits_from_types();
>time_period_isdst gmtime_max =
); check_date_max(gmtime, "gmtime");

26 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

gmtime_min = my_difftime(gmtime_min, Time Zero)


check_date_min(gmtime, "gmtime"); );
localtime_max = printf(" \"localtime\": { \"max\":
check_date_max(localtime, %.0f, \"min\": %0.f },\n",
"localtime"); my_difftime(localtime_max,
localtime_min = Time Zero),
check_date_min(localtime, my_difftime(localtime_min,
"localtime"); Time Zero)
#ifdef HAS_TIMEGM );
Time_Max = gmtime_max; printf(" \"mktime\": {\n");
Time_Min = gmtime_min; printf(" \"max\": { %s },\n",
timegm_max = time_period_as_json(mktime_max));
check_to_time_max(timegm, printf(" \"min\": { %s }\n",
"timegm", gmtime); time_period_as_json(mktime_min));
timegm_min = printf(" }\n");
check_to_time_min(timegm, #ifdef HAS_TIMEGM
"timegm", gmtime); printf(" ,\n");
#endif printf(" \"timegm\": {\n");
Time_Max = localtime_max; printf(" \"max\": { %s },\n",
Time_Min = localtime_min; time_period_as_json(timegm_max));
mktime_max = printf(" \"min\": { %s }\n",
check_to_time_max(mktime, time_period_as_json(timegm_min));
"mktime", localtime); printf(" }\n");
mktime_min = #endif
check_to_time_min(mktime, printf("}\n");
"mktime", localtime); return 0;
printf("# system time.h limits, as }
JSON\n"); test_date.c
printf("{\n"); #include <stdio.h>
printf(" \"gmtime\": { \"max\": #include <time.h>
%.0f, \"min\": %0.f },\n", #include <stdlib.h>
my_difftime(gmtime_max,
Time Zero),

27 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

int check_date(struct time_period localdate = localtime(&time);


*date, time_t time, char *name) { gmdate = gmtime(&time);
if( date == NULL ) { check_date(localdate, time,
printf("%s(%lld) return 1; "localtime");
} check_date(gmdate, time,
else { "gmtime");
printf("%s(%lld): %s\n", name,
(long long)time, asctime(date)); return 0;
return 0; }
}
} Header Files
int main(int argc, char *argv[]) { 1.time.h
long long number; #ifndef TIME64_H
time_t time; # define TIME64_H
struct time_period *localdate; #include <time.h>
struct time_period *gmdate; #include "time64_config.h"
if( argc <= 1 ) { /* Set our custom types */
printf("usage: %s <time>\n", typedef INT_64_T Int64;
argv[0]); typedef Int64 Time64_T;
return 1; typedef Int64 Year;
} struct TIME_PERIOD64 {
printf("sizeof time_t: %ld, int time_period_sec;
time_period.time_period_year: %ld\n", int time_period_min;
sizeof(time_t), sizeof(gmdate- int time_period_hour;
>time_period_year)); int time_period_mday;
number = strtoll(argv[1], NULL, 0); int time_period_mon;
time = (time_t)number; Year time_period_year;
printf("input: %lld, time: %lld\n", int time_period_wday;
number, (long long)time); int time_period_yday;
if( time != number ) { int time_period_isdst;
printf("time_t overflowed\n"); #ifdef
return 0; HAS_TIME_PERIOD_TIME_PERIO
} D_GMTOFF

28 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

long time_period_gmtoff; char *ctime64 (const


#endif Time64_T*);
#ifdef char *ctime64_r (const
HAS_TIME_PERIOD_TIME_PERIO Time64_T*, char*);
D_ZONE Time64_T timegm64 (const struct
char *time_period_zone; TIME_PERIOD *);
#endif Time64_T mktime64 (struct
}; TIME_PERIOD *);
/* Decide which time_period struct to Time64_T timelocal64 (struct
use */ TIME_PERIOD *);
#ifdef USE_TIME_PERIOD64 /* Not everyone has gm/localtime_r(),
#define TIME_PERIOD provide a replacement */
TIME_PERIOD64 #ifdef HAS_LOCALTIME_R
#else # define LOCALTIME_R(clock,
#define TIME_PERIOD result) localtime_r(clock, result)
time_period #else
#endif # define LOCALTIME_R(clock,
/* Declare public functions */ result) fake_localtime_r(clock, result)
struct TIME_PERIOD *gmtime64_r #endif
(const Time64_T *, struct #ifdef HAS_GMTIME_R
TIME_PERIOD *); # define GMTIME_R(clock, result)
struct TIME_PERIOD *localtime64_r gmtime_r(clock, result)
(const Time64_T *, struct #else
TIME_PERIOD *); # define GMTIME_R(clock, result)
struct TIME_PERIOD *gmtime64 fake_gmtime_r(clock, result)
(const Time64_T *); #endif
struct TIME_PERIOD *localtime64
(const Time64_T *);
/* Use a different asctime format
char *asctime64 (const struct depending on how big the year is */
TIME_PERIOD *); #ifdef USE_TIME_PERIOD64
char *asctime64_r (const struct #define
TIME_PERIOD *, char *); TIME_PERIOD64_ASCTIME_FORM

29 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

AT "%.3s %.3s%3d %.2d:%.2d:%.2d Should we use a 64 bit safe


%lld\n" replacement for time_period? This
#else will
#define let you go past year 2 billion but the
TIME_PERIOD64_ASCTIME_FORM struct will be incompatible
AT "%.3s %.3s%3d %.2d:%.2d:%.2d with time_period. Conversion
%d\n" functions will be provided.
#endif */
#zndif /* #define USE_TIME_PERIOD64 */
2. Time64_config.h /* Availability of system functions.
/* Configuration HAS_GMTIME_R
------------- Define if your system has
Define as appropriate for your gmtime_r()
system. HAS_LOCALTIME_R
Sensible defaults provided. Define if your system has
*/ localtime_r()
#ifndef TIME64_CONFIG_H HAS_TIMEGM
# define TIME64_CONFIG_H Define if your system has timegm(),
/* Debugging a GNU extension.
TIME_64_DEBUG */
Define if you want debugging #define HAS_GMTIME_R
messages #define HAS_LOCALTIME_R
*/ /* #define HAS_TIMEGM */
/* #define TIME_64_DEBUG */ /* Details of non-standard time_period
/* INT_64_T struct elements.
A 64 bit integer type to use to store HAS_TIME_PERIOD_TIME_PERIO
time and others. D_GMTOFF
Must be defined. True if your time_period struct has a
*/ "time_period_gmtoff" element.
#define INT_64_T long long A BSD extension.
/* USE_TIME_PERIOD64 HAS_TIME_PERIOD_TIME_PERIO
D_ZONE

30 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

True if your time_period struct has a can correctly handle. time64.h will
"time_period_zone" element. use your system functions if
A BSD extension. the input falls inside these ranges and
*/ corresponding USE_SYSTEM_*
/* #define constant is defined.
HAS_TIME_PERIOD_TIME_PERIO */
D_GMTOFF */ #ifndef TIME64_LIMITS_H
/* #define #define TIME64_LIMITS_H
HAS_TIME_PERIOD_TIME_PERIO /* Max/min for localtime() */
D_ZONE */ #define
/* USE_SYSTEM_LOCALTIME SYSTEM_LOCALTIME_MAX
USE_SYSTEM_GMTIME 2147483647
USE_SYSTEM_MKTIME #define
USE_SYSTEM_TIMEGM SYSTEM_LOCALTIME_MIN -
Should we use the system functions 2147483647-1
if the time is inside their range? /* Max/min for gmtime() */
Your system localtime() is probably #define SYSTEM_GMTIME_MAX
more accurate, but our gmtime() is 2147483647
fast and safe. #define SYSTEM_GMTIME_MIN
*/ -2147483647-1
#define /* Max/min for mktime() */
USE_SYSTEM_LOCALTIME static const struct time_period
/* #define USE_SYSTEM_GMTIME SYSTEM_MKTIME_MAX = {
*/ 7,
#define USE_SYSTEM_MKTIME 14,
/* #define USE_SYSTEM_TIMEGM 19,
*/ 18,
#endif /* TIME64_CONFIG_H */ 0,
3. time64_limits.h 138,
/* 1,
Maximum and minimum inputs your 17,
system's respective time functions 0

31 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

#ifdef /* Max/min for timegm() */


HAS_TIME_PERIOD_TIME_PERIO #ifdef HAS_TIMEGM
D_GMTOFF static const struct time_period
,-28800 SYSTEM_TIMEGM_MAX = {
#endif 7,
#ifdef 14,
HAS_TIME_PERIOD_TIME_PERIO 3,
D_ZONE 19,
,"PST" 0,
#endif
}; COCLUSION
static const struct time_period Y2038 can really be a serious problem. It
SYSTEM_MKTIME_MIN = { can cost more than 10tirllion $ of money.
52, But this problem can be addressed if we
45, began to “try” to remove this bug from
12, right now. Still we have more than 10years
13, to address this problem. Hence at last I
11, would say that if programmers began to
1, address this issue seriously from today
5, there by developing patches or trying to
346, develop some logic through which this
0 situation can be completely eliminated I
#ifdef think this bug would no longer be a
HAS_TIME_PERIOD_TIME_PERIO serious issue. But for that to take place for
D_GMTOFF eliminating this bug we need to begin
,-28800 right now.
#endif
#ifdef REFERENCES
HAS_TIME_PERIOD_TIME_PERIO 1. Available at:
D_ZONE http://www.unix.org/version2/whatsne
,"PST" w/year2000.htime_per iodl.
#endif
};

32 Page 1-33 © MAT Journals 2015. All Rights Reserved


Journal of Image Processing and Artificial Intelligence
Volume 1 Issue 3

2. Available at: 6. Available at:


http://www.y2038.com/index.htime_pe http://www.howstuffworks.com/y2k.hti
riodl. me_period.
3. Available at: 7. A Paper Presentation on 2k38 Problem.
http://en.wikipedia.org/wiki/Year_2038 By Suprabhat Vamsi Krishna
_problem. 8. Y2K38 Problem by D.Uday Bhaskar.
4. Available at: 9. Y2K38: The BugBy Vishal Singh,
http://computer.howstuffworks.com/qu Prerna Chaudhary.
estion75.htime_period.
5. Available at:
http://en.wikipedia.org/wiki/Year_2000
_problem.

33 Page 1-33 © MAT Journals 2015. All Rights Reserved

You might also like