This is from a much older posting, but I needed it recently, so here it is again...

In many places, SCCM uses a 16-character text string (actually a hexadecimal number) to represent one of the schedule token classes (SMS_ST_NonRecurring, SMS_ST_RecurInterval, SMS_ST_RecurMonthlyByDate, SMS_ST_RecurMonthlyByWeekday, and SMS_ST_RecurWeekly).

Microsoft provides a WMI interface to translate between the text string and one of the SMS_ST_ WMI objects. Unfortunately, this interface is only accessible from the SCCM site server and it is not available to clients (who would not likely have the WMI access permission to the SMS_ScheduleMethods class).

This post attempts to explain the string and provide methods to allow for its encryption and decryption.

The string is a 64-bit hexadecimal number. For the purposes of this post, the 16-bit words are denoted A-D, least significant bit first.

 +---------+---------+---------+---------+
 | (MSB) D |    C    |    B    | A (LSB) |
 +---------+---------+---------+---------+

The table below lists the bits and their meanings, starting with the least significant bit first. Depending on the class used, bits A1 through B2 have different meanings. These bits are not used, however, for the SMS_ST_NonRecurring class. Bit A0 and bits B3 through D15 are common to all classes.

Bit Description
A0 (LSB) 0 Single bit flag representing the IsGMT property common to all SMS_ST_ classes
RecurInterval RecurWeekly RecurMonthlyByWeekday RecurMonthlyByDate
A1 1 Not used
A2 2 Not used
A3 3 Encodes DaySpan property Not used
A4 4 Not used
A5 5 Not used
A6 6 Not used
A7 7 Not used
A8 8 Encodes HourSpan property Not used
A9 9 Not used Encodes WeekOrder property Not used
A10 10 Not used Encodes ForNumberOfMonths property
A11 11 Not used
A12 12 Not used Encodes ForNumberOfMonths property
A13 13 Encodes MinuteSpan property Encodes ForNumberOfWeeks property
A14 14 Encodes MonthDay property
A15 15
B0 16 Encodes Day property Encodes Day property
B1 17
B2 18
B3 19 Determines SMS_ST_ class encoded:
001 = SMS_ST_NonRecurring
010 = SMS_ST_RecurInterval
011 = SMS_ST_RecurWeekly
100 = SMS_ST_RecurMonthlyByWeekday
101 = SMS_ST_RecurMonthlyByDate
B4 20
B5 21
B6 22 Encodes DayDuration property
B7 23
B8 24
B9 25
B10 26
B11 27 Encodes HourDuration property
B12 28
B13 29
B14 30
B15 31
C0 32 Encodes MinuteDuration property
C1 33
C2 34
C3 35
C4 36
C5 37
C6 38 Encodes the number of years since 1970 for the StartTime property Because this is limited to 6 bits, the maximum year is 2033
C7 39
C8 40
C9 41
C10 42
C11 43
C12 44 Encodes the month portion of the StartTime property
C13 45
C14 46
C15 47
D0 48 Encodes the day portion of the StartTime property
D1 49
D2 50
D3 51
D4 52
D5 53 Encodes the hour portion of the StartTime property
D6 54
D7 55
D8 56
D9 57
D10 58 Encodes the minute portion of the StartTime property
D11 59
D12 60
D13 61
D14 62
D15 63


Listed below is a sample of code for VBScript that treats these objects as classes. You can use the SMS_ScheduleMethods class to convert them to/from the 16 character hexadecimal string.

Sample Classes Code in VBScript

'Sample code to convert between SCCM schedule interval strings and their meanings
'***************************************************************************************************
' SMS_ScheduleMethods
'***************************************************************************************************

