Think of it as an expanded version of PB's own FormatDate() command.
For PHP's syntax, see their documentation here: http://php.net/manual/en/function.date.php
EnableExplicit-friendly, cross-platform compileable, comes with a ready-to-run example!
A single procedure, with no global variables or macros to carry with it!
But be aware it is a work in progress!
A few of the format codes have not been implemented yet, and the time zone codes are not implemented on Mac/Linux!
And it is not 100% verified... (for example, some padding lengths might differ from PHP's?)
I am completely open to suggestions, contributions, and improvements!
Code: Select all
; +---------------+
; | PHPFormatDate |
; +---------------+
; | 8.21.2011 . Creation (PB 4.51)
; | .22. . Added full date/time combos, Swatch time, difference from GMT
; | .23. - Version 1.0 (for PB forums)
; | 5.11.2016 - Version 1.1 (corrected day prefixes such as "st")
; | 1.23.2017 - Version 1.2 (corrected GMT offset bug when passing midnight)
;
;
;
; This procedure mimics the native date() function of the PHP language.
; It can be used as an expanded replacement for PB's FormatDate() function,
; but be aware that it uses completely different syntax!
; The Timestamp argument defaults to -1, which is replaced by the current time.
;
; The format syntax (list of character codes) matches PHP's syntax here:
; *** http://php.net/manual/en/function.date.php ***
;
;
;
; Note the following exceptions, and their contribution to the result:
;
; 'u' (microseconds) PB timestamps do not use microseconds, always becomes "000000"
; 'W' (ISO week number) not implemented, becomes "?"
; 'o' (ISO year) not implemented, becomes "?"
; 'e' (time zone ID) not implemented, becomes "?"
; 'I' (daylight savings flag) not implemented, becomes "?"
; 'T' (time zone abbreviation) not implemented, becomes "?"
;
; Also:
; * Time zones are not yet implemented on Mac/Linux. GMT offset will alway be 00:00.
;
; PHPFormatDate (Version 1.2)
Procedure.s PHPFormatDate(Format.s, Timestamp.i = -1)
Protected Result.s
Protected Year.i, Month.i, Day.i, Hour.i, Minute.i, Second.i
Protected FromGMT.i, GMTHour.s, GMTMinute.s, Temp.i
Protected *C.CHARACTER
; Use current time, by default
If (Timestamp = -1)
Timestamp = Date()
EndIf
; OS-dependent code for getting time zone info (GMT offset)
CompilerIf (#PB_Compiler_OS = #PB_OS_Windows)
Protected GMTTime.SYSTEMTIME, LocalTime.SYSTEMTIME
; Retrieve GMT and local times
GetSystemTime_(GMTTime)
GetLocalTime_(LocalTime)
FromGMT = (LocalTime\wHour - GMTTime\wHour)*60 + (LocalTime\wMinute - GMTTime\wMinute)
If (GMTTime\wDayOfWeek = (LocalTime\wDayOfWeek + 1) % 7)
FromGMT - 24*60
ElseIf (GMTTime\wDayOfWeek = (LocalTime\wDayOfWeek + 7 - 1) % 7)
FromGMT + 24*60
EndIf
; Format time zone offset appropriately
If (FromGMT > 0)
GMTHour = "+" + RSet(Str(FromGMT / 60), 2, "0")
GMTMinute = RSet(Str(FromGMT % 60), 2, "0")
Else
GMTHour = "-" + RSet(Str((0-FromGMT) / 60), 2, "0")
GMTMinute = RSet(Str((0-FromGMT) % 60), 2, "0")
EndIf
CompilerElse
; Mac and Linux GMT code not yet implemented
FromGMT = 0
GMTHour = "+00"
GMTMinute = "00"
CompilerEndIf
; Extract numeric timestamp values
Year = Year (Timestamp)
Month = Month (Timestamp)
Day = Day (Timestamp)
Hour = Hour (Timestamp)
Minute = Minute(Timestamp)
Second = Second(Timestamp)
; Parse through each format character
Result = ""
*C = @Format
While (*C\c)
Select (*C\c)
; Day representations
Case 'd' : Result + RSet(Str(Day), 2, "0")
Case 'D'
Select (DayOfWeek(Timestamp))
Case 0 : Result + "Sun"
Case 1 : Result + "Mon"
Case 2 : Result + "Tue"
Case 3 : Result + "Wed"
Case 4 : Result + "Thu"
Case 5 : Result + "Fri"
Case 6 : Result + "Sat"
EndSelect
Case 'j' : Result + Str(Day)
Case 'l'
Select (DayOfWeek(Timestamp))
Case 0 : Result + "Sunday"
Case 1 : Result + "Monday"
Case 2 : Result + "Tuesday"
Case 3 : Result + "Wednesday"
Case 4 : Result + "Thursday"
Case 5 : Result + "Friday"
Case 6 : Result + "Saturday"
EndSelect
Case 'N' : Result + Str(((DayOfWeek(Timestamp) + 6) % 7) + 1)
Case 'S'
Select (Day)
Case 1, 21, 31 : Result + "st"
Case 2, 22 : Result + "nd"
Case 3, 23 : Result + "rd"
Default : Result + "th"
EndSelect
Case 'w' : Result + Str(DayOfWeek(Timestamp))
Case 'z' : Result + Str(DayOfYear(Timestamp)-1)
; Week representations
Case 'W' : Result + "?" ; ISO week (not implemented)
; Month representations
Case 'F'
Select (Month)
Case 1 : Result + "January"
Case 2 : Result + "February"
Case 3 : Result + "March"
Case 4 : Result + "April"
Case 5 : Result + "May"
Case 6 : Result + "June"
Case 7 : Result + "July"
Case 8 : Result + "August"
Case 9 : Result + "September"
Case 10 : Result + "October"
Case 11 : Result + "November"
Case 12 : Result + "December"
EndSelect
Case 'm' : Result + RSet(Str(Month), 2, "0")
Case 'M'
Select (Month)
Case 1 : Result + "Jan"
Case 2 : Result + "Feb"
Case 3 : Result + "Mar"
Case 4 : Result + "Apr"
Case 5 : Result + "May"
Case 6 : Result + "Jun"
Case 7 : Result + "Jul"
Case 8 : Result + "Aug"
Case 9 : Result + "Sep"
Case 10 : Result + "Oct"
Case 11 : Result + "Nov"
Case 12 : Result + "Dec"
EndSelect
Case 'n' : Result + Str(Month)
Case 't'
Select (Month)
Case 1,3,5,7,8,10,12
Result + "31"
Case 2
If (Year % 400 = 0)
Result + "29"
ElseIf (Year % 100 = 0)
Result + "28"
ElseIf (Year % 4 = 0)
Result + "29"
Else
Result + "28"
EndIf
Case 4,6,9,11
Result + "30"
EndSelect
; Year representations
Case 'L'
If (Year % 400 = 0)
Result + "1"
ElseIf (Year % 100 = 0)
Result + "0"
ElseIf (Year % 4 = 0)
Result + "1"
Else
Result + "0"
EndIf
Case 'o' : Result + "?" ; ISO year (not implemented)
Case 'Y' : Result + Str(Year)
Case 'y' : Result + RSet(Str(Year % 100), 2, "0")
; Time representations
Case 'a'
If (Hour >= 12)
Result + "pm"
Else
Result + "am"
EndIf
Case 'A'
If (Hour >= 12)
Result + "PM"
Else
Result + "AM"
EndIf
Case 'B'
Result + RSet(Str((36000*Hour + 600*Minute + 10*Second) / 864), 3, "0")
Case 'g' : Result + Str(((Hour + 23) % 12) + 1)
Case 'G' : Result + Str(Hour)
Case 'h' : Result + RSet(Str(((Hour + 23) % 12) + 1), 2, "0")
Case 'H' : Result + RSet(Str(Hour), 2, "0")
Case 'i' : Result + RSet(Str(Minute), 2, "0")
Case 's' : Result + RSet(Str(Second), 2, "0")
Case 'u' : Result + "000000" ; microseconds (not implemented)
; Timezone representations
Case 'e' : Result + "?" ; Timezone identifier (not implemented)
Case 'I' : Result + "?" ; Daylight savings flag (not implemented)
Case 'O' : Result + GMTHour + GMTMinute
Case 'P' : Result + GMTHour + ":" + GMTMinute
Case 'T' : Result + "?" ; Timezone abbreviation (not implemented)
Case 'Z' : Result + Str(FromGMT*60)
; Full date/time
Case 'c' : Result + PHPFormatDate("Y-m-d\TH:i:sP")
Case 'r' : Result + PHPFormatDate("D, d M Y H:i:s O", Timestamp)
Case 'U' : Result + RSet(Str(Timestamp), 11, "0")
; Escape or pass all other characters
Case '\' : *C + SizeOf(CHARACTER) : Result + Chr(*C\c)
Default : Result + Chr(*C\c)
EndSelect
*C + SizeOf(CHARACTER)
Wend
ProcedureReturn (Result)
EndProcedure
; =======================================================================================
;- EXAMPLE PROGRAM
; =======================================================================================
CompilerIf (#PB_Compiler_IsMainFile)
;Debug PHPFormatDate("r", Date(2014, 8, 1, 16, 14, 0)) : End
; Create array of all valid codes
#PHPFormats = 38
Dim PHPFormat.s(#PHPFormats - 1)
PHPFormat( 0) = "d"
PHPFormat( 1) = "D"
PHPFormat( 2) = "j"
PHPFormat( 3) = "l"
PHPFormat( 4) = "N"
PHPFormat( 5) = "S"
PHPFormat( 6) = "w"
PHPFormat( 7) = "z"
PHPFormat( 8) = "W"
PHPFormat( 9) = "F"
PHPFormat(10) = "m"
PHPFormat(11) = "M"
PHPFormat(12) = "n"
PHPFormat(13) = "t"
PHPFormat(14) = "L"
PHPFormat(15) = "o"
PHPFormat(16) = "Y"
PHPFormat(17) = "y"
PHPFormat(18) = "a"
PHPFormat(19) = "A"
PHPFormat(20) = "B"
PHPFormat(21) = "g"
PHPFormat(22) = "G"
PHPFormat(23) = "h"
PHPFormat(24) = "H"
PHPFormat(25) = "i"
PHPFormat(26) = "s"
PHPFormat(27) = "u"
PHPFormat(28) = "e"
PHPFormat(29) = "I"
PHPFormat(30) = "O"
PHPFormat(31) = "P"
PHPFormat(32) = "T"
PHPFormat(33) = "Z"
PHPFormat(34) = "c"
PHPFormat(35) = "r"
PHPFormat(36) = "U"
PHPFormat(37) = "\\"
; Create window with ListIcon
OpenWindow(0, 0, 0, 400, 600, "PHPFormatDate Demonstration", #PB_Window_ScreenCentered|#PB_Window_MinimizeGadget|#PB_Window_Invisible)
ListIconGadget(0, 0, 0, WindowWidth(0), WindowHeight(0), "Format", 195, #PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect)
AddGadgetColumn(0, 1, "Result", 195)
SmartWindowRefresh(0,1)
; An example format string
Define Main.s = "\I\t \i\s l \t\h\e jS, \o\f M Y."
AddGadgetItem(0, 0, Main)
; Add all valid formats
Define i.i, Event.i, Timestamp.i
For i = 0 To #PHPFormats - 1
AddGadgetItem(0, i+1, PHPFormat(i))
Next i
; Timer to update
AddWindowTimer(0, 0, 1000)
Repeat
Event = WaitWindowEvent()
; Update all fields
If (Event = #PB_Event_Timer)
Timestamp.i = Date()
SetGadgetItemText(0, 0, PHPFormatDate(Main, Timestamp), 1)
For i = 0 To #PHPFormats - 1
SetGadgetItemText(0, i+1, PHPFormatDate(PHPFormat(i), Timestamp), 1)
Next i
HideWindow(0, 0)
EndIf
Until (Event = #PB_Event_CloseWindow)
CompilerEndIf
; EOF