1 Introduction
2 Ground Rules

Building a File System
3 File Systems
4 File Content Data Structure
5 Allocation Cluster Manager
6 Exceptions and Emancipation
7 Base Classes, Testing, and More
8 File Meta Data
9 Native File Class
10 Our File System
11 Allocation Table
12 File System Support Code
13 Initializing the File System
14 Contiguous Files
15 Rebuilding the File System
16 Native File System Support Methods
17 Lookups, Wildcards, and Unicode, Oh My
18 Finishing the File System Class

The Init Program
19 Hardware Abstraction and UOS Architecture
20 Init Command Mode
21 Using Our File System
22 Hardware and Device Lists
23 Fun with Stores: Partitions
24 Fun with Stores: RAID
25 Fun with Stores: RAM Disks
26 Init wrap-up

The Executive
27 Overview of The Executive
28 Starting the Kernel
29 The Kernel
30 Making a Store Bootable
31 The MMC
32 The HMC
33 Loading the components
34 Using the File Processor
35 Symbols and the SSC
36 The File Processor and Device Management
37 The File Processor and File System Management
38 Finishing Executive Startup

Users and Security
39 Introduction to Users and Security
40 More Fun With Stores: File Heaps
41 File Heaps, part 2
42 SysUAF
43 TUser
44 SysUAF API

Terminal I/O
45 Shells and UCL
46 UOS API, the Application Side
47 UOS API, the Executive Side
48 I/O Devices
49 Streams
50 Terminal Output Filters
51 The TTerminal Class
52 Handles
53 Putting it All Together
54 Getting Terminal Input
55 QIO
56 Cooking Terminal Input
57 Putting it all together, part 2
58 Quotas and I/O

UCL
59 UCL Basics
60 Symbol Substitution
61 UCL Command execution
62 UCL Command execution, part 2
63 UCL Command Abbreviation
64 ASTs
65 UCL Expressions, Part 1
66 UCL Expressions, Part 2: Support code
67 UCL Expressions, part 3: Parsing
68 SYS_GETJPIW and SYS_TRNLNM
69 UCL Expressions, part 4: Evaluation

UCL Lexical Functions
70 PROCESS_SCAN
71 PROCESS_SCAN, Part 2
72 TProcess updates
73 Unicode revisted
74 Lexical functions: F$CONTEXT
75 Lexical functions: F$PID
76 Lexical Functions: F$CUNITS
77 Lexical Functions: F$CVSI and F$CVUI
78 UOS Date and Time Formatting
79 Lexical Functions: F$CVTIME
80 LIB_CVTIME
81 Date/Time Contexts
82 SYS_GETTIM, LIB_Get_Timestamp, SYS_ASCTIM, and LIB_SYS_ASCTIM
83 Lexical Functions: F$DELTA_TIME
84 Lexical functions: F$DEVICE
85 SYS_DEVICE_SCAN
86 Lexical functions: F$DIRECTORY
87 Lexical functions: F$EDIT and F$ELEMENT
88 Lexical functions: F$ENVIRONMENT
89 SYS_GETUAI
90 Lexical functions: F$EXTRACT and F$IDENTIFIER
91 LIB_FAO and LIB_FAOL
92 LIB_FAO and LIB_FAOL, part 2
93 Lexical functions: F$FAO
94 File Processing Structures
95 Lexical functions: F$FILE_ATTRIBUTES
96 SYS_DISPLAY
97 UCL Lexical functions: F$GETDVI
98 Parse_GetDVI

Glossary/Index


Download sources
Download binaries

Lexical Functions - F$CVTIME

Our next lexical function is F$CVTIME. It converts a given time into a specific format. Here is the definition:

F$CVTIME converts an absolute or combination time string to an absolute, delta, or a string of the form yyyy-mm-dd hh:mm:ss.cc. All arguments are optional,

Format
F$CVTIME({input_time},{output_format},{output_time})

Return Value
A string containing the requested information.

Arguments
input_time

Specifies a string containing an absolute, delta, or combination time. "TODAY", "TOMORROW", and "YESTERDAY" are also allowed.

If this argument is omitted or a null string (""), the current system date and time is used in its place. Any parts of the date field which are omitted are defaulted to the current date. Any parts of the time field which are omitted are defaulted to 0. Arguments can be omitted to the right of the last argument specified, but commas (,) must be used as placeholders if arguments are omitted to the left of the last argument specified.