Class SMS_ScheduleMethods
    'This class emulates the SMS_ScheduleMethods WMI class available on the SCCM site server
    
    Public Function ReadFromString(strIn)
        'This function will translate from a given string into a class object appropriate for
        'the schedule token represented
        
        Dim objST, nClassType
        
        'Get the class type from the appropriate bits in the string
        
        nClassType = ReadBits(strIn, 19, 21)
        
        'Depending on the class type, create the appropriate class and populate class-specific
        'properties
        
        Select Case nClassType
            Case 1:
                Set objST = New SMS_ST_NonRecurring
            Case 2:
                Set objST = New SMS_ST_RecurInterval
                objST.DaySpan = ReadBits(strIn, 3, 7)
                objST.HourSpan = ReadBits(strIn, 8, 12)
                objST.MinuteSpan = ReadBits(strIn, 13, 18)
            Case 3:
                Set objST = New SMS_ST_RecurWeekly
                objST.Day = ReadBits(strIn, 16, 18)
                objST.ForNumberOfWeeks = ReadBits(strIn, 13, 15)
            Case 4:
                Set objST = New SMS_ST_RecurMonthlyByWeekday
                objST.Day = ReadBits(strIn, 16, 18)
                objST.ForNumberOfMonths = ReadBits(strIn, 12, 15)
                objST.WeekOrder = ReadBits(strIn, 9, 11)
            Case 5:
                Set objST = New SMS_ST_RecurMonthlyByDate
                objST.MonthDay = ReadBits(strIn, 14, 18)
                objST.ForNumberOfMonths = ReadBits(strIn, 10, 13)
        End Select
        
        'Set the generic properties available on all objects
        If ReadBits(strIn,0,0) = 1 Then objST.IsGMT = True
        objST.DayDuration = ReadBits(strIn, 22, 26)
        objST.HourDuration = ReadBits(strIn, 27, 31)
        objST.MinuteDuration = ReadBits(strIn, 32, 37)
        objST.StartTime = DateSerial(1970 + ReadBits(strIn, 38, 43), ReadBits(strIn, 44, 47), _
            ReadBits(strIn, 48, 52)) + _ 
            TimeSerial(ReadBits(strIn, 53, 57), ReadBits(strIn, 58, 63), 0)
        
        'Return the class object
        Set ReadFromString = objST
    End Function
    
    Public Function WriteToString(objST)
        'This function will convert the inputted ST class object into a string
        
        Dim strWrk
        
        strWrk = String(16, "0") 'Initialize the output string
        
        'Switch based on class type
        
        Select Case objST.Class_
            Case "SMS_ST_NonRecurring":
                WriteBits strWrk, 19, 21, 1
            Case "SMS_ST_RecurInterval":
                WriteBits strWrk, 19, 21, 2
                WriteBits strWrk, 3, 7, objST.DaySpan
                WriteBits strWrk, 8, 12, objST.HourSpan
                WriteBits strWrk, 13,18, objST.MinuteSpan
            Case "SMS_ST_RecurWeekly":
                WriteBits strWrk, 19, 21, 3
                WriteBits strWrk, 13, 15, objST.ForNumberOfWeeks
                WriteBits strWrk, 16, 18, objST.Day
            Case "SMS_ST_RecurMonthlyByWeekday"
                WriteBits strWrk, 19, 21, 4
                WriteBits strWrk, 9, 11, objST.WeekOrder
                WriteBits strWrk, 12, 15, objST.ForNUmberOfMonths
                WriteBits strWrk, 16, 18, objST.Day
            Case "SMS_ST_RecurMonthlyByDate"
                WriteBits strWrk, 19, 21, 5
                WriteBits strWrk, 10, 13, objST.ForNumberOfMonths
                WriteBits strWrk, 14, 18, objST.MonthDay
        End Select
        
        'Update the string for the generic stuff
        WriteBits strWrk, 22, 26, objST.DayDuration
        WriteBits strWrk, 27, 31, objST.HourDuration
        WriteBits strWrk, 32, 37, objST.MinuteDuration
        WriteBits strWrk, 38, 43, Year(objST.StartTime) - 1970
        WriteBits strWrk, 44, 47, Month(objST.StartTime)
        WriteBits strWrk, 48, 52, Day(objST.StartTime)
        WriteBits strWrk, 53, 57, Hour(objST.StartTime)
        WriteBits strWrk, 58, 63, Minute(objST.StartTime)
        If objST.IsGMT Then WriteBits strWrk, 0, 0, 1
        
        WriteToString = strWrk
    End Function
    
    Private Function ReadBits(strIn, nStart, nEnd)
        'This function will return a number that is encoded in the specified bits within the hexadecimal
        'input string
        
        Dim strWrk, nRaw, nMask, nShift
        
        strWrk = StrReverse(strIn)  'Copy the string with least significant nibble on the left
        strWrk = Mid(strWrk, ((nStart) \ 4) + 1) 'Trim off the least significant nibbles
        strWrk = Left(strWrk, ((nEnd - nStart + 1 + (nStart mod 4)) \ 4) + 1) 'Trim off the upper part
        
        nRaw = CLng("&H" & StrReverse(strWrk)) 'This is the number from the hexadecimal digits
        nMask = (2 ^ (nEnd - nStart + 1)) - 1 'Calculate the bitmask to apply
        nShift = 2 ^ (nStart mod 4) 'Calculate the multiplier for the mask and the result
        ReadBits = (nRaw and (nMask * nShift)) / nShift
    End Function
    
    Private Sub WriteBits(ByRef strIn, nStart, nEnd, nValue)
        'This routine will store bits into the input string
        
        Dim strWrk, nRaw, nMask, nShift, sA, sB
        
        strWrk = StrReverse(strIn) 'Copy the string with least significant nibble on the left
        sA = Left(strWrk, (nStart \ 4)) 'The least significant nibbles
        strWrk = Mid(strWrk, Len(sA) + 1) 'Trim off the least significant nibbles
        sB = Mid(strWrk, ((nEnd - nStart + 1 + (nStart mod 4)) \ 4) + 2) 'The upper part
        strWrk = Left(strWrk, ((nEnd - nStart + 1 + (nStart mod 4)) \ 4) + 1) 'Trim off the upper part
        
        nRaw = CLng("&H" & StrReverse(strWrk)) 'This is the current number
        nShift = 2 ^ (nStart mod 4) 'Calculate the multiplier 
        nMask = (2 ^ (nEnd - nStart + 1)) - 1 'Calculate the bitmask to apply
        'Zero out the area for the bits
        nRaw = nRaw or (nMask * nShift)
        nRaw = nRaw xor (nMask * nShift)
        'Put in the new value
        nRaw = nRaw or (nValue * nShift)
        'Convert this to a hex string
        strWrk = StrReverse(String(Len(strWrk)-Len(Hex(nRaw)),"0") & Hex(nRaw))
        'Update the input string
        strIn = StrReverse(sA & strWrk & sB)
    End Sub
