{"id":4590,"date":"2021-02-13T00:01:43","date_gmt":"2021-02-13T08:01:43","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=4590"},"modified":"2021-02-20T09:19:39","modified_gmt":"2021-02-20T17:19:39","slug":"parsing-integer-values-into-a-time_t-value","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=4590","title":{"rendered":"Parsing Integer Values Into a <em>time_t<\/em> Value"},"content":{"rendered":"<p>Pulling a date from a string involves slicing the string into substrings, which are then converted into values for year, month, and day. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4595\">Last week&#8217;s Lesson<\/a> demonstrated such code. This week, the final step is accomplished, converting year, month, and day integers into a <em>time_t<\/em> value.<br \/>\n<!--more--><br \/>\nI can think of two ways to create a <em>time_t<\/em> value. My default method, which I&#8217;ve written about before <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=37\">on this blog<\/a>, is to populate a <em>tm<\/em> structure which can then be converted into a <em>time_t<\/em> value. It&#8217;s kind of a backwards way to obtain the value, but I know it works.<\/p>\n<p>As a review, the <em>time_t<\/em> value represents the Unix epoch, or the number of seconds passed since January 1, 1970. The <em>tm<\/em> structure contains members that reference individual parts of a date, such as the year, month, day of the month, and so on. Both of <em>time_t<\/em> and the <em>tm<\/em> structure are defined in the <code>time.h<\/code> header file.<\/p>\n<p>In my earlier post, I populated a <em>tm<\/em> structure with the current time, then updated specific members to reflect the <em>time_t<\/em> value I wanted. Here&#8217;s a snippet from the code:<\/p>\n<pre class=\"screen\">\r\ntime(&amp;today);\r\nbirthday = localtime(&amp;today);\r\nbirthday-&gt;tm_mon = month-1;\r\nbirthday-&gt;tm_mday = day;\r\nbirthday-&gt;tm_year = year-1900;\r\n\r\nbday = mktime(birthday);<\/pre>\n<p>The <em>time()<\/em> function sets the current time&#8217;s <em>time_t<\/em> value into variable <code>today<\/code>.<\/p>\n<p>The <em>localtime()<\/em> function extracts from the <em>time_t<\/em> value individual members of the <em>tm<\/em> structure <code>birthday<\/code>.<\/p>\n<p>The month, day, and year members of <em>tm<\/em> structure <code>birthday<\/code> are updated with values from <em>int<\/em> variables <code>month<\/code>, <code>day<\/code>, and <code>year<\/code>.<\/p>\n<p>Finally, the <em>mktime()<\/em> function converts the data from <em>tm<\/em> structure <code>birthday<\/code> into the <em>time_t<\/em> value <code>bday<\/code>.<\/p>\n<p>I wondered if you really need to pre-populate a <em>tm<\/em> structure to make this process work? So I ran a test and filled various members of the structure directly. Alas, the results were inconsistent, so I retained my approach from the earlier blog post.<\/p>\n<p>Here&#8217;s the final version of the filename-to-<em>time_t<\/em> code:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2021_02_13-Lesson.c\" rel=\"noopener\" target=\"_blank\">2021_02_13-Lesson.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;time.h&gt;\r\n\r\n<span class=\"comments\">\/* copy and convert the digits *\/<\/span>\r\nchar *convert( char *s, int size )\r\n{\r\n    int x;\r\n    static char buffer[5];\r\n    char c;\r\n\r\n    for( x=0; x&lt;size; x++ )\r\n    {\r\n        c = *(s+x);\r\n        if( c=='.' || c=='\\0' )\r\n        {\r\n            fprintf(stderr,\"Malformed filename\\n\");\r\n            exit(2);\r\n        }\r\n        buffer[x] = c;\r\n    }\r\n    buffer[x] = '\\0';\r\n\r\n    return(buffer);\r\n}\r\n\r\nint main(int argc, char *argv[])\r\n{\r\n    char *filename;\r\n    int year, month, day;\r\n    time_t now,file;\r\n    struct tm *date;\r\n    \r\n    <span class=\"comments\">\/* check for filename argument *\/<\/span>\r\n    if( argc&lt;2 )\r\n    {\r\n        <span class=\"comments\">\/* output error message to standard error *\/<\/span>\r\n        fprintf(stderr,\"Filename option required\\n\\n\");\r\n        <span class=\"comments\">\/* leave with exit code 1*\/<\/span>\r\n        exit(1);\r\n    }\r\n    <span class=\"comments\">\/* assign to pointer for convenience *\/<\/span>\r\n    filename = argv[1];\r\n\r\n    <span class=\"comments\">\/* code to confirm that the file exists goes here *\/<\/span>\r\n    <span class=\"comments\">\/* ... *\/<\/span>\r\n    \r\n    <span class=\"comments\">\/* extract integers. *\/<\/span>\r\n    year = strtol(convert(filename+0,4),NULL,10);\r\n    month = strtol(convert(filename+4,2),NULL,10);\r\n    day = strtol(convert(filename+6,2),NULL,10);\r\n\r\n    <span class=\"comments\">\/* fill the tm structure with the current date\/time *\/<\/span>\r\n    time(&amp;now);\r\n    date = localtime(&amp;now);\r\n    <span class=\"comments\">\/* backfill some specific items in the date structure *\/<\/span>\r\n    date-&gt;tm_sec = 0;\r\n    date-&gt;tm_min = 0;\r\n    date-&gt;tm_hour = 0;\r\n    date-&gt;tm_mday = day;\r\n    date-&gt;tm_mon = month - 1;\r\n    date-&gt;tm_year = year - 1900;\r\n    <span class=\"comments\">\/* convert the structure to a time_t value *\/<\/span>\r\n    file = mktime(date);\r\n\r\n    <span class=\"comments\">\/* output results *\/<\/span>\r\n    printf(\"%4d %2d %2d\\n\",year,month,day);\r\n    printf(\"time_t value is %ld\\n\",file);\r\n    printf(\"%s\\n\",ctime(&amp;file));\r\n\r\n    return(0);\r\n}<\/pre>\n<p>Line 54 generates a <em>time_t<\/em> value in variable <code>now<\/code>. The <em>tm<\/em> structure date is filled at Line 55.<\/p>\n<p>From Lines 57 through 62, the <em>tm<\/em> structure <code>date<\/code> is updated with new values. The <code>month<\/code> and <code>year<\/code> values must be modified to fit into the <em>tm<\/em> structure properly; months are numbered from zero and years start at 1900.<\/p>\n<p>Sample output for the argument <code>20210115.txt<\/code>:<\/p>\n<p><code>2021&nbsp;&nbsp;1 15<br \/>\ntime_t value is 1610697600<br \/>\nFri Jan 15 00:00:00 2021<\/code><\/p>\n<p>And for <code>2021okay.txt<\/code><\/p>\n<p><code>2021&nbsp;&nbsp;0&nbsp;&nbsp;0<br \/>\ntime_t value is 1606723200<br \/>\nMon Nov 30 00:00:00 2020<\/code><\/p>\n<p>With the output above, you see that bogus data is generated due to the bogus input. The code doesn&#8217;t validate input to the degree necessary to detect this issue. I leave a solution up to you.<\/p>\n<p>In <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4616\">next week&#8217;s Lesson<\/a>, I cover how to manually create a <em>time_t<\/em> value.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The final step in parsing the filename string is to convert the year, month, and day integer values into a <em>time_t<\/em> &#8220;Unix epoch&#8221; value. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4590\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-4590","post","type-post","status-publish","format-standard","hentry","category-main"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4590","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4590"}],"version-history":[{"count":12,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4590\/revisions"}],"predecessor-version":[{"id":4636,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4590\/revisions\/4636"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4590"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4590"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4590"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}