How to use the date and time that i get from time.h function - c

Let's say the user is prompted for the date - e.g. Friday.
How can that string be used to correctly compare with another sting?
#include <stdio.h>
#include <time.h>
int main(void)
{
time_t current_time;
struct tm * time_info;
char timeString[9];
time(&current_time);
time_info = localtime(&current_time);
strftime(timeString, sizeof(timeString), "%A", time_info);
printf("%s\n",timeString);
if (timeString == "Friday")
{printf("Weekday");
}
else
{printf("not weekday");
}
return 0;
}
The program keeps printing out not weekday.

Use strncmp() instead of comparing the string with ==:
if (strncmp(timeString,"Friday",7) == 0)
{printf("Weekday");
}
See this in action at tutorialspoint.com:
Friday
Currently, it is Thursday (for ~50% of the world) - so try this one:
Thursday

Related

12-hour AM/PM format to military (24-hour) time

I am trying to solve this task on hackerrank but having problem when submitting solution.
Here is my solution, I would like to someone point me to mistakes, or give me advice what to avoid when working with strings?
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
char clkType[3];
char hours[3];
char* timeConversion(char* s)
{
strncpy(clkType, &s[8], 2);
clkType[2] = '\0';
if(strcmp(clkType, "AM") == 0)
{
s[8] = '\0';
return s;
}
else
{
s[0] += 0x1;
s[1] += 0x2;
s[8] = '\0';
strncpy(hours, &s[0], 2);
hours[2] = '\0';
if(strcmp(hours, "24") == 0)
{
s[0] = '0';
s[1] = '0';
s[8] = '\0';
}
return s;
}
}
int main() {
char* s = (char *)malloc(512000 * sizeof(char));
scanf("%s", s);
int result_size;
char* result = timeConversion(s);
printf("%s\n", result);
return 0;
}
I am getting expected result when I'm testing it with these 04:59:59AM, 12:40:22AM, 12:45:54PM, 12:00:00AM time cases but when submitting results it gives me errors on those test cases.
You have special handling for midnight. You need special handling for noon as well, and you need to fix midnight handling, too.
By convention, 12 AM denotes midnight and 12 PM denotes noon. Your code does it the other way around, converting 12:00:00 AM to 12:00:00 (noon) and 12:00:00 PM to midnight.
One simple way of dealing with time conversion problems is to convert the input to a number of seconds from midnight, and then format this number as the desired output. This approach eliminates character manipulation (adding 12 one digit at a time) and make the code more readable in general.
12 Am translates to 00:00:00 you return as soon as you check for AM you also need to check if it's 12

Time convert from a file and compare to the current time