End Class

'***************************************************************************************************
' SMS_ST_NonRecurring
'***************************************************************************************************
Class SMS_ST_NonRecurring
    Private m_DayDuration, m_HourDuration, m_IsGMT, m_MinuteDuration, m_StartTime
    Private m_Class
    
    Public Sub Class_Initialize()
        m_Class = "SMS_ST_NonRecurring"
        m_DayDuration = 0
        m_HourDuration = 0
        m_IsGMT = False
        m_MinuteDuration = 0
        m_StartTIme = CDate("1/1/1990")
    End Sub
    
    Public Property Get Class_()
        Class_ = m_Class
    End Property
    
    Public Property Get ToString()
        Dim strWrk
        
        strWrk = ""
        
        If (m_DayDuration > 0) or (m_HourDuration > 0) or (m_MinuteDuration > 0) Then _
            strWrk = "A window of " & m_DayDuration & " day(s), " & m_HourDuration & _
            " hour(s), and " & m_MinuteDuration & " minute(s) "
        If strWrk = "" Then
            strWrk = "Starting on/at " & FormatDateTime(m_StartTime)
        Else
            strWrk = strWrk & "starting on/at " & FormatDateTime(m_StartTime)
        End If
        
        If m_IsGMT Then strWrk = strWrk & " GMT"
        
        ToString = strWrk
    End Property
    
    Public Property Get DayDuration()
        DayDuration = m_DayDuration
    End Property
    
    Public Property Let DayDuration(nDay)
        If IsNumeric(nDay) Then
            If (CLng(nDay) >= 0) and (CLng(nDay) <= 31) Then m_DayDuration = CLng(nDay)
        End If
    End Property
    
    Public Property Get HourDuration()
        HourDuration = m_HourDuration
    End Property
    
    Public Property Let HourDuration(nHour)
        If IsNumeric(nHour) Then
            If (CLng(nHour) >= 0) and (CLng(nHour) <= 23) Then m_HourDuration = CLng(nHour)
        End If
    End Property
    
    Public Property Get IsGMT()
        IsGMT = m_IsGMT
    End Property
    
    Public Property Let IsGMT(bGMT)
        If VarType(bGMT) = 11 Then
            m_GMT = bGMT
        Else
            On Error Resume Next
            m_GMT = CBool(bGMT)
            On Error Goto 0
        End If
    End Property
    
    Public Property Get MinuteDuration()
        MinuteDuration = m_MinuteDuration
    End Property
    
    Public Property Let MinuteDuration(nMinute)
        If IsNumeric(nMinute) Then
            If (CLng(nMinute) >= 0) and (CLng(nMinute) <= 59) Then m_MinuteDuration = CLng(nMinute)
        End If
    End Property
    
    Public Property Get StartTime()
        StartTime = m_StartTime
    End Property
    
    Public Property Let StartTime(dStartTime)
        If IsDate(dStartTime) Then m_StartTime = CDate(dStartTime)
    End Property
