📄 datetime.hhf
字号:
#if( ! @defined( datetime_hhf ))?datetime_hhf := true;#includeonce( "hla.hhf" )namespace date; @fast; const minYear := 1600; maxYear := 3000; type daterec: record day :uns8; month :uns8; year :uns16; endrecord; type OutputFormat: enum { mdyy, mdyyyy, mmddyy, mmddyyyy, yymd, yyyymd, yymmdd, yyyymmdd, MONdyyyy, MONTHdyyyy, badDateFormat }; static DaysToMonth :uns32[13]; @external( "DATE_DAYSTOMONTH" ); DaysInMonth :uns32[13]; @external( "DATE_DAYSINMONTH" ); DaysFromMonth :uns32[13]; @external( "DATE_DAYSFROMMONTH" ); Months :string[13]; @external( "DATE_MONTHS" ); shortMonths :string[13]; @external( "DATE_SHORTMONTHS" ); DateSeparator :char; @external( "DATE_SEPARATOR" ); DateFormat :OutputFormat; @external( "DATE_FORMAT" ); // _isDateRec_- // // This is a utility macro that returns true or false // depending upon whether the parameter is a date.daterec // object. This is for internal use within this header file. #macro _isDateRec_( _dr_ ); #if( @typename( _dr_ ) = "daterec" ) #if ( @defined( _dr_.month ) & @defined( _dr_.day ) & @defined( _dr_.year ) ) true #else false #endif #else false #endif #endmacro // _isMDY_ // // This is another utility macro. It checks its parameters // to ensure that they are all valid m.d.y types. #macro _isMDY_( _m_, _d_, _y_ ):_error_; ?_error_ := !hla.isNumber( _m_ ) | !hla.isNumber( _d_) | !hla.isNumber( _y_); #if( !_error_ ) ?_error_ := ( !@IsConst( _m_ ) & @size( _m_ ) <> 1 ) | ( !@IsConst( _d_ ) & @size( _d_ ) <> 1 ) | ( !@IsConst( _y_ ) & @size( _y_ ) <> 2 ); #endif (!_error_) #endmacro // date.unpack- // // The first parameter is a date.daterec object. The remaining // parameters are dword objects. This macro unpacks the date // in the daterec parameter into its constituent parts. // No range checking is done on the date value. #macro unpack( _dr_, _y_, _m_, _d_ ); #if( !@global:date._isDateRec_( _dr_ ) ) #error( "Expected a date.daterec type as the 1st parameter" ) #elseif ( !( hla.IsNumber( _y_ ) & @size(_y_) = 4 ) & !( hla.IsNumber( _m_ ) & @size(_m_) = 4 ) & !( hla.IsNumber( _d_ ) & @size(_y_) = 4 ) ) #error( "Month, Day, and Year values must be dword objects" ) #else push( eax ); movzx( dr.d, eax ); mov( eax, _d_ ); movzx( _dr_.m, eax ); mov( eax, _m_ ); movzx( _dr_.y, eax ); mov( eax, _y_ ); pop( eax ); #endif #endmacro // date.pack- // // This macro takes three dword objects representing the // month, day, and year and packs these values into a // daterec variable. Minimal range checking is done on the // date value. val yStr :string := "";; mStr :string := ""; dStr :string := ""; #macro pack( _m_, _d_, _y_, dr ); ?@global:date.yStr := @lowercase( @string:_y_, 0); ?@global:date.mStr := @lowercase( @string:_m_, 0); ?@global:date.dStr := @lowercase( @string:_d_, 0); #if( !@global:date._isDateRec_( dr )) #error( "Expected a date.daterec type as the 4th parameter" ) // Handle the special case where m and day are both constants: #elseif( @isconst(_d_) & @isconst(_m_)) #if( (_d_) > 31 | (_d_) = 0 | (_m_) > 12 | (_m_) = 0 ) #error( "Month or Day value is out of range" ) #endif #if( @isconst( _y_ )) #if( (_y_) < @global:date.minYear | (_y_) > @global:date.maxYear ) #error( "Year value is out of range" ) #endif mov( (_d_) + ((_m_) << 8) + ((_y_)<<16), dr ); #elseif( @isreg16( _y_ )) mov( (_d_) + ((_m_) << 8), (type word dr)); mov( _y_, dr.year ); #else push( eax ); mov( (_d_) + ((_m_) << 8), (type word dr)); mov( _y_, ax ); mov( ax, dr.year ); pop( eax ); #endif #elseif( @isreg8(_m_) & @isreg8(_d_)) #if ( @substr( @global:date.dStr, 1, 1 ) = "l" & @substr( @global:date.mStr, 1, 1 ) = "h" & @substr( @global:date.dStr, 0, 1 ) = @substr( @global:date.mStr, 0, 1 ) ) mov ( @text( @substr( @global:date.dStr, 0, 1) + "x"), (type word dr) ); #else mov( _d_, dr.day ); mov( _m_, dr.month ); #endif #if( @isreg16(_y_) | @isconst(_y_) ) mov( _y_, dr.year ); #else push( eax ); mov( (type word _y_), ax ); mov( ax, dr.year ); pop( eax ); #endif #else push( eax ); #if( @isconst( _d_ ) ) #if( (_d_) <= 31 & (_d_) > 0 ) mov( _d_, al ); #else #error( "Day value is out of range" ); #endif #elseif( @global:date.dStr <> "al" ) mov( (type byte _d_), al ); #endif #if( @isconst( _m_ ) ) #if( (_m_) <= 12 & (_m_) > 0 ) mov( _m_, ah ); #else #error( "Month value is out of range" ); #endif #elseif( @global:date.mStr = "al" ) mov( (type byte [esp]), ah ); #elseif( @global:date.mStr <> "ah" ) mov( (type byte _m_), ah ); #endif mov( ax, (type word dr)); #if( @isconst( _y_ ) ) #if( (_y_) < @global:date.maxYear & (_y_) >= @global:minYear ) mov( _y_, dr.year ); #else #error( "Year value is out of range" ); #endif #elseif( @isreg16( _y_ )) #if( @global:date.yStr = "ax" ) mov( [esp], ax ); mov( ax, dr.year ); #else mov( _y_, dr.year ); #endif #else mov( (type word _y_), ax ); mov( ax, dr.year ); #endif pop( eax ); #endif #endmacro procedure utc( var todaysDate:daterec ); @external( "DATE_UTC" ); procedure today( var todaysDate:daterec ); @external( "DATE_TODAY" ); procedure setSeparator( c:char ); @external( "DATE_SETSEPARATOR" ); procedure setFormat( f:OutputFormat ); @external( "DATE_SETFORMAT" ); procedure addDays( days:uns32; var theDate:daterec ); @external( "DATE_ADDDAYS" ); procedure subDays( days:uns32; var theDate:daterec ); @external( "DATE_SUBDAYS" ); procedure addMonths( months:uns32; var theDate:daterec ); @returns( "eax" ); @external( "DATE_ADDMONTHS" ); procedure subMonths( months:uns32; var theDate:daterec ); @returns( "eax" ); @external( "DATE_SUBMONTHS" ); procedure addYears( years:uns32; var theDate:daterec ); @external( "DATE_ADDYEARS" ); procedure subYears( years:uns32; var theDate:daterec ); @external( "DATE_SUBYEARS" ); procedure fromJulian( Julian:uns32; var Gregorian:daterec ); @external( "DATE_FROMJULIAN" ); // IsLeapYear- // // Returns true in AL if the date/year passed as a parameter // is a leap year, false otherwise. // // Note that IsLeapYear is a macro that overloads the _IsLeapYear // procedure allowing either a date.daterec, word, or dword parameter. procedure _isLeapYear( Year:word ); @returns( "al" ); @external( "DATE_ISLEAPYEAR" ); #macro isLeapYear( _y_ily_ ); #if( @global:date._isDateRec_( _y_ily_ )) @global:date._isLeapYear( _y_ily_.year ) #elseif( @IsConst( _y_ily_ )) @global:date._isLeapYear( #{ pushd( _y_ily_ ); }# ) #elseif( hla.isNumber( _y_ily_ ) & @size(_y_ily_) = 2 ) @global:date._isLeapYear( #{ pushw(0); pushw( _y_ily_ ); }# ) #elseif( hla.isNumber( _y_ily_ ) & @size(_y_ily_) = 4 ) @global:date._isLeapYear( #{ push( _y_ily_ ); }# ) #else #error( "isLeapYear parameter error" ) #endif #endmacro // validate- // // Checks the date passed as a parameter to see if it is valid. // Raises the "ex.InvalidDate" exception if it is not valid. // // Note that date.validate is a macro that overloads the // date._validate procedure, allowing a daterec or (m,d,y) // parameters to be passed. procedure _validate( dr:daterec ); @external( "DATE_VALIDATE" ); #macro validate( _m_, _dy_[] ); #if( @elements( _dy_ ) = 0 ) // y had better be a daterec object // if we had only one parameter. #if( @global:date._isDateRec_( _m_ )) @global:date._validate( _m_ ) #else #error( "Expected a daterec type as the parameter" ) #endif #elseif( @elements( _dy_ ) = 2 ) #if( @global:date._isMDY_( _m_, @text( _dy_[0]), @text( _dy_[1]))) @global:date._validate ( #{ pushw( @text(_dy_[1]) ); push( ax ); push( eax ); mov( @text(_dy_[0]), al ); mov( _m_, ah ); mov( ax, [esp+4] ); pop( eax ); }# ) #else #error( "Syntax error in validate parameter list" ); #endif #else #error ( "Error in date.validate parameter list" nl "Usage: date.validate( dr:daterec ) or " nl " date.validate( m:word; d:word; y:word )" ) #endif #endmacro // isValid- // // Checks the date passed as a parameter to see if it is valid. // Returns true/false in AL to denote the validity of the parameter. // // Note that date.IsValid is a macro that overloads the // date._IsValid procedure, allowing a daterec or (m,d,y) // parameters to be passed. procedure _isValid( dr:daterec ); @returns( "al" ); @external( "DATE_ISVALID" ); #macro isValid( _m_, _dy_[] ); #if( @elements( _dy_ ) = 0 ) // y had better be a daterec object // if we had only one parameter. #if( @global:date._isDateRec_( _m_ ) ) @global:date._isValid( _m_ ) #else #error( "Expected a daterec type as the parameter" ) #endif #elseif( @elements( _dy_ ) = 2 ) #if( @global:date._isMDY_( _m_, @text( _dy_[0] ), @text( _dy_[1]))) @global:date._isValid ( #{ pushw( @text(_dy_[1]) ); push( ax ); push( eax ); mov( @text(_dy_[0]), al ); mov( _m_, ah ); mov( ax, [esp+4] ); pop( eax ); }# ) #else #error( "Syntax error in IsValid parameter list" ) #endif #else #error ( "Error in date.isValid parameter list" nl "Usage: date.isValid( dr:daterec ) or " nl " date.isValid( m:word; d:word; y:word )" ) #endif #endmacro procedure _toJulian( dr:daterec ); @returns( "eax" ); @external( "DATE_JULIAN" ); #macro toJulian( _m_, _dy_[] ); #if( @elements( _dy_ ) = 0 ) // m had better be a daterec object // if we had only one parameter. #if( @global:date._isDateRec_( _m_ ) ) @global:date._toJulian( _m_ ) #else #error( "Julian expected a daterec type as the parameter" ) #endif #elseif( @elements( _dy_ ) = 2 ) #if( @global:date._isMDY_( _m_, @text( _dy_[0] ), @text( _dy_[1])) ) @global:date._toJulian ( #{ pushw( @text(_dy_[1]) ); push( ax ); push( eax ); mov( @text(_dy_[0]), al ); mov( _m_, ah ); mov( ax, [esp+4] ); pop( eax ); }# ) #else #error( "Syntax error in Julian parameter list" ); #endif #else #error ( "Error in toJulian parameter list" nl "Usage: toJulian( dr:daterec ) or " nl " toJulian( m:word; d:word; y:word )" ) #endif #endmacro
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -