Announcement

Collapse
No announcement yet.

4D-CD-00042 Designer or ViSi Routine for Parsing a Time String

Collapse
This topic is closed.
X
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • 4D-CD-00042 Designer or ViSi Routine for Parsing a Time String



    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 hour is 0 or greater than twelve, the input is assumed to be of the 24-hour format, hence, the indicator is ignored.

    Note also 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. 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 is not able to 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 is not able to 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 is not able to 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 that 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.
    Attached Files
    Doff
Working...
X