Note: if this argument is a delta time, the output_format argument must be "DELTA".

output_format

Specifies the format to be returned. It must be one of the following values:
ABSOLUTEThe date/time is returned as per the default date and/or time format. Single digit days are returned with no leading space or zero.
COMPARISON
(default)
The date and time is returned in the form yyyy-mm-dd hh:mm:ss.cc. This format can be used for comparing two date/times. If the output_format is omitted or null (""), it is assumed to be a request for a comparison date/time result.
DELTAThe request is returned in delta format, which is dddd-hh:mm:ss.cc. If this option is used, the input_time argument must be a delta time specification. This must be used if the input_time argument is a delta time.

output_time

Specifies a string containing one of the following (which may not be abbreviated): DATE, MONTH, DATEFIME, SECOND, DAY, TIME, HOUR, WEEKDAY, HUNDREDTH, YEAR, MINUTE, DAUPF YEAR, HOUROFYEAR, MINUTEOFYEAR, SECONDOF YEAR.

If this argument is omitted or null (""), the default is DATETIME.

If the input_time argument is a delta time and the output_format argument is "DELTA", then this argument cannot be MONTH, WEEKDAY, YEAR, DAYOFYEAR, HOUROFYEAR, MINUTEOFYEAR, or SECONDOFYEAR.

Example
$ X = F$CVTIME()

This is equivalent to:
$ X = F$CVTIME("","COMPARISON","DATETIME") In this example, the current date/time is returned in the form yyyy-mm-dd hh:mm:ss.cc, for instance, "21-DEC-2019 11:55:12.20".

The resulting string can be compared using UCL operators (for instnace, .LTS. and .GTS.).

Example
$ X = F$CVTIME("YESTERDAY",,"WEEKDAY")

In this example, F$CVTIME returns the weekday that corresponds to the input time of "YESTERDAY". Thus, if the current day is tuesday, the function will return "Monday".

        Function_Cvtime : begin
                            if( Missing_Parentheses( '(' ) ) then
                            begin
                                exit ;
                            end ;
                            if( Parse_CVTime( Err, Context ) ) then
                            begin
                                exit ;
                            end ;
                            if( Missing_Parentheses( ')' ) ) then
                            begin
                                exit ;
                            end ;
                            S := Context ;
                        end ;
We update the Function_Reference code to handle the F$CVTIME lexical function. This is like the previous lexical functions we've added.

function Parse_CVTime( var Err : integer ; var Context : string ) : boolean ;

var Input_Time, Output_Time, Output : string ;
    TS : int64 ;
    Output_Flag, Output_Time_Flag : integer ;

begin
    // Setup...
    Result := False ;
    Err := 0 ;
    Output := '' ;
    Output_Time := '' ;
The Parse_CVTime function parses and executes the F$CVTIME lexical function. We set up by clearing the error return and function return.

    // Get parameters...
    Input_Time := lowercase( Get_Parameter( Err, Context, True ) ) ; //NEW:Added 3rd parameter
    if( Err <> 0 ) then
    begin
        exit ;
    end ;
    if( Parser.Peek <> ')' ) then
    begin
        if( Missing_Comma( Err ) ) then
        begin
            exit ;
        end ;
        Output := lowercase( Get_Parameter( Err, Context, True ) ) ;
        if( Err <> 0 ) then
        begin
            exit ;
        end ;
        if( Parser.Peek <> ')' ) then
        begin
            if( Missing_Comma( Err ) ) then
            begin
                exit ;
            end ;
            Output_Time := lowercase( Get_Parameter( Err, Context ) ) ;
            if( Err <> 0 ) then
            begin
                exit ;
            end ;
        end ;
    end ;
Next, we get the input time argument and exit if there was an error. If we haven't reached the closing parenthesis, we grab the next comma and then get the output specification argument. Again, if we haven't reached the closing parenthesis yet, we get the comma and then the output format argument value. This approach allows the code to handle the omitted arguments as per the above documentation.

    // Process output format keywords...
    if( Output = 'absolute' ) then
    begin
        Output_Flag := CVF_Absolute ;
    end else
    if( Output = 'delta' ) then
    begin
        Output_Flag := CVF_Delta ;
    end else
    if( ( Output = 'comparison' ) or ( Output = '' ) ) then
    begin
        Output_Flag := CVF_Comparison ;
    end else
    begin
        Err := UCL_IVKEYW ;
        exit ;
    end ;