End Class

'***************************************************************************************************
' SMS_ST_RecurInterval
'***************************************************************************************************
Class SMS_ST_RecurInterval
    Private m_DayDuration, m_HourDuration, m_IsGMT, m_MinuteDuration, m_StartTime 
    Private m_Class 
    Private m_DaySpan, m_HourSpan, m_MinuteSpan 
    
    Public Sub Class_Initialize()
        m_Class = "SMS_ST_RecurInterval"
        m_DayDuration = 0
        m_HourDuration = 0
        m_IsGMT = False
        m_MinuteDuration = 0
        m_StartTIme = CDate("1/1/1990")
        m_DaySpan = 0
        m_HourSpan = 0
        m_MinuteSpan = 0
    End Sub
    
    Public Property Get Class_()
        Class_ = m_Class
    End Property
    
    Public Property Get ToString()
        Dim strWrk
        
        strWrk = ""
        
        If (m_DayDuration > 0) or (m_HourDuration > 0) or (m_MinuteDuration > 0) Then _
            strWrk = "A window of " & m_DayDuration & " day(s), " & m_HourDuration & _
            " hour(s), and " & m_MinuteDuration & " minute(s) "
        If strWrk = "" Then
            strWrk = "Starting on/at " & FormatDateTime(m_StartTime)
        Else
            strWrk = strWrk & "starting on/at " & FormatDateTime(m_StartTime)
        End If
        If m_IsGMT Then strWrk = strWrk & " GMT"
        strWrk = strWrk & " recurring every"
        If m_DaySpan > 0 Then strWrk = strWrk & " " & m_DaySpan & " day(s)"
        If m_HourSpan > 0 Then strWrk = strWrk & " " & m_HourSpan & " hour(s)"
        If m_MinuteSpan > 0 Then strWrk = strWrk & " " & m_MinuteSpan & " minute(s)"
        ToString = strWrk
    End Property
    
    Public Property Get DayDuration()
        DayDuration = m_DayDuration
    End Property
    
    Public Property Let DayDuration(nDay)
        If IsNumeric(nDay) Then
            If (CLng(nDay) >= 0) and (CLng(nDay) <= 31) Then m_DayDuration = CLng(nDay)
        End If
    End Property
    
    Public Property Get HourDuration()
        HourDuration = m_HourDuration
    End Property
    
    Public Property Let HourDuration(nHour)
        If IsNumeric(nHour) Then
            If (CLng(nHour) >= 0) and (CLng(nHour) <= 23) Then m_HourDuration = CLng(nHour)
        End If
    End Property
    
    Public Property Get IsGMT()
        IsGMT = m_IsGMT
    End Property
    
    Public Property Let IsGMT(bGMT)
        If VarType(bGMT) = 11 Then
            m_GMT = bGMT
        Else
            On Error Resume Next
            m_GMT = CBool(bGMT)
            On Error Goto 0
        End If
    End Property
    
    Public Property Get MinuteDuration()
        MinuteDuration = m_MinuteDuration
    End Property
    
    Public Property Let MinuteDuration(nMinute)
        If IsNumeric(nMinute) Then
            If (CLng(nMinute) >= 0) and (CLng(nMinute) <= 59) Then m_MinuteDuration = CLng(nMinute)
        End If
    End Property
    
    Public Property Get StartTime()
        StartTime = m_StartTime
    End Property
    
    Public Property Let StartTime(dStartTime)
        If IsDate(dStartTime) Then m_StartTime = CDate(dStartTime)
    End Property
    
    Public Property Get DaySpan()
        DaySpan = m_DaySpan
    End Property
    
    Public Property Let DaySpan(nDaySpan)
        If IsNumeric(nDaySpan) Then
            If (CLng(nDaySpan) >= 0) and (CLng(nDaySpan) <= 31) Then m_DaySpan = CLng(nDaySpan)
        End If
    End Property
    
    Public Property Get HourSpan()
        HourSpan = m_HourSpan
    End Property
    
    Public Property Let HourSpan(nHourSpan)
        If IsNumeric(nHourSpan) Then
            If (CLng(nHourSpan) >= 0) and (CLng(nHourSPan) <= 23) Then m_HourSpan = CLng(nHourSpan)
        End If
    End Property
    
    Public Property Get MinuteSpan()
        MinuteSpan = m_MinuteSpan
    End Property
    
    Public Property Let MinuteSpan(nMinuteSpan)
        If IsNumeric(nMinuteSpan) Then
            If (CLng(nMinuteSpan) >= 0) and (CLng(nMinuteSpan) <= 59) Then m_MinuteSpan = CLng(nMinuteSpan)
        End If
    End Property