I've asked something close to this before, but as it seems, the time I get from the file does not convert to the same type of time you get from localtime() and time().
Exactly what I want is:
I have a txt file with the following information
order.txt
file1.txt;5;15:40
file2.txt;7;15:41
file1.txt;10;16:00
My objective is to get the time in hour:min (15:40) and then, if it's the same as the currentTime, then I show the file1.txt content. Otherwise, if the currentTime is lower than the hour:min time (15:40), it waits untill it's 15:40 and shows the file1.txt content. If the currentTime is higher, then it ignores the first one and goes to the next one.
So for example, if the current time is 15:39, it will wait 1 minute and then show the file1.txt content.
If the current Time is 15:40, it shows the file1.txt content without waiting.
If the current Time is 15:41, it just goes to the next one (file2.txt) and checks again.
Used variables
FILE* orderFile;
FILE* contentFile;
FILE* defaultFile; (This will be used when this code works)
char fileName[50];
char textContent[5000];
int seconds;
int hour, min;
int diff_time;
char timeValue[50];
time_t current;
Includes
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
So for that I've tried the following code:
orderFile = fopen("order.txt","r");
defaultFile = fopen("default.txt","r");
while(fscanf(orderFile," %49[^;];%d; %49[^\n]",fileName,&seconds,timeValue)
{
sscanf(timeValue,"%d:%d",&hour,&min);
contentFile = fopen(fileName,"r");
if(contentFile != NULL)
{
fseek (contentFile, 0, SEEK_END);
size = ftell(contentFile);
rewind(contentFile);
if(size == 0)
{
printf("\nEmpty file. (Scanned file: %s)\n", fileName);
fclose(contentFile);
}
else
{
time_t now;
time(&now);
struct tm file_time_tm;
file_time_tm = *localtime(&now);
file_time_tm.tm_hour = hour;
file_time_tm.tm_min = min;
file_time_tm.tm_sec = 0;
file_time_tm.tm_isdst = -1;
time_t fileTime = mktime(&file_time_tm);
double diff_time = difftime(fileTime, now);
if(diff_time == 0)
{
while(fscanf(contentFile,"%[^\t]",textContent) == 1)
{
printf("%s\n", textContent);
}
sleep(seconds);
}
else
{
if(diff_time > 0)
{
while(fscanf(defaultFile,"%[^\t]",defaultContent) == 1)
{
printf("%s\n", defaultContent);
}
sleep(diff_time);
while(fscanf(contentFile,"%[^\t]",textContent) == 1)
{
printf("%s\n", textContent);
}
sleep(seconds);
}
}
fclose(defaultFile);
fclose(contentFile);
}
}
else
{
if(contentFile == NULL)
{
printf("\nFile does not exist. (Scanned file: %s)\n", fileName);
fclose(contentFile);
}
}
}
fclose(orderFile);
printf("\n");
So thanks to chux it is quite working now, yet not fully working.
If I have the following:
Current Time: 15:00
order.txt
file1.txt;5;15:01
file2.txt;6;15:02
file3.txt;3;15:03
When I run the program, the following will occur:
DEFAULT MESSAGE (text inside default.txt)
WAITS DIFF_TIME (CORRECTLY DONE)
SHOWS CONTENT FROM THE file1.txt
WAITS 5 SECONDS
X - SHOWS CONTENT FROM THE file2.txt (This is wrong, it should check again and if the time is 15:02 it will show, not 15:01. Which I assume it's because it is still reading as 15:01 on the timeValue and not 15:02, any idea why?)
WAITS UNTILL IT'S 15:02 (wrong)
SHOWS file3.txt (wrong)
WAITS UNTILL IT'S 15:03
ENDS (wrong as it should not end after waiting, it should end when file3.txt shows and waits for 3 seconds)
Output I need:
DEFAULT MESSAGE
waits diff_time
file1.txt content
waits 5 seconds
DEFAULT MESSAGE
waits diff_time
file2.txt content
waits 7 seconds
DEFAULT MESSAGE
waits diff_time
file3.txt content
waits 3 seconds
ENDS
It also does not work well if I have two files with the same time, such as this:
order.txt
file1.txt;5;15:01
file2.txt;6;15:01
file3.txt;3;15:02
It breaks it aswell.
Any idea of how to do this correctly?
As commented above by #M Oehm, it is apparent the compiler warnings are not fully enabled. Suggest enabling them - it will save you time.
A problem lies in the time compare and subtraction.
// Troublesome code
if(currentTime->tm_hour < hour && currentTime->tm_min < min) {
diff_time = difftime(currentTime,timeValue);
printf("%d - Or this?\n", diff_time);
sleep(diff_time);
}
The comparison is curious. Usually with such a comparison would be in the form
if (h1 < h2 || (h1 == h2 && m1 < m2))
difftime takes 2 time_t paramters, not char timeValue[50] and a struct tm.
The values passed to double difftime(time_t time1, time_t time0) appear backwards. The result it time1 - time0.
Recommend instead
int current_hm = currentTime->tm_hour * 60 + currentTime->tm_min;
int file_hm = hour * 60 + min;
if (current_hm < file_hm) {
unsigned diff_time = (file_hm - current_hm)*60u;
printf("%u - Or this?\n", diff_time);
sleep(diff_time);
}
[Edit]
Simplified approach.
time_t now;
time(&now);
struct tm file_time_tm;
file_time_tm = *localtime(&now);
file_time_tm.tm_hour = hour; // from file
file_time_tm.tm_min = min; // from file
file_time_tm.tm_sec = 0;
file_time_tm.tm_isdst = -1;
time_t filetime = mktime(&file_time_tm);
double diff = difftime(filetime, now); // filetime - now
if (diff > 0) {
sleep((unsigned) diff);
}
Chux's suggestion to do your comparisons with your own integer that represents the minutes after midnight is probably easier in your case, but if you want to use the standard time mechanisms, you can do it.
But first, keep in mind that there are two time representations, time_t, which is a "numerical" time that stores the seconds after the epoch and struct tm, which is the human-readable time that breaks a time down to years, months, days and so on.
With strptime, you can scan a string accoding to a format specification. It is the scanf for struct tm. This function does not initialise fields that are not specified, so that you can assign the current time with localtime and then overwrite only the hour and minute fields.
mktime converts a struct tm to a time_t, which you can pass to difftime.
The following code snipped shows how such a comparison might work:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main()
{
char stamp[] = "12:53";
char *p;
struct tm now;
time_t t = time(NULL);
now = *localtime(&t);
p = strptime(stamp, "%H:%M", &now);
if (p == NULL || *p != '\0') {
printf("Illegal date.\n");
} else {
char buf[20];
double dsec;
int dmin;
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M\n", &now);
puts(buf);
dsec = difftime(t, mktime(&now));
printf("Diff: %g sec\n", dsec);
dmin = (int) dsec / 60;
printf("Diff: %d min\n", dmin);
}
return 0;
}

Printing out current date

Implement a function that determines and prints out the current year, month and day. For example:
Today is 03/04/2014.
Code so far that I have:
#include <stdio.h>
#include <time.h>
int main ()
{
int days, weeks, months, years, option, rmd, currentyear, currentmonth;
int daysinjan, daysinfeb, daysinmarch;
time_t seconds;
seconds = time(NULL);
days = seconds/(60*60*24);
weeks = seconds/((60*60*24)*7);
rmd=seconds%31557600;
months = ((seconds/31557600) * 12)+(((float)rmd/31557600)*12);
years = days/(365.25);
currentyear = 1970 + years;
currentmonth = (((float)rmd/31557600)*12)+1;
printf("%ld/%ld", currentmonth,currentyear);
return 0;
}
Please do not mind all the useless stuff in the code, this question is part of a project and i simply used the code from my previous question to try and work with that code in order to solve this question. The problem i have is that i cannot print the current day of the month that it is, because of this i feel that i have gone about this question wrongly.
This uses standard library calls to do all the math for you.
From Here:
#include <time.h>
#include <stdio.h>
#define SIZE 256
int main (void)
{
char buffer[SIZE];
time_t curtime;
struct tm *loctime;
/* Get the current time. */
curtime = time (NULL);
/* Convert it to local time representation. */
loctime = localtime (&curtime);
/* Print out the date and time in the standard format. */
fputs (asctime (loctime), stdout);
/* Print it out in a nice format. */
strftime (buffer, SIZE, "Today is %A, %B %d.\n", loctime);
fputs (buffer, stdout);
strftime (buffer, SIZE, "The time is %I:%M %p.\n", loctime);
fputs (buffer, stdout);
return 0;
}
If you wanted to create this as a function to return a string, you could do it like this:
char * getTimeString (char *str)
{
//replace this comment with relevant code from above with (at least) two additional lines:
strcpy(str, buffer);
return str;
}
Call it like this:
int main(void)
{
char *timeStr;
timeStr = malloc(30);//sufficient length to accept values assigned in getTimeString()
printf("%s\n", getTimeString(timeStr);
free(timeStr);
return 0;
}
#include <time.h> // for time_t
#include <stdio.h> // for printf
int main () {
int days, weeks, months, years, option, rmd, currentyear, currentmonth;
int daysinjan, daysinfeb, daysinmarch;
time_t seconds;
seconds = time(NULL);
days = seconds/(60*60*24);
weeks = seconds/((60*60*24)*7);
rmd=seconds%31557600;
months = ((seconds/31557600) * 12)+(((float)rmd/31557600)*12);
years = days/(365.25);
currentyear = 1970 + years;
currentmonth = (((float)rmd/31557600)*12)+1;
printf("%ld/%ld", currentmonth,currentyear);
return 0;
}

C code for date time format validation. specified format is "YYYYMMDDHHMMSSmmmmmm"

I need to validate a date-time value for "YYYYMMDDHHMMSSmmmmmm" format. Actually what I am hoping is I need to find out a already tested working C code to validate a date time value for above format.
Further, I have a date-time value like 201304011031000000. I need a function to verify whether this is a valid date or not.[isdatetime()]
Below are the each parts of formats.
YYYY : Year
MM : Month
DD : Day
HH : hour
MM : Minutes
SS : seconds
mmmmmm: micro-seconds
If you're on a POSIX system, this looks like something that should be handled with strptime(), but the 'milliseconds' (or microseconds) part is not handled by strptime() or any other standard conversion function I know of.
Assuming the question is asking for microseconds, you could use a variation on the theme provided by:
#include <stdio.h>
#include <string.h>
#include <time.h>
int main(void)
{
const char datetime[] = "20130417221633012345"; // YYYYMMDDHHMMSSFFFFFF
struct tm time_val;
unsigned microsecs;
const char *end = strptime(datetime, "%Y%m%d%H%M%S", &time_val);
if (end != 0)
{
int nbytes;
if (strlen(end) == 6 && sscanf(end, "%6u%n", &microsecs, &nbytes) == 1 &&
nbytes == 6)
{
char buffer[32];
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &time_val);
printf("%s = %s.%.6u\n", datetime, buffer, microsecs);
}
}
return 0;
}
Revised requirement
#include <stdio.h>
#include <string.h>
#include <time.h>
int isdatetime(const char *datetime)
{
// datetime format is YYYYMMDDHHMMSSFFFFFF
struct tm time_val;
unsigned microsecs;
int nbytes;
const char *end = strptime(datetime, "%Y%m%d%H%M%S", &time_val);
if (end != 0 && strlen(end) == 6 &&
sscanf(end, "%6u%n", &microsecs, &nbytes) == 1 && nbytes == 6)
return 1; // Valid
return 0; // Invalid
}
You can use regex.h for windows or for linux.
"YYYYMMDDHHMMSSMSSSSS" is something like: (\d{4}[0,1][0,9]\d{})... you can find your specific format here, it depends wether you enable 24 or 12 clock etc.

Need to get Saturdays date of the week in linux C

I am trying to get Saturday's date of the week in Linux C. Using the function time and localtime, I got today's date and time details. How to proceed further to get Saturday's date?
#include <time.h>
#include <stdio.h>
#include <string.h>
int main()
{
char date[20];
struct tm *curr_tm = NULL;
time_t curr_time;
curr_time = time(NULL);
curr_tm = localtime(&curr_time);
curr_tm->tm_wday = 6;
//Refers to saturday.
printf("new date %d\t%d\t%d\n", curr_tm->tm_mday, curr_tm->tm_mon, curr_tm->tm_year+1900);
return 1;
}
How should I proceed with this?
struct tm orig;
// ...
// struct tm correctly set with everything within range.
orig.tm_mday += 6 - orig.tm_wday;
mktime(&orig);
tm_mday is the number of days since Sunday. Thus, 6 minus that is the number of days until Saturday (if today is Saturday it does nothing). This puts the structure out of range, which mktime fixes.
EDIT:
curr_time->tm_mday += 6 - curr_time->tm_wday;
mktime(curr_time);
Based on your code, the following will get you the next Saturday (today if it's Saturday).
#include <time.h>
#include <stdio.h>
#include <string.h>
int main() {
char date[20];
struct tm *curr_tm = NULL;
time_t curr_time;
curr_time = time(NULL);
curr_tm = localtime(&curr_time);
// Add the difference between todays day of week and Saturday, then re-make.
curr_tm->tm_mday += 6 - curr_tm->tm_wday;
mktime (curr_tm);
printf("new date %d\t%d\t%d\n",
curr_tm->tm_mday, curr_tm->tm_mon+1, curr_tm->tm_year+1900);
return 1;
}
You can replace the curr_tm->tm_mday += 6 - curr_tm->tm_wday; line with:
curr_tm->tm_mday += (curr_tm->tm_wday == 6) ? 7 : 6 - curr_tm->tm_wday;
to get next Saturday even if today is Saturday.

Resources