Next we convert the second argument into a flag value and exit with an error if the value isn't valid. "comparison" is the default if the argument is empty.

    // Process output time keywords...
    if( ( Output_Time = 'datetime' ) or ( Output_Time = '' ) ) then
    begin
        Output_Time_Flag := CVO_DateTime ;
    end else
    if( Output_Time = 'date' ) then
    begin
        Output_Time_Flag := CVO_Date ;
    end else
    if( Output_Time = 'time' ) then
    begin
        Output_Time_Flag := CVO_Time ;
    end else
    if( Output_Time = 'hour' ) then
    begin
        Output_Time_Flag := CVO_Hour ;
    end else
    if( Output_Time = 'second' ) then
    begin
        Output_Time_Flag := CVO_Second ;
    end else
    if( Output_Time = 'minute' ) then
    begin
        Output_Time_Flag := CVO_Minute ;
    end else
    if( Output_Time = 'hundreth' ) then
    begin
        Output_Time_Flag := CVO_Hundredth ;
    end else
    if( Output_Time = 'day' ) then
    begin
        Output_Time_Flag := CVO_Day ;
    end else
    if( Output_Time = 'month' ) then
    begin
        Output_Time_Flag := CVO_Month ;
    end else
    if( Output_Time = 'weekday' ) then
    begin
        Output_Time_Flag := CVO_Weekday ;
    end else
    if( Output_Time = 'year' ) then
    begin
        Output_Time_Flag := CVO_Year ;
    end else
    if( Output_Time = 'dayofyear' ) then
    begin
        Output_Time_Flag := CVO_DayofYear ;
    end else
    if( Output_Time = 'hourofyear' ) then
    begin
        Output_Time_Flag := CVO_HourofYear ;
    end else
    if( Output_Time = 'minuteofyear' ) then
    begin
        Output_Time_Flag := CVO_MinuteofYear ;
    end else
    if( Output_Time = 'secondofyear' ) then
    begin
        Output_Time_Flag := CVO_SecondofYear ;
    end else
    begin
        Err := UCL_IVKEYW ;
        exit ;
    end ;
Next we convert the final argument into a flag value and exit with an error if the value isn't valid. "datetime" is the default if the argument is empty.

    // Call LIB$CVTime...
    Err := LIB_CVTime( Input_Time, Output_Flag, Output_Time_Flag ) ;
    if( Err <> 0 ) then
    begin
        case Err of
            LIB_BADTOPT :
                begin
                    Err := UCL_IVKEYW ;
                    Context := Output_Time ;
                end ;
            LIB_EVDTIME :
                begin
                    Err := UCL_IVDTIME ;
                    Context := Input_Time ;
                end ;
        end ;
        exit ;
    end ;
    Context := Input_Time ;
end ; // Parse_CVTime
Finally, we call startlet's LIB_CVTIME function, passing on the input time, and the two flag values. If we get an error, we translate it into a UCL error code. Otherwise, we return the value from LIB_CVTIME (the first parameter is passed by reference).

We will discuss LIB_CVTIME, and the flag constant values used above, in the next article. But first, let's look at a modification to the Get_Parameter function.

function Get_Parameter( var Err : integer ; var Context : string ;
    Allow_Blank : boolean = False ) : string ;

begin
    Result := '' ;
    if( ( Parser.Peek = ',' ) or ( Parser.Peek = ')' ) ) then
    begin
        if( not Allow_Blank ) then
        begin
            Err := UCL_ARGREQ ;
        end ;
        exit ;
    end ;
    if( Parser.Token_EOL ) then
    begin
        Err := UCL_ARGREQ ;
        exit ;
    end ;
    Result := Get_Expression( Err, Context ) ;
    if( ( Err = UCL_EXPSYN ) and ( ( Parser.Peek = ',' ) or ( Parser.Peek = ')' ) ) ) then
    begin
        Err := 0 ;
    end ;
end ;
We covered this function back in article 74, but we've added a third, optional, parameter used to allow the parameter to be omitted. A simple change to handle omitted parameters. By default, parameters cannot be omitted. But if the third parameter is True, then parameters can be omitted. In that case, an omitted parameter results in the function returning null.

In the next article, we will look at date/time support provided in Starlet, including the LIB_CVTIME function.

 

Copyright © 2020 by Alan Conroy. This article may be copied in whole or in part as long as this copyright is included.