End Class

'***************************************************************************************************
' SMS_ST_RecurWeekly
'***************************************************************************************************
Class SMS_ST_RecurWeekly
    Private m_DayDuration, m_HourDuration, m_IsGMT, m_MinuteDuration, m_StartTime
    Private m_Class
    Private m_Day, m_ForNumberOfWeeks
    
    Public Sub Class_Initialize()
        m_Class = "SMS_ST_RecurWeekly"
        m_DayDuration = 0
        m_HourDuration = 0
        m_IsGMT = False
        m_MinuteDuration = 0
        m_StartTIme = CDate("1/1/1990")
        m_Day = 1
        m_ForNumberOfWeeks = 1
    End Sub
    
    Public Property Get Class_()
        Class_ = m_Class
    End Property
    
    Public Property Get ToString()
        Dim strWrk
        
        strWrk = ""
        
        If (m_DayDuration > 0) or (m_HourDuration > 0) or (m_MinuteDuration > 0) Then _
            strWrk = "A window of " & m_DayDuration & " day(s), " & m_HourDuration & _
            " hour(s), and " & m_MinuteDuration & " minute(s) "
        If strWrk = "" Then
            strWrk = "Starting on/at " & FormatDateTime(m_StartTime)
        Else
            strWrk = strWrk & "starting on/at " & FormatDateTime(m_StartTime)
        End If
        If m_IsGMT Then strWrk = strWrk & " GMT"
        strWrk = strWrk & " recurring every " & m_ForNumberOfWeeks & " week(s) on " & WeekdayName(m_Day)
        ToString = strWrk
    End Property
    
    Public Property Get DayDuration()
        DayDuration = m_DayDuration
    End Property
    
    Public Property Let DayDuration(nDay)
        If IsNumeric(nDay) Then
            If (CLng(nDay) >= 0) and (CLng(nDay) <= 31) Then m_DayDuration = CLng(nDay)
        End If
    End Property
    
    Public Property Get HourDuration()
        HourDuration = m_HourDuration
    End Property
    
    Public Property Let HourDuration(nHour)
        If IsNumeric(nHour) Then
            If (CLng(nHour) >= 0) and (CLng(nHour) <= 23) Then m_HourDuration = CLng(nHour)
        End If
    End Property
    
    Public Property Get IsGMT()
        IsGMT = m_IsGMT
    End Property
    
    Public Property Let IsGMT(bGMT)
        If VarType(bGMT) = 11 Then
            m_GMT = bGMT
        Else
            On Error Resume Next
            m_GMT = CBool(bGMT)
            On Error Goto 0
        End If
    End Property
    
    Public Property Get MinuteDuration()
        MinuteDuration = m_MinuteDuration
    End Property
    
    Public Property Let MinuteDuration(nMinute)
        If IsNumeric(nMinute) Then
            If (CLng(nMinute) >= 0) and (CLng(nMinute) <= 59) Then m_MinuteDuration = CLng(nMinute)
        End If
    End Property
    
    Public Property Get StartTime()
        StartTime = m_StartTime
    End Property
    
    Public Property Let StartTime(dStartTime)
        If IsDate(dStartTime) Then m_StartTime = CDate(dStartTime)
    End Property
    
    Public Property Get Day()
        Day = m_Day
    End Property 
    
    Public Property Let Day(nDay)
        If IsNumeric(nDay) Then
            If (CLng(nDay) >= 1) and (CLng(nDay) <= 7) Then m_Day = CLng(nDay)
        End If
    End Property
    
    Public Property Get ForNumberOfWeeks()
        ForNumberOfWeeks = m_ForNumberOfWeeks
    End Property
    
    Public Property Let ForNumberOfWeeks(nWeeks)
        If IsNumeric(nWeeks) Then
            If (CLng(nWeeks) >= 1) and (CLng(nWeeks) <= 4) Then m_ForNumberOfWeeks = CLng(nWeeks)
        End If
    End Property
End Class

'***************************************************************************************************
' SMS_ST_RecurMonthlyByWeekday
'***************************************************************************************************
Class SMS_ST_RecurMonthlyByWeekday
    Private m_DayDuration, m_HourDuration, m_IsGMT, m_MinuteDuration, m_StartTime
    Private m_Class
    Private m_Day, m_ForNumberOfMonths, m_WeekOrder
    
    Public Sub Class_Initialize()
        m_Class = "SMS_ST_RecurMonthlyByWeekday"
        m_DayDuration = 0
        m_HourDuration = 0
        m_IsGMT = False
        m_MinuteDuration = 0
        m_StartTIme = CDate("1/1/1990")
        m_Day = 1
        m_ForNumberOfMonths = 1
        m_WeekOrder = 0
    End Sub
    
    Public Property Get Class_()
        Class_ = m_Class
    End Property
    
    Public Property Get ToString()
        Dim strWrk
        
        strWrk = ""
        
        If (m_DayDuration > 0) or (m_HourDuration > 0) or (m_MinuteDuration > 0) Then _
            strWrk = "A window of " & m_DayDuration & " day(s), " & m_HourDuration & _
            " hour(s), and " & m_MinuteDuration & " minute(s) "
        If strWrk = "" Then
            strWrk = "Starting on/at " & FormatDateTime(m_StartTime)
        Else
            strWrk = strWrk & "starting on/at " & FormatDateTime(m_StartTime)
        End If
        If m_IsGMT Then strWrk = strWrk & " GMT"
        
        strWrk = strWrk & " recurring every " & m_ForNumberOfMonths & " month(s) on the "
        
        Select Case m_WeekOrder
            Case 0: strWrk = strWrk & "last "
            Case 1: strWrk = strWrk & "first "
            Case 2: strWrk = strWrk & "second "
            Case 3: strWrk = strWrk & "third "
            Case 4: strWrk = strWrk & "fourth "
        End Select
        
        strWrk = strWrk & WeekdayName(m_Day)
        
        ToString = strWrk
    End Property
    
    Public Property Get DayDuration()
        DayDuration = m_DayDuration
    End Property
    
    Public Property Let DayDuration(nDay)
        If IsNumeric(nDay) Then
            If (CLng(nDay) >= 0) and (CLng(nDay) <= 31) Then m_DayDuration = CLng(nDay)
        End If
    End Property
    
    Public Property Get HourDuration()
        HourDuration = m_HourDuration
    End Property
    
    Public Property Let HourDuration(nHour)
        If IsNumeric(nHour) Then
            If (CLng(nHour) >= 0) and (CLng(nHour) <= 23) Then m_HourDuration = CLng(nHour)
        End If
    End Property
    
    Public Property Get IsGMT()
        IsGMT = m_IsGMT
    End Property
    
    Public Property Let IsGMT(bGMT)
        If VarType(bGMT) = 11 Then
            m_GMT = bGMT
        Else
            On Error Resume Next
            m_GMT = CBool(bGMT)
            On Error Goto 0
        End If
    End Property
    
    Public Property Get MinuteDuration()
        MinuteDuration = m_MinuteDuration
    End Property
    
    Public Property Let MinuteDuration(nMinute)
        If IsNumeric(nMinute) Then
            If (CLng(nMinute) >= 0) and (CLng(nMinute) <= 59) Then m_MinuteDuration = CLng(nMinute)
        End If
    End Property
    
    Public Property Get StartTime()
        StartTime = m_StartTime
    End Property
    
    Public Property Let StartTime(dStartTime)
        If IsDate(dStartTime) Then m_StartTime = CDate(dStartTime)
    End Property
    
    Public Property Get Day()
        Day = m_Day
    End Property
    
    Public Property Let Day(nDay)
        If IsNumeric(nDay) Then
            If (CLng(nDay) >= 1) and (CLng(nDay) <= 7) Then m_Day = CLng(nDay)
        End If
    End Property
    
    Public Property Get ForNumberOfMonths()
        ForNumberOfMonths = m_ForNumberOfMonths
    End Property
    
    Public Property Let ForNumberOfMonths(nMonths)
        If IsNumeric(nMonths) Then
            If (CLng(nMonths) >= 1) and (CLng(nMonths) <= 12) Then m_ForNumberOfMonths = CLng(nMonths)
        End If
    End Property
    
    Public Property Get WeekOrder()
        WeekOrder = m_WeekOrder
    End Property
    
    Public Property Let WeekOrder(nWeekOrder)
        If IsNumeric(nWeekOrder) Then
            If (CLng(nWeekOrder) >= 0) and (CLng(nWeekOrder) <= 4) Then m_WeekOrder = CLng(nWeekOrder)
        End If
    End Property
