Convert characters to Date

N

Nimmy

Hi,

I have a file which has different dates, I want to scanf them as CHAR and
convert them to DATE format, how can I do this?

Thanks
 
M

Mike Wahler

Nimmy said:
Hi,

I have a file which has different dates, I want to scanf them as CHAR

C does not have a type 'CHAR', but it does have 'char'.
and
convert them to DATE format,

C does not have a type 'DATE', but the standard library
provides a few formats for storing dates. See the functions
declared by said:
how can I do this?

This depends entirely upon what text format you've used to
store your dates.

-Mike
 
N

Nimmy

Apologies,
I mean by 'char', my date format is 01/04/2004 like dd/mm/yyyy (british
style),

how this will be transformed into struct tm mydate and I want to mydate to
get the above 01/04/2004...

I have seen time.h, then I decided to do as follow:

t.tm_mday = 01; /* Day of the Month */
t.tm_mon = 03; /* Month */ <FOR APRIL 03???>> Yes that's what it
says...
t.tm_year = (2004-1900)=104; /* Year - does not include century */ 104
+ 1900
/* I don't want the rest of them but it seems to be mandatory */
t.tm_wday = 4; /* Day of the week */
t.tm_yday = 0; /* Does not show in asctime */
t.tm_isdst = 0; /* Is Daylight SavTime; does not show in asctime */

Of course in this case, I will be getting the date, month and year in INT
format,

Still it is not exactly working what I want....
Any help?
 
E

Eric Sosman

Nimmy said:
Hi,

I have a file which has different dates, I want to scanf them as CHAR and
convert them to DATE format, how can I do this?

