System Date/Time Format Problems

Ken Ray kray at sonsothunder.com
Mon Jul 4 09:24:35 EDT 2011


I have a handler I've been using for a while that works great with
formatting dates. Here it is (sorry for the length, but it's heavily
commented - oh and watch for word wraps):

----------------------------------------------------------------------
--| FUNCTION: stsFormattedDate
--|
--| Author:   Ken Ray
--| Version:  2.6
--| Created:  8/2/04
--| Last Mod: 2/8/11
--| Requires: --
--|
--| Formats an incoming date according to a variety of date
--| patterns and outputs the result.
--|
--| Parameters:
--|     <pDate>: The date to be formatted. Must be a date or
--|           date/time combination,  or empty. If empty, uses the
--|           current date and default 2AM time if time is
--|           requested in the pattern. Will also check to see if the
--|           date is a mySQL-formatted
--|           date if it can't be identified as a "normal" date.
--|     <pFormat>: The pattern to use to format the incoming date.
--|           The following patterns are available where "M" is used for
--|           the month, "D" for the day, "Y" for the year, "W" for
--|           the weekday name, "H" for hours, "P" for AM/PM,
--|           "N" for minutes, "S" for seconds, and "G" for GMT
--|           calculation, as follows:
--|                M = month number, no leading zeroes (1-12)
--|                MM = month number, with leading zeroes (01-12)
--|                MMM = month name, abbreviated (Jan - Dec)
--|                MMMM = month name, long (January - December)
--|                D = day number, no leading zeroes (1-31)
--|                DD = day number, with leading zeroes (01-31)
--|                W = weekday name, single letter (S/M/T/W/t/F/s)
--|                WW = weekday name, shortest (Su/M/Tu/W/Th/F/Sa)
--|                WWW = weekday name, abbreviated (Sun/Mon/Tue/Wed/
--|                     Thu/Fri/Sat)
--|                WWWW = weekday name, long (Sunday/Monday/Tuesday/etc.)
--|                YY = two-digit year (00-99)
--|                YYYY = four digit year (1970-2004)
--|                H = hours, no leading zeroes, 12 hour format (1-12)
--|                HH = hours, leading zeroes, 12 hour format (01-12)
--|                HHH = hours, no leading zeroes, 24 hour format (1-23)
--|                HHHH = hours, leading zeroes, 24 hour format (01-23)
--|                HHHHH = military time format (0000 - 2359)
--|                P = AM/PM, single character, lower case (a/p)
--|                PP = AM/PM, single character, upper case (A/P)
--|                PPP = AM/PM, two characters, lower case (am/pm)
--|                PPPP = AM/PM, two characters, upper case (AM/PM)
--|                N = minutes, no leading zeroes (0-59)
--|                NN = minutes, leading zeroes (00-59)
--|                S = seconds, no leading zeroes (0-59)
--|                SS = seconds, leading zeroes (00-59)
--|                G = GMT Offset (-1100 to +1100)
--|                GH = GMT Offset hours, including sign (-11 to +11)
--|                GM = GMT Offset minutes
--|     <pUseBrackets>: Determines whether or not the format needs to
--|           have brackets surrounding each part of the pattern. If true,
--|           it requires that all patterns are surrounded by square
--|           brackets, and allows the letters used in the pattern
--|           (MDYWHNSGP) to be used as part of the return string that
--|           is *not* part of the pattern (for example "GMT" as a string).
--|           If false, pattern letters are replaced by the corresponding
--|           date parts in the returned string (so it assumes that
--|           characters that are not part of the pattern are not letters,
--|           but symbols).
----------------------------------------------------------------------
function stsFormattedDate pDate,pFormat,pUseBrackets
  if (pDate = "") or (pDate = "Now") then put the date && the long time into