End Class

'***************************************************************************************************
' SMS_ST_RecurMonthlyByDate
'***************************************************************************************************
Class SMS_ST_RecurMonthlyByDate
    Private m_DayDuration, m_HourDuration, m_IsGMT, m_MinuteDuration, m_StartTime
    Private m_Class
    Private m_ForNumberOfMonths, m_MonthDay
    
    Public Sub Class_Initialize()
        m_Class = "SMS_ST_RecurMonthlyByDate"
        m_DayDuration = 0
        m_HourDuration = 0
        m_IsGMT = False
        m_MinuteDuration = 0
        m_StartTIme = CDate("1/1/1990")
        m_ForNumberOfMonths = 1
        m_MonthDay = 0
    End Sub
    
    Public Property Get Class_()
        Class_ = m_Class
    End Property
    
    Public Property Get ToString()
        Dim strWrk
        
        strWrk = ""
        
        If (m_DayDuration > 0) or (m_HourDuration > 0) or (m_MinuteDuration > 0) Then _
            strWrk = "A window of " & m_DayDuration & " day(s), " & m_HourDuration & _
            " hour(s), and " & m_MinuteDuration & " minute(s) "
        If strWrk = "" Then
            strWrk = "Starting on/at " & FormatDateTime(m_StartTime)
        Else
            strWrk = strWrk & "starting on/at " & FormatDateTime(m_StartTime)
        End If
        If m_IsGMT Then strWrk = strWrk & " GMT"
        
        strWrk = strWrk & " recurring "
        If m_MonthDay = 0 Then
            strWrk = strWrk & "the last day"
        Else
            strWrk = strWrk & "day " & m_MonthDay
        End If
        strWrk = strWrk & " of every " & m_ForNumberOfMonths & " month(s)"
        
        ToString = strWrk
    End Property
    
    Public Property Get DayDuration()
        DayDuration = m_DayDuration
    End Property
    
    Public Property Let DayDuration(nDay)
        If IsNumeric(nDay) Then
            If (CLng(nDay) >= 0) and (CLng(nDay) <= 31) Then m_DayDuration = CLng(nDay)
        End If
    End Property
    
    Public Property Get HourDuration()
        HourDuration = m_HourDuration
    End Property
    
    Public Property Let HourDuration(nHour)
        If IsNumeric(nHour) Then
            If (CLng(nHour) >= 0) and (CLng(nHour) <= 23) Then m_HourDuration = CLng(nHour)
        End If
    End Property
    
    Public Property Get IsGMT()
        IsGMT = m_IsGMT
    End Property
    
    Public Property Let IsGMT(bGMT) 
        If VarType(bGMT) = 11 Then
            m_GMT = bGMT
        Else
            On Error Resume Next
            m_GMT = CBool(bGMT)
            On Error Goto 0
        End If
    End Property
    
    Public Property Get MinuteDuration()
        MinuteDuration = m_MinuteDuration
    End Property
    
    Public Property Let MinuteDuration(nMinute)
        If IsNumeric(nMinute) Then
            If (CLng(nMinute) >= 0) and (CLng(nMinute) <= 59) Then m_MinuteDuration = CLng(nMinute)
        End If
    End Property
    
    Public Property Get StartTime()
        StartTime = m_StartTime
    End Property
    
    Public Property Let StartTime(dStartTime)
        If IsDate(dStartTime) Then m_StartTime = CDate(dStartTime)
    End Property
    
    Public Property Get ForNumberOfMonths()
        ForNumberOfMonths = m_ForNumberOfMonths
    End Property
    
    Public Property Let ForNumberOfMonths(nMonths)
        If IsNumeric(nMonths) Then
            If (CLng(nMonths) >= 1) and (CLng(nMonths) <= 12) Then m_ForNumberOfMonths = CLng(nMonths)
        End If
    End Property
    
    Public Property Get MonthDay()
        MonthDay = m_MonthDay
    End Property
    
    Public Property Let MonthDay(nMonthDay)
        If IsNumeric(nMonthDay) Then
            If (CLng(nMonthDay) >= 0) and (CLng(nMonthDay) <= 12) Then m_MonthDay = CLng(nMonthDay)
        End If
    End Property
End Class