First, neither the C language nor its library supports
anything called a CHAR or a DATE. I can guess that by "CHAR"
you mean "character string," or more exactly "zero-terminated
array of `char'." But I don't know what you mean by "DATE,"
as there are at least three plausible possibilities:

- A `struct tm' value expressing a date
- A `time_t' value expressing a date
- A character string expressing a date

.... and perhaps others of your imagining.

Second, you haven't described just how your "file has
different dates." What form are they in? What do they
look like? Some possibilities:

- 07/04/2004: Independence Day, USA-style

- 14/07/2004: Bastille Day, European-style

- 07/04/04: Independence Day, in one of the years 1804,
1904, 2004, ...

- 2004-11-02: USA Election Day, ISO-style

- Wed Jul 14, 2004: Bastille Day, easy-readin' style

- Ides Martius: March 15th, in an unspecified year

.... and of course there are many more. You will have to be
much more specific if you expect to get solutions for your
problem instead of for some other problem we might guess you
have.
 
A

Al Bowers

Nimmy said:
Apologies,
I mean by 'char', my date format is 01/04/2004 like dd/mm/yyyy (british
style),

how this will be transformed into struct tm mydate and I want to mydate to
get the above 01/04/2004...

I have seen time.h, then I decided to do as follow:

t.tm_mday = 01; /* Day of the Month */
t.tm_mon = 03; /* Month */ <FOR APRIL 03???>> Yes that's what it
says...
t.tm_year = (2004-1900)=104; /* Year - does not include century */ 104
+ 1900
/* I don't want the rest of them but it seems to be mandatory */
t.tm_wday = 4; /* Day of the week */
t.tm_yday = 0; /* Does not show in asctime */
t.tm_isdst = 0; /* Is Daylight SavTime; does not show in asctime */

Of course in this case, I will be getting the date, month and year in INT
format,

What do you mean "getting the date, month and year in INT format"?

Your assignments to the struct members seems fine. Next use function
mktime to get a time_t value which you can use to display the time, or
for other purposes.

Still it is not exactly working what I want....
Any help?

Try this:

#include <stdio.h>
#include <string.h>
#include <time.h>

int main(void)
{
char *chardate[2] = {"01/04/2004","01/04/04"};
int mday,mon,yr,i;
struct tm mydate = {0};
time_t date;

for(i = 0; i < 2;i++)
{
if(3 == sscanf(chardate,"%d/%d/%d",&mday,&mon,&yr))
{
mon--;
if(yr < 100) yr += 100;
else yr -= 1900;
mydate.tm_year = yr;
mydate.tm_mon = mon;
mydate.tm_mday = mday;
date = mktime(&mydate);
}
if(date != (time_t)-1)
printf("\"%s\" converts to %s\n",
chardate,ctime(&date));
else puts("The date is unavailable\n");
}
return 0;
}
 
M

Mike Wahler

Nimmy said:
Apologies,
I mean by 'char', my date format is 01/04/2004 like dd/mm/yyyy (british
style),

how this will be transformed into struct tm mydate and I want to mydate to
get the above 01/04/2004...

I have seen time.h, then I decided to do as follow:

t.tm_mday = 01; /* Day of the Month */
t.tm_mon = 03; /* Month */ <FOR APRIL 03???>> Yes that's what it
says...
t.tm_year = (2004-1900)=104; /* Year - does not include century */ 104
+ 1900
/* I don't want the rest of them but it seems to be mandatory */
t.tm_wday = 4; /* Day of the week */
t.tm_yday = 0; /* Does not show in asctime */
t.tm_isdst = 0; /* Is Daylight SavTime; does not show in asctime */

Of course in this case, I will be getting the date, month and year in INT
format,

Still it is not exactly working what I want....

If you have code that doesn't produce the result you want:
a) Post the *complete* code.
b) Tell us *exactly* the result you want, and what you got instead.
Any help?

Maybe you can use this:

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

enum component {DAY = 1, MONTH, YEAR};
const int BAD_VALUE = -1;

int date_item(const char *s, char delim, enum component which)
{
long result = 0;
char *d = (char *)s;
char *end = NULL;
errno = 0;

switch(which)
{
case DAY:
result = strtol(d, &end, 10);
break;

case MONTH:
if(d = strchr(d, delim))
result = strtol(++d, &end, 10) - 1;
break;

case YEAR:
if (d = strchr(d, delim))
if(d = strchr(++d, delim))
result = strtol(++d, &end, 10);
break;

default:
end = d;
break;
}

return ((d == end) || (errno == ERANGE)) ? BAD_VALUE : (int)result;
}

struct tm* date(const char *s, char delim, unsigned int dst)
{
static struct tm dt = {0};
dt.tm_mday = date_item(s, delim, DAY);
dt.tm_mon = date_item(s, delim, MONTH);
dt.tm_year = date_item(s, delim, YEAR);

if(dt.tm_year != BAD_VALUE)
dt.tm_year -= 1900;

dt.tm_isdst = dst;

return dt.tm_mday != BAD_VALUE &&
dt.tm_mon != BAD_VALUE &&
dt.tm_year != BAD_VALUE
? &dt : NULL;
}

void show_date(struct tm *date)
{
if(mktime(date) != (time_t)-1)
{
printf("date->tm_mday == %d\n"
"date->tm_mon == %d\n"
"date->tm_year == %d\n",
date->tm_mday,
date->tm_mon,
date->tm_year);

putchar('\n');
printf("%s\n", asctime(date));
}
else
fprintf(stderr, "Data outside representable range\n");
}

int main(void)
{
FILE *input = NULL;
char buffer[100] = {0};
struct tm mydate = {0};
struct tm *dt = NULL;

input = fopen("mydate.txt", "r");
if(input == NULL)
{
fprintf(stderr, "Cannot open input\n");
return EXIT_FAILURE;
}

if(fgets(buffer, sizeof buffer, input) == NULL)
{
fprintf(stderr, "Error reading input or no input\n");
return EXIT_FAILURE;
}

fclose(input);
dt = date(buffer, '/', 0);

if(dt)
{
mydate = *dt;
show_date(&mydate);
}
else
fprintf(stderr, "Invalid data\n");

return 0;
}


Input file 'mydate.txt':

01/04/2004


Output:

date->tm_mday == 1
date->tm_mon == 3
date->tm_year == 104

Thu Apr 01 00:00:00 2004



-Mike
 
M

Mike Wahler

Nimmy said:
Hi,

I have a file which has different dates, I want to scanf them as CHAR and
convert them to DATE format, how can I do this?

What's wrong with the answers you already got when
you asked this a few hours ago? The example I posted
uses what Emmanuel recommends, 'fgets()' and 'strtol()'
(they provide a more robust solution than using
'fscanf()' imo). I also see no need for intermediate
storage in a string.

-Mike
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,145
Messages
2,570,824
Members
47,371
Latest member
Brkaa

Latest Threads

Top