x char (30)
let x = today using "dd.mm.yyyy"
is there some special function ? or do i have to build one my self:
x charr (30),
xdate datetime year to fraction
let xdate = current
let x = xdate using "dd.mm.yyyy HH:MM:SS" ???????
--------------A7C30BD4A29
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Steen N. Hansen wrote:
>
> how do i make a format on a datetime, in a way like formating a date type:
>
> x char (30)
>
> let x = today using "dd.mm.yyyy"
>
> is there some special function ? or do i have to build one my self:
I have a NewEra class that does this sort or thing. The conversion to
4GL would be minor.
Header and File are attached. It's new and not throughly tested, so
please report any bugs. And of course, there's no warranty. Usage
comments are in the .4gl file.
//////////////// =======================================================
////////// // Dennis J. Pimple Informix Software, Inc.
////// / /// Principal Consultant 5299 DTC Blvd Suite 740
///// // //// den...@informix.com Englewood CO 80111
//// // /////
/// // ////// recept: 303-850-0210
// // /////// direct: 303-740-5611 Opinions expressed are mine,
/ /////////// fax: 303-843-6408 and do not necessarily
//////////////// http://www.informix.com reflect those of my employer
--------------A7C30BD4A29
Content-Type: text/plain; charset=us-ascii; name="cdatetf.4gh"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="cdatetf.4gh"
###############################################################################
###############################################################################
-------------------------------------------------------------------------------
--
-- Module Name : cdatetf.4gh
-- Description : CDateTime Format object
-- Version : 0.1
-- Date Created : 10/14/1997
-- Date Last Edited : 10/14/1997
--
-- Author : Dennis J. Pimple (den...@informix.com)
-- Informix Software Inc.
--
--
-- Date Revisions, Corrections, Bug Fixes, etc.
-- ---------- ---------------------------------------------------------------
--
-------------------------------------------------------------------------------
###############################################################################
###############################################################################
-------------------------------------------------------------------------
-------------------------------------------------------------------------
--
-- CLASS NAME: CDateTimeFormat
-- NOTES: CDateTimeFormat formats DATETIME values in various ways.
--
-------------------------------------------------------------------------
-------------------------------------------------------------------------
CLASS CDateTimeFormat
--
-- member variables
--
--
-- member functions
--
PUBLIC FUNCTION CDateTimeFormat()
--
--
PUBLIC FUNCTION formatDatetime(
theDatetime DATETIME YEAR TO FRACTION(5),
format CHAR(*) )
RETURNING CHAR(*)
--
PRIVATE FUNCTION DTToFormat( theDatetime DATETIME YEAR TO FRACTION(5),
format CHAR(*) )
RETURNING CHAR(*)
--
PRIVATE FUNCTION DateToFormat( theDate DATE, format CHAR(*) )
RETURNING CHAR(*)
END CLASS
--------------A7C30BD4A29
Content-Type: text/plain; charset=us-ascii; name="cdatetf.4gl"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="cdatetf.4gl"
################################################################################
################################################################################
--------------------------------------------------------------------------------
--
-- Module Name : CDATEF.4GL
-- Program Name : utillib.dll
-- Version : 1.0
-- Date Created : 10/14/1997
-- Date Last Edited : 10/14/1997
--
-- Author : Dennis Pimple (den...@informix.com)
-- Informix Software Inc.
--
-- Date Revisions, Corrections, Bug Fixes, etc.
-- ---------- ------------------------------------------------------------------
--
--------------------------------------------------------------------------------
################################################################################
################################################################################
--------------------------------------------------------------------------------
-- Informix System Header Files
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Project Specific Header Files
--------------------------------------------------------------------------------
INCLUDE "cdatetf.4gh"
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--
-- FUNCTION/OBJECT NAME : CDatetimeFormat::CDatetimeFormat
-- DESCRIPTION : Class Constructor
-- ARGUMENTS REQUIRED : NONE
-- RETURN VALUES : NONE
-- EVENTS RAISED : NONE
-- NOTES:
--
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
FUNCTION CDatetimeFormat::CDatetimeFormat()
END FUNCTION # CDatetimeFormat::CDatetimeFormat()
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--
-- FUNCTION/OBJECT NAME : CDatetimeFormat::formatDatetime
-- DESCRIPTION : Format the passed DATETIME
-- according to the passed string
-- ARGUMENTS REQUIRED : A DATETIME (YEAR to any scale), format string
-- RETURN VALUES : CHAR(*) with the formatted value
-- EVENTS RAISED : NONE
-- NOTES : any of the following will be interpreted.
-- Symbols for character strings will follow the shift pattern given
-- examples are for Monday, February 3, 1997 11:45:59.00000 pm
--
-- DATE FORMATS
-- wd Weekday 1
-- da/Da/DA 2-char day mo/Mo/MO
-- day/Day/DAY 3-char day mon/Mon/MON
-- dayf/Dayf/DAYF full day monday/Monday/MONDAY
-- d 1-digit day 3 (1-31)
-- dd day of month 03 (01-31)
-- mo/Mo/MO 3-char month feb/Feb/FEB
-- mon/Mon/MON full month february/February/FEBRUARY
-- m 1-digit month 2 (1-12)
-- mm numeric month 02 (01-12)
-- y 1-digit year 97 (1-99)
-- yy 2-digit year 97 (01-99)
-- yyyy 4-digit year 1997
-- TIME FORMATS
-- h am/pm 1-digit hour 11 (1-12, 12:00 am is midnight)
-- hr am/pm hour 11 (01-12, 12:00 am is midnight)
-- ht 1-dig 24-hour 23 (0-23, 00:00 is midnight)
-- hrt 24-hour 23 (00-23, 00:00 is midnight)
-- mi 1-dig minutes 45 (0-59)
-- min minutes 45 (00-59)
-- s 1-digit seconds 59 (0-59)
-- ss 2-digit seconds 59 (00-59)
-- f -> fffff fraction (1-5) 0-00-000-0000-00000 (0-99999)
-- a/p/A/P 1-char am pm p/P
-- am/Am/AM/pm/Pm/PM 2-char am pm pm/Pm/PM
-- any character string besides those will be copied exactly (including case)
--
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
FUNCTION CDatetimeFormat::formatDatetime(
theDatetime DATETIME YEAR TO FRACTION(5),
format CHAR(*) )
RETURNING CHAR(*)
-- return value
VARIABLE chFormat CHAR(*) = NULL
--
VARIABLE siLength SMALLINT
VARIABLE siPos SMALLINT
VARIABLE chF CHAR(*)
VARIABLE chFullF CHAR(*)
VARIABLE siFirstPos SMALLINT
IF theDatetime IS NOT NULL THEN
-- 1 6 9 12 15 18 21 25
-- yyyy-mm-dd hh:mm:ss.fffff
LET siLength = LENGTH( format )
LET siPos = 1
LET chF = NULL
WHILE siPos <= siLength
-- get the first character after the last format found
LET chF = format[ siPos ]
IF chF MATCHES "[wdDmMyhsfapAP]" THEN
-- is part of a legal format
LET siFirstPos = siPos
LET chFullF = NULL
WHILE TRUE
-- is this part of a full format?
-- the IN clauses below igonre any trailing spaces
-- (e.g. chF of "Day" and "Day " both are IN "Day" )
-- so we have to specially look for a blank space
-- since no legal format has a blank space,
-- it's pretty simple
IF chF IN ( "wd", "da", "Da", "DA", "day", "Day", "DAY",
"dayf", "Dayf", "DAYF", "d", "dd",
"mo", "Mo", "MO", "mon", "Mon", "MON",
"m", "mm", "y", "yy", "yyy", "yyyy",
"h", "hr", "ht", "hrt",
"mi", "min", "s", "ss",
"f", "ff", "fff", "ffff", "fffff",
"a", "p", "A", "P", "am", "Am", "AM",
"pm", "Pm", "PM" )
AND format[ siPos ] != " "
THEN
-- store the newest full format
IF chF != "yyy" THEN
LET chFullF = chF
END IF # chF != "yyy"
-- is this string one of the strings for which we must
-- keep checking?
IF siPos < siLength
AND chF IN ( "da", "Da", "DA", "day", "Day", "DAY",
"d",
"mo", "Mo", "MO",
"m", "y", "yy", "yyy",
"h", "hr", "ht",
"mi", "s",
"f", "ff", "fff", "ffff",
"a", "p", "A", "P" )
AND format[ siPos ] != " "
THEN
-- NAR; the while loop will take the next step
ELSE
-- add this (chF) to chFormat
LET chFormat =
chFormat, self.DTToFormat( theDatetime, chF )
-- increment the position pointer since the last
-- position was part of the format we're using
LET siPos = siPos + 1
EXIT WHILE
END IF # chF IN ( ...
ELSE
IF chFullF IS NOT NULL THEN
-- we do have something to add to chFormat
LET chFormat =
chFormat, self.DTToFormat( theDatetime, chFullF )
-- set siPos to the position after
-- the valid full format was found
-- so the next string test will start there
LET siPos = siFirstPos + LENGTH( chFullF )
EXIT WHILE
ELSE
-- NAR, the next loop will handle it
END IF # chFullF IS NOT NULL
END IF # chF IN ( ...
-- if we've gone through 7 characters
-- without finding anything ...
-- or have looked over the entire string.
IF siPos - siFirstPos = 6 OR siPos = siLength THEN
-- we never found a format,
-- so add the 1st char in the string
-- and set up to try again with the next
-- add the first character we found in the string
LET chFormat = chFormat, format[ siFirstPos ]
LET siPos = siFirstPos + 1
EXIT WHILE
END IF # siPos - siFirstPos = 6 OR siPos = siLength
-- try the next character
LET siPos = siPos + 1
IF siPos < siLength THEN
LET chF = chF, format[ siPos ]
END IF # siPos < siLength
END WHILE # TRUE
ELSE
-- this character isn't the start of any legal format;
-- copy it exactly
LET chFormat = chFormat, chF
-- and try the next position
LET siPos = siPos + 1
END IF # chF MATCHES "[wdDmMyhsfapAP]"
END WHILE # siPos <= siLength
END IF # theDatetime IS NOT NULL
RETURN chFormat
END FUNCTION # CDatetimeFormat::formatDatetime()
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--
-- FUNCTION/OBJECT NAME : CDatetimeFormat::DTToFormat
-- DESCRIPTION : Format the passed DATETIME
-- according to the passed string
-- ARGUMENTS REQUIRED : A DATETIME (YEAR to any scale),
-- : specific format string
-- RETURN VALUES : CHAR(*) with the formatted value
-- EVENTS RAISED : NONE
-- NOTES : This function imposes a single format rule from the
-- formatDatetime function and deals with it.
-- e.g. formatDatetime can be called with "Mon dd",
-- this function would be called twice: once with "Mon"
-- and once with "dd"
--
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
FUNCTION CDatetimeFormat::DTToFormat( theDatetime DATETIME YEAR TO FRACTION(5),
format CHAR(*) )
RETURNING CHAR(*)
VARIABLE chDatetime CHAR(*)
VARIABLE dtDatetime DATE
--
VARIABLE iDigit INTEGER
VARIABLE siLength SMALLINT
--
VARIABLE chFormat CHAR(*) = NULL
LET dtDatetime = EXTEND( theDatetime, YEAR TO DAY )
-- call a seperate function for the date parts to format,
-- in anticipation of a formatDate function
IF format IN ( "wd", "da", "Da", "DA", "day", "Day", "DAY",
"dayf", "Dayf", "DAYF", "d", "dd",
"mo", "Mo", "MO", "mon", "Mon", "MON",
"m", "mm", "y", "yy", "yyyy" )
THEN
LET chFormat = self.DateToFormat( dtDatetime, format )
ELSE
-- handle the time format stuff right here
LET chDatetime = theDatetime
-- 1 6 9 12 15 18 21 25
-- yyyy-mm-dd hh:mm:ss.fffff
CASE
WHEN format IN ( "h", "hr", "ht", "hrt",
"a", "p", "A", "P", "am", "Am", "AM",
"pm", "Pm", "PM" )
-- work with the hour
LET iDigit = chDatetime[ 12, 13 ]
IF format[1] MATCHES "[apAP]" THEN
-- am/pm rules
IF iDigit > 11 THEN
LET chFormat = "pm"
ELSE
LET chFormat = "am"
END IF # iDigit > 11
-- check for 1st char shifting
IF format[1] MATCHES "[AP]" THEN
LET chFormat[1] = UPSHIFT( chFormat[1] )
END IF # format[1] MATCHES "[AP]"
IF LENGTH( format ) = 1 THEN
-- truncate to 1 digit
LET chFormat = chFormat[1]
ELSE
-- check for full upshift
IF format[2] = "M" THEN
LET chFormat = UPSHIFT( chFormat )
END IF # format[2] = "M"
END IF # LENGTH( format ) = 1
ELSE # format IN ( "h", "hr", "ht", "hrt" )
IF format IN ( "h", "hr" ) THEN
-- non-military time
CASE
WHEN iDigit = 0
-- 12:00 am
LET iDigit = 12
WHEN iDigit > 12
-- 1->11 pm (12->23)
LET iDigit = iDigit - 12
OTHERWISE
-- NAR
END CASE # iDigit
END IF # format IN ( "h", "hr" )
IF format IN ( "h", "ht" ) THEN
-- 1 digit if it is
LET chFormat = iDigit USING "<&"
ELSE
LET chFormat = iDigit USING "&&"
END IF # format IN ( "h", "ht" )
END IF # format[1] MATCHES "[apAP]"
WHEN format IN ( "mi", "min" )
-- work with the minute
LET iDigit = chDatetime[ 15, 16 ]
IF format = "mi" THEN
LET chFormat = iDigit USING "<&"
ELSE
LET chFormat = iDigit USING "&&"
END IF # format = "mi"
WHEN format IN ( "s", "ss" )
-- work with the second
LET iDigit = chDatetime[ 18, 19 ]
IF format = "s" THEN
LET chFormat = iDigit USING "<&"
ELSE
LET chFormat = iDigit USING "&&"
END IF # format = "s"
OTHERWISE # format IN ( "f", "ff", "fff", "ffff", "fffff"
-- work with the fraction
LET chFormat = chDatetime[ 21, 25 ]
LET siLength = LENGTH( format )
LET chFormat = chFormat[ 1, siLength ]
END CASE # format IN
END IF # format IN ( "wd" ...
RETURN chFormat
END FUNCTION # CDateTimeFormat::DTToFormat( )
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--
-- FUNCTION/OBJECT NAME : CDatetimeFormat::DateToFormat
-- DESCRIPTION : Format the passed DATE
-- according to the passed string
-- ARGUMENTS REQUIRED : A DATE
-- : specific format string
-- RETURN VALUES : CHAR(*) with the formatted value
-- EVENTS RAISED : NONE
-- NOTES : This function imposes the single format rules
-- for date values from DTToFormat() above.
-- I'm anticipating having a FormatDate() function to
-- format date strings (and expansion of the USING clause),
-- at which time this function will be called directly
--
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
FUNCTION CDateTimeFormat::DateToFormat( theDate DATE, format CHAR(*) )
RETURNING CHAR(*)
VARIABLE chFormat CHAR(*) = NULL
--
VARIABLE siWeekday SMALLINT
VARIABLE siLength SMALLINT
VARIABLE siDigit SMALLINT
VARIABLE siCentury SMALLINT
LET siWeekday = WEEKDAY( theDate )
CASE
WHEN format = "wd"
LET chFormat = siWeekday USING "&"
WHEN format IN ( "da", "Da", "DA", "day", "Day", "DAY",
"dayf", "Dayf", "DAYF" )
CASE
WHEN siWeekday = 0
LET chFormat = "sunday"
WHEN siWeekday = 1
LET chFormat = "monday"
WHEN siWeekday = 2
LET chFormat = "tuesday"
WHEN siWeekday = 3
LET chFormat = "wednesday"
WHEN siWeekday = 4
LET chFormat = "thursday"
WHEN siWeekday = 5
LET chFormat = "friday"
WHEN siWeekday = 6
LET chFormat = "saturday"
END CASE # siWeekday
LET siLength = LENGTH( format )
IF siLength <= 3 THEN
-- truncate to 2 or 3 characters
LET chFormat = chFormat[1,siLength]
END IF # siLength <= 3
-- upshift as required
CASE
WHEN format[2] = "A"
LET chFormat = UPSHIFT( chFormat )
WHEN format[1] = "D"
LET chFormat[1] = UPSHIFT( chFormat[1] )
OTHERWISE
-- NAR
END CASE # format
WHEN format IN ( "d", "dd" )
LET siDigit = DAY( theDate )
IF format = "d" THEN
LET chFormat = siDigit USING "<&"
ELSE
LET chFormat = siDigit USING "&&"
END IF # format = "d"
WHEN format IN ( "mo", "Mo", "MO", "mon", "Mon", "MON", "m", "mm" )
LET siDigit = MONTH( theDate )
IF format IN ( "mo", "Mo", "MO", "mon", "Mon", "MON" ) THEN
-- character
CASE
WHEN siDigit = 1
LET chFormat = "january"
WHEN siDigit = 2
LET chFormat = "february"
WHEN siDigit = 3
LET chFormat = "march"
WHEN siDigit = 4
LET chFormat = "april"
WHEN siDigit = 5
LET chFormat = "may"
WHEN siDigit = 6
LET chFormat = "june"
WHEN siDigit = 7
LET chFormat = "july"
WHEN siDigit = 8
LET chFormat = "august"
WHEN siDigit = 9
LET chFormat = "september"
WHEN siDigit = 10
LET chFormat = "october"
WHEN siDigit = 11
LET chFormat = "november"
WHEN siDigit = 12
LET chFormat = "december"
END CASE # siDigit
IF LENGTH( format ) = 2 THEN
-- truncate to 3 characters
LET chFormat = chFormat[1,3]
END IF # LENGTH( format ) = 2
-- upshift as required
CASE
WHEN format[2] = "O"
LET chFormat = UPSHIFT( chFormat )
WHEN format[1] = "M"
LET chFormat[1] = UPSHIFT( chFormat[1] )
OTHERWISE
-- NAR
END CASE # format[
ELSE # "m", "mm"
IF format = "m" THEN
LET chFormat = siDigit USING "<&"
ELSE
LET chFormat = siDigit USING "&&"
END IF # format = "m"
END IF # format IN ( "mo", "Mo", "MO", "mon", "Mon", "MON" )
OTHERWISE # format IN ( "y", "yy", "yyyy" )
LET siDigit = YEAR( theDate )
IF LENGTH( format ) > 2 THEN
-- full year
LET chFormat = siDigit USING "&&&&"
ELSE
-- deduct the century
-- do it in several steps so rounding helps us
-- (i.e. doing it in one big step didn't work)
LET siCentury = siDigit / 100
LET siCentury = siCentury * 100
LET siDigit = siDigit - siCentury
IF format = "y" THEN
LET chFormat = siDigit USING "<&"
ELSE # "yy"
LET chFormat = siDigit USING "&&"
END IF # format = "y"
END IF # LENGTH( format ) > 2
END CASE # format IN
RETURN chFormat
END FUNCTION # CDateTimeFormat::DateToFormat( )
--------------A7C30BD4A29--
> how do i make a format on a datetime, in a way like formating a date
> type:
>
> x char (30)
> let x = today using "dd.mm.yyyy"
>
> is there some special function?
Not in I4GL, as such. Which is not to say that you couldn't write your own.
> or do i have to build one my self:
>
> x charr (30),
^ syntax error: the construct is not recognizable in this context :-)
> xdate datetime year to fraction
>
> let xdate = current
> let x = xdate using "dd.mm.yyyy HH:MM:SS" ???????
In some respects, it would not be too hard; there are various datetime
formatting routines available in ESQL/C (dttofmtasc(), etc), or you could
fall back on strftime() in ANSI C. However, these routines are all
loosely in the printf-family and use '%X' style notations to indicate
which elements of the date/time value are to be printed. You would have
to write a parser to convert strings such as "dd.mm.yyyy HH:MM:SS" into
the equivalent "%d.%m.%Y %H:%M:%S". You also wouldn't be able to use the
USING clause; you'd have to write:
LET x = format_datetime(xdate, "dd.mm.yyyy HH:MM:SS")
Yours,
Jonathan Leffler (jo...@informix.com) #include <witticism.h>