Skip to content

Designer or ViSi: Routine for Parsing a Time String

Introduction

This codebase example shows how to parse a time string to find the hour, minute, and second information. The program expects the input string to be of the format hh:mm:ss xx, where,

  • hh = hour
  • mm = minute
  • ss = second
  • xx = "am/pm/nn/mn" indicator

When the hour is 0 or greater than twelve, the input is assumed to be of the 24-hour format, hence, the indicator is ignored.

Note

That the indicator "xx" may be excluded from the input string.

Example 1: input: "12:0:0 am" , output: globalHour = 0 , globalMinute = 0, globalSecond = 0;
Example 2: input: "12:00:0" , output: globalHour = 0 , globalMinute = 0, globalSecond = 0;
Example 3: input: "12:34:45 PM", output: globalHour = 12, globalMinute = 34, globalSecond = 45;
Example 4: input: "15:6:9 Am" , output: globalHour = 15, globalMinute = 6, globalSecond = 9, indicator is ignored
Example 1: input: "99:99:99" , output: globalHour = 99 , globalMinute = 99, globalSecond = 99;

If the program does not understand the input time string, it prints out an error message.

Prerequisites

This codebase example assumes the reader can program the 4D Systems display module using Workshop4 IDE ViSi or Designer environment. Beginners are advised to read the following aplication notes.

How the Program Works

In summary, the program does the following:

  1. Find the locations of the first and second colon characters and the first space character. The program prints out an error message if both colon characters are not found.

  2. Use the data in step 1 to locate the hour, minute, second, and indicator (if it exists) substrings and copy them to separate arrays.

  3. Extract any decimal number from the minute substring and convert it to its equivalent integer value, which is then stored in the global variable "globalMinute". The minute substring must be one- or two-characters wide. If the program cannot find a decimal number in the minute substring, it prints the message "No minute extracted.".

  4. Extract any decimal number from the second substring and convert it to its equivalent integer value, which is then stored in the global variable "globalSecond". The second substring must be one- or two-characters wide. If the program cannot find a decimal number in the second substring, it prints the message "No second extracted.".

  5. Extract any decimal number from the hour substring and convert it to its equivalent integer value, which is then stored in the global variable "globalHour". The hour substring must be one- or two-characters wide. If the program cannot find a decimal number in the hour substring, it prints the message "No hour extracted.".

  6. Compare the indicator substring (if it exists) to a list of stored strings of correct and expected indicators. Note that the indicator substring must be one- or two- characters long and that the matching process is case insensitive. If the program finds a match for the input indicator substring, it may modify the value stored in "globalHour". Otherwise it prints out an error message.

Note

This program will only parse a string for the hour, minute, and second information; it will not check if the information is valid. For example, "99:99:99" is a valid input since it has an hour, minute, and second information. Further testing of the values of the extracted variables can be easily implemented by the user using the code snippet in 4D-CD-00023 Designer or ViSi Time and Date Validation.

To see an actual example of a more complete time string check, see the codebase example 4D-CD-00044 Designer or ViSi Parse and Check a Time String. 4D-CD-00044 combines this example (4D-CD-00042) and 4D-CD-00023 Designer or ViSi Time and Date Validation to perform both parsing and checking the validity of a time string. Furthermore, 4D-CD-00044 shows how the source code in this example(4D-CD-00042) is converted to an include file that can be used in a larger project.

All variables and arrays used in the program are located inside the array PTClass[].

    var PTClass[PTi + 1];

This array contains PTi + 1 words, some of which are used for storing strings, and some are used as variables. A list of constants is then used for indexing into the array. The list is partially shown below.

    #CONST
        PTssHour            // 2 words for hour substring array
        PTssMinute    2     // 2 words for minute substring array
        PTssSecond    4     // 2 words for second substring array
        PTssIndic     6     // 2 words for "am/pm/nn/mn" indicator substring array
        PTptrBGTime   8     // 1 word  for byte-aligned pointer to input time string array
        PTptrSSHour         // 1 word  for byte-aligned pointer to hour substring array
        PTptrSSMinute       // 1 word  for byte-aligned pointer to minute substring array
        PTptrSSSecond       // 1 word  for byte-aligned pointer to second substring array
        PTptrSSIndic        // 1 word  for byte-aligned pointer to "am/pm/nn/mn" indicator substring array
        PTptrWGTime         // 1 word  for word-aligned pointer to global time string array
        PTptrGHour          // 1 word  for word-aligned pointer to global hour
        ...
        PTindicFlag         // 1 word  for indicator existence flag
        PTi                 // 1 word  as a general-purpose variable    
    #END

The constants have the implicit values shown below:

    #CONST
        PTssHour      0     // implicit value
        PTssMinute    2     //  explicit value
        PTssSecond    4     //  explicit value
        PTssIndic     6     //  explicit value
        PTptrBGTime   8     //  explicit value
        PTptrSSHour   9     // implicit value
        PTptrSSMinute 10    // implicit value
        PTptrSSSecond 11    // implicit value
        PTptrSSIndic  12    // implicit value
        PTptrWGTime   13    // implicit value
        PTptrGHour    14    // implicit value
        ...
        PTindicFlag   25    // implicit value
        PTi           26    // implicit value   
    #END

Thus, we can use the 27th element of the array as a general-purpose counter variable:

    PTClass[PTi] := 0;
    for(; PTClass[PTi] < 12; PTClass[PTi]++) 
        ...
    next

Also, we can use the fifteenth element of the array as a pointer to another variable:

    PTClass[PTptrGHour] := &globalHour;

To access the content of the global variable "globalHour", we can dereference its pointer:

    var x := *PTClass[PTptrGHour];

To assign a value to the global variable "globalHour" thru its pointer we write,

    *PTClass[PTptrGHour] := 12;

Also, we can input a sequence of bytes (e.g. the input hour substring) starting at the address of PTClass[PTssHour]:

    to(&PTClass[PTssHour]); print("12"); 

We arbitrarily limit the length of the input byte sequence to 4 including the null terminator, so it will not overlap with the bytes located starting at &PTClass[PTssMinute].

We can use an element of the big array "PTClass[]" as a byte-aligned pointer to another section of the array:

PTClass[PTptrSSHour]  := str_Ptr(&PTClass[PTssHour]); 

Putting all variables and "sub-arrays" inside a large array and using constants in an organized list as indices into the array allow for the writing of the definitions (as comments) of all the variables and arrays in one place in the source code.

Instructions

  1. In the attached Designer code, modify the input time string on line 96. Compile the project and upload it to a uLCD-32PTU (or your target display).

  2. The program should now run on the display module. See the video for more information.

Attachment

Project File