One of the things which concerns me is the ways that some of the BBS
software are going to mangle datestamps after the end of this year.
Whilst this isn't exclusively a Linux issue, it affects some Linux
packages, and raising the visibility of the problem can only help.
The press would have us believe that the Y2000 problem is because
computers will see the year go from '99' to '00'. If only it were
that simple - various packages will see the year go from '99' to:
00
100
0
:0
and I'm sure there are other variations too.
In the BBS system, there is a date/timestamp which ought to look
like:
YYMMDD/hhmmZ
Things have been fine up to now, but from the end of this year
the code that generates the date/timestamp could be in trouble.
For example, try the code attached as 'date.c'. It has a few
sample ways of creating the date/timestamp - all work currently,
but many will fail next year (apologies to those who recognise
their own code in these samples, but only you know who you are :-).
I think that code writers need to be careful when parsing the BBS
date/timestamp information. Try the code attached as 'scandate.c'
to see what could happen. Then put your hand on your heart, and
think whether you ever check the return code from sscanf()...
I reckon all code which parses the date/timestamp should look
for the '/', and work forwards and backwards from that position.
There are plenty of BBS operators who can't or won't upgrade their
BBS software, so we'll be seeing plenty of bad date/timestamps
from 1/1/2000 (or however it gets represented!).
73, Andrew G8FSL
--
Andrew Benham [EMAIL PROTECTED]
Nortel Networks, London Road, Harlow, Essex CM17 9NA, United Kingdom
Tel: +44 1279 402372 Fax: +44 1279 405746
I speak for myself, my views are not necessarily the views
of Nortel Networks or any other corporation.
#include <stdio.h>
#include <time.h>
#define SECONDS_IN_YEAR (365*86400L)
void print_timestamps(struct tm *);
int main(void)
{
time_t t;
struct tm *tb;
puts("A variety of ways of doing timestamps");
time(&t);
tb=localtime(&t);
puts("For 1999: they all give the same result");
print_timestamps(tb);
t += SECONDS_IN_YEAR;
tb=localtime(&t);
puts("\nFor 2000: hmm....");
print_timestamps(tb);
}
void print_timestamps(struct tm *tb)
{
char buffer[14];
/* The right way to get two digit years */
printf("%02d%02d%02d/%02d%02dZ\n",tb->tm_year % 100,
tb->tm_mon +1, tb->tm_mday,tb->tm_hour,tb->tm_min);
/* Forgetting that tm_year = 100 for 2000 A.D. */
printf("%02d%02d%02d/%02d%02dZ\n",tb->tm_year, tb->tm_mon +1,
tb->tm_mday,tb->tm_hour,tb->tm_min);
/* Forgetting the year needs a leading 0 */
printf("%d%02d%02d/%02d%02dZ\n",tb->tm_year % 100,
tb->tm_mon +1, tb->tm_mday,tb->tm_hour,tb->tm_min);
/* The right way with snprintf() */
snprintf(buffer,13,"%02d%02d%02d/%02d%02dZ",tb->tm_year % 100,
tb->tm_mon +1, tb->tm_mday,tb->tm_hour,tb->tm_min);
puts(buffer);
/* Want 13 characters, but the year field is too wide & we lose the Z */
snprintf(buffer,13,"%02d%02d%02d/%02d%02dZ",tb->tm_year, tb->tm_mon +1,
tb->tm_mday,tb->tm_hour,tb->tm_min);
puts(buffer);
snprintf(buffer,13,"%d%02d%02d/%02d%02dZ",tb->tm_year % 100,
tb->tm_mon +1, tb->tm_mday,tb->tm_hour,tb->tm_min);
puts(buffer);
}
#include <stdio.h>
#include <string.h>
void print_timestamp(char *);
int main(void)
{
char timestamp[15];
puts("A 1999 timestamp:");
strcpy(timestamp,"990109/1234Z");
print_timestamp(timestamp);
puts("And now some 2000 timestamps:");
strcpy(timestamp,"000109/1234Z");
print_timestamp(timestamp);
strcpy(timestamp,"1000109/1234Z");
print_timestamp(timestamp);
strcpy(timestamp,"00109/1234Z");
print_timestamp(timestamp);
strcpy(timestamp,"1000109/1234");
print_timestamp(timestamp);
puts("\nEven if 5 fields are read OK, it isn't necessarily right");
}
void print_timestamp(char *string)
{
/* Initialise each time variable to a bad value.
* How often do people do this ? */
int year = -1, month = -1, day = -1, hour = -1, minute = -1;
int read_ok;
/* How often do people check the return value from scanf() ?? */
read_ok=sscanf(string,"%02d%02d%02d/%02d%02dZ",&year,&month,&day,&hour,&minute);
printf("%13s -> %02d:%02d %02d/%02d/%02d (read %d fields OK)\n",
string,hour,minute,day,month,year,read_ok);
}