pDate
  if (pFormat = "") then put "MM/DD/YYYY" into pFormat
  if isNumber(word -1 of pDate) then
    if (word -1 of pDate <=2359) and (length(word -1 of pDate)=4) then
      -- date and military time sent in, just needs a colon between
      -- hour and minute for it to be converted
      put ":" before char -2 of pDate
    else
      -- simple number, coerce to AM
      if word -1 of pDate <= 12 then
        put ((word -1 of pDate) & ":00 AM") into word -1 of pDate
      else
        -- a number larger than 12 but not military? Can't do anything
        -- with that
        return "invalid time"
      end if
    end if
  end if
  
  -- Check for am/pm without preceding space
  put word -1 of pDate into tTestTime
  if (tTestTime <> "AM") and (tTestTime <> "PM") then
    put offset("a",tTestTime) into tLoc
    if (tLoc <> 0) and (char (tLoc-1) of pDate <> " ") then
      if char (tLoc+1) of tTestTime <> "m" then put "m" after \
         char tLoc of tTestTime
      put " " before char tLoc of tTestTime
      put word -2 of tTestTime into tTime
      if ":"is not in tTime then
        -- probably something like "2am"
        put (tTime & ":00") into word -2 of tTestTime
      end if
      put tTestTime into word -1 of pDate
    end if
    put offset("p",tTestTime) into tLoc
    if (tLoc <> 0) and (char (tLoc-1) of tTestTime <> " ") then
      if char (tLoc+1) of tTestTime <> "m" then put "m" after \
         char tLoc of tTestTime
      put " " before char tLoc of tTestTime
      put word -2 of tTestTime into tTime
      if ":"is not in tTime then
        -- probably something like "2pm"
        put (tTime & ":00") into word -2 of tTestTime
      end if
      put tTestTime into word -1 of pDate
    end if
  end if
  
  put ((pUseBrackets <> "") and (pUseBrackets <> "false")) into pUseBrackets
  put pDate into tOrigDate
  
  -- Check to see if it's mySQL-formatted
  if matchText(word 1 of pDate,"(?s)(.*)-(.*)-(.*)",tY,tM,tD) and \
        length(tY)=4 then
    if word 2 of pDate <> "" then
      put tM & "/" & tD & "/" & tY && (word 2 of pDate) into pDate
    else
      put tM & "/" & tD & "/" & tY into pDate
    end if
    convert pDate to dateItems
    if (pDate is "invalid date") or (("69" is not in tOrigDate) and \
        (item 1 of pDate="1969")) then
      return "invalid date"
    end if
  else
    convert pDate to dateItems
    if (pDate is "invalid date") or (("69" is not in tOrigDate) and \
       (item 1 of pDate="1969")) then
      return "invalid date"
    end if
  end if
  put item 1 of pDate into tYear
  put item 2 of pDate into tMonthNum
  put item 3 of pDate into tDayNum
  put item 4 of pDate into tHour
  put item 5 of pDate into tMinute
  put item 6 of pDate into tSecond
  put item 7 of pDate into tWeekdayNum
  put word -1 of the internet date into G
  put char -2 to -1 of G into GM
  put char 1 to -3 of G into GH
  set the numberFormat to "00"
  
  if pUseBrackets then
    put "[GH],[GM],[G],[MMMM],[MMM],[MM],[M],[WWWW],[WWW]," & \
        "[WW],[W],[DD],[D],[YYYY],[YY],[HHHHH],[HHHH],[HHH],[HH]," & \
        "[H],[PPPP],[PPP],[PP],[P],[NN],[N],[SS],[S]" into tFormatWords
  else
    put "GH,GM,G,MMMM,MMM,MM,M,WWWW,WWW,WW,W," & \
        "DD,D,YYYY,YY,HHHHH,HHHH,HHH,HH,H,PPPP,PPP," & \
        "PP,P,NN,N,SS,S" into tFormatWords
  end if
  put "!@#$%^&*()_+{}|:'<>?~`-=[]" into tReplaceChars
  repeat with x = 1 to the number of items of tFormatWords
    replace (item x of tFormatWords) with \
         "[[[" & char x of tReplaceChars & "]]]]" in pFormat
  end repeat
  
  put tYear into YYYY
  put char -2 to -1 of tYear into YY
  
  put tMonthNum into M
  put (tMonthNum+0) into MM
  put line tMonthNum of the abbreviated monthNames into MMM
  put line tMonthNum of the long monthNames into MMMM
  
  put tDayNum into D
  put (tDayNum+0) into DD
  
  put char tWeekDayNum of "SMTWtFs" into W
  put item tWeekDayNum of "S,M,Tu,W,Th,F,Sa" into WW
  put line tWeekDayNum of the abbreviated weekdayNames into WWW
  put line tWeekDayNum of the long weekdayNames into WWWW
  
  put tHour into HHH
  put (tHour+0) into HHHH
  if tHour < 12 then
    if tHour = 0 then put 12 into H
    else put tHour into H
    put "a" into P
    put "A" into PP
    put "am" into PPP
    put "AM" into PPPP
  else
    put tHour-12 into H
    if H = 0 then put 12 into H
    if H < 10 then
      delete char 1 of H  -- remove leading 0
    end if
    put "p" into P
    put "P" into PP
    put "pm" into PPP
    put "PM" into PPPP
  end if
  put (H+0) into HH
  
  put tMinute into N
  put (tMinute+0) into NN
  
  put HHHH & NN into HHHHH
  
  put tSecond into S
  put (tSecond+0) into SS
  
  repeat with x = 1 to the number of items of tFormatWords
    if pUseBrackets then
      local tTemp
      get matchText(item x of tFormatWords,"\[(.*?)\]",tTemp)
      do "put" && tTemp && "into tVal"
    else
      do "put" && (item x of tFormatWords) && "into tVal"
    end if
    replace "[[[" & char x of tReplaceChars & "]]]]"  with tVal in pFormat
  end repeat
  
  return pFormat
end stsFormattedDate



Use it like this:

put stsFormattedDate(the date && the long time,"M/D/YYYY HH:NN p")
--> 7/4/2011 08:23 a

Hopes this helps,

Ken Ray
Sons of Thunder Software, Inc.
Email: kray at sonsothunder.com
Web Site: http://www.sonsothunder.com/






More information about the use-livecode mailing list