Advanced FormatDate()

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
va!n
Addict
Addict
Posts: 1104
Joined: Wed Apr 20, 2005 12:48 pm

Advanced FormatDate()

Post by va!n »

Would be nice to have following options too... (for example 02 = February)

Code: Select all

%mm     ; Returns "02"
%mmm    ; Returns "Feb"
%mmmm   ; Returns "February"
va!n aka Thorsten

Intel i7-980X Extreme Edition, 12 GB DDR3, Radeon 5870 2GB, Windows7 x64,
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

agree. and localized of course.
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

a handy solution (no api but not localized) :

Code: Select all

removed
Last edited by Flype on Tue Jan 16, 2007 2:41 pm, edited 1 time in total.
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
va!n
Addict
Addict
Posts: 1104
Joined: Wed Apr 20, 2005 12:48 pm

Post by va!n »

@Flype:
cool! very nice! :)
va!n aka Thorsten

Intel i7-980X Extreme Edition, 12 GB DDR3, Radeon 5870 2GB, Windows7 x64,
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

yeah it is !

but here is a more complete one (localized) :

Code: Select all

removed
and by the way GetCalendarInfo_() isn't defined in PB4
even if the associated constants (#CAL_) are defined. :roll:
Last edited by Flype on Tue Jan 16, 2007 2:29 pm, edited 1 time in total.
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

Flype wrote:and by the way GetCalendarInfo_() isn't defined in PB4
even if the associated constants (#CAL_) are defined. :roll:
And no GetCalendarInfo() function in Windows NT4 or 95 kernel32.dll.
It's for 98/ME and 2k/XP only.
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

yes i know but it should be enough for most people !

MSDN say 'Included in Windows 98 and later.'
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

well,


1/ Here is a short and handy cross-platform solution (but not localized) :

Code: Select all

Macro FormatDate2(mask, date)
FormatDate(ReplaceString(ReplaceString(mask,"%ddd",StringField("Sun,Mon,Tue,Wed,Thu,Fri,Sat",DayOfWeek(date)+1,",")),"%mmm",StringField("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec",Month(date),",")),date)
EndMacro

Debug FormatDate2("%dd.%mm.%yyyy %hh:%ii:%ss", Date())
Debug FormatDate2("%ddd %dd %mmm %yyyy %hh:%ii:%ss", Date())

2/ Even if i don't care about Win95 nor NT4, here is a compatible one :

Code: Select all

Procedure.s GetDateFormat(mask.s, date.l)
  Protected st.SYSTEMTIME, result.s = Space(64)
  st\wDay   = Day  (date)
  st\wMonth = Month(date)
  st\wYear  = Year (date)
  If GetDateFormat_(#LOCALE_USER_DEFAULT, 0, @st, mask, @result, 64) 
    ProcedureReturn UCase(Left(result, 1)) + Right(result, Len(result) - 1)
  EndIf
EndProcedure

Procedure.s FormatDate2(mask.s, date.l)
  mask = ReplaceString(mask, "%dddd", GetDateFormat("dddd", date))
  mask = ReplaceString(mask, "%ddd",  GetDateFormat("ddd",  date))
  mask = ReplaceString(mask, "%mmmm", GetDateFormat("MMMM", date))
  mask = ReplaceString(mask, "%mmm",  GetDateFormat("MMM",  date))
  ProcedureReturn FormatDate(mask, date)
EndProcedure

Debug FormatDate2("%ddd %dd %mmm %yyyy  %hh:%ii:%ss", Date())
Debug FormatDate2("%dddd %dd %mmmm %yyyy  %hh:%ii:%ss", Date())

3/ And another localized function for Windows 98 and later :

Code: Select all

Import "kernel32.lib"
  GetCalendarInfoA(lcID.l, calID.l, calType.l, *lpCalData, cchData.l, *lpValue)
EndImport

Procedure.s GetCalendarInfo(type.l)
  Protected result.s = Space(64)
  If GetCalendarInfoA(#LOCALE_USER_DEFAULT, #CAL_GREGORIAN, type, @result, 64, 0)
    ProcedureReturn UCase(Left(result, 1)) + Right(result, Len(result) - 1)
  EndIf
EndProcedure

Procedure.s FormatDate2(mask.s, date.l)
  mask = ReplaceString(mask, "%dddd", GetCalendarInfo(#CAL_SDAYNAME1         + DayOfWeek(date) - 1))
  mask = ReplaceString(mask, "%mmmm", GetCalendarInfo(#CAL_SMONTHNAME1       + Month(date)     - 1))
  mask = ReplaceString(mask, "%ddd",  GetCalendarInfo(#CAL_SABBREVDAYNAME1   + DayOfWeek(date) - 1))
  mask = ReplaceString(mask, "%mmm",  GetCalendarInfo(#CAL_SABBREVMONTHNAME1 + Month(date)     - 1))
  ProcedureReturn FormatDate(mask, date)
EndProcedure

Debug FormatDate2("%ddd %dd %mmm %yyyy  %hh:%ii:%ss", Date())
Debug FormatDate2("%dddd %dd %mmmm %yyyy  %hh:%ii:%ss", Date())
Last edited by Flype on Tue Jan 16, 2007 2:40 pm, edited 4 times in total.
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

Flype wrote:
even if i don't care about Win95 nor NT4, here is a compatible one :
Does anyone even use '95 anymore?

Anyway, good routine, thanks.
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

Flype wrote:even if i don't care about Win95 nor NT4
:D
Flype wrote:here is a compatible one
Thanks
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Re: Advanced FormatDate()

Post by AND51 »

va!n wrote:Would be nice to have following options too... (for example 02 = February)

Code: Select all

%mm     ; Returns "02"
%mmm    ; Returns "Feb"
%mmmm   ; Returns "February"
This would be to much work, because I want to have "Montag" and not "Monday". My birhtday is in "Oktober" and not in "October".

I mean: you cannot realize an advanced FormatDate() for all languages.
And if there is no german FormatDate, the germans
1) get angry/jealous
2) cannot use english Dates, because it's not useful for them
This does not only affect on the germans, but also n the french, spain, etc...

Solution: The best was to read the system configuration and try to find the day-names. Hover your clock in the systray and you'll see the day-name in you language; this name must be read to have a user-definded weekday (and everybody will be happy, even the germans). :wink:
PB 4.30

Code: Select all

onErrorGoto(?Fred)
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

just a question !

i can see that localized date strings (Win32 API) are all lower case !

in french we usually writes days and months with a first char capitalized :

not 'january' but 'January'.

does it depends of the country ?


well, in the two functions i provided i use this trick :

>> ProcedureReturn UCase(Left(result, 1)) + Right(result, Len(result) - 1)

but you can remove it if needed.

:?:
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Advanced FormatDate()

Post by Shardik »

AND51 wrote:
va!n wrote:Would be nice to have following options too... (for example 02 = February)

Code: Select all

%mm     ; Returns "02"
%mmm    ; Returns "Feb"
%mmmm   ; Returns "February"
This would be to much work, because I want to have "Montag" and not "Monday". My birhtday is in "Oktober" and not in "October".

I mean: you cannot realize an advanced FormatDate() for all languages.
And if there is no german FormatDate, the germans
1) get angry/jealous
2) cannot use english Dates, because it's not useful for them
This does not only affect on the germans, but also n the french, spain, etc...

Solution: The best was to read the system configuration and try to find the day-names. Hover your clock in the systray and you'll see the day-name in you language; this name must be read to have a user-definded weekday (and everybody will be happy, even the germans). :wink:
Here is a solution to read the month and day names (long and abbreviated) in the language defined in your OS (tested with Win98SE):

Code: Select all

Procedure.S GetLocaleSetting(SettingID.L)
  Protected Buffer.S
  Protected BufferSize.L
  Protected ErrorMsg.S
  Protected NumBytes.L

  BufferSize = GetLocaleInfo_(#LOCALE_USER_DEFAULT, SettingID, @Buffer, 0)

  Buffer = Space(BufferSize)

  NumBytes = GetLocaleInfo_(#LOCALE_USER_DEFAULT, SettingID, @Buffer, BufferSize)

  If NumBytes = 0
    Select GetLastError_()
      Case #ERROR_INSUFFICIENT_BUFFER
        ErrorMsg = "Insufficient buffer size!"
      Case #ERROR_INVALID_FLAGS
        ErrorMsg = "Invalid flags!"
      Case #ERROR_INVALID_PARAMETER
        ErrorMsg = "Invalid Parameter!"
      Default
        ErrorMsg = "GetLastError() returned undefined error code!"
    EndSelect

    MessageRequester("Error", ErrorMsg, #MB_ICONERROR)

    ProcedureReturn ""
  EndIf

  ProcedureReturn Buffer
EndProcedure


i.L
Setting.S

; ----- Long month names

Debug "Long month names:"

For i = #LOCALE_SMONTHNAME1 To #LOCALE_SMONTHNAME12
  Setting = GetLocaleSetting(i)

  If Setting <> ""
    Debug Setting
  Else
    End
  EndIf
Next i

Debug "-----"
Debug "Abbreviated month names:"

For i = #LOCALE_SABBREVMONTHNAME1	 To #LOCALE_SABBREVMONTHNAME12
  Setting = GetLocaleSetting(i)

  If Setting <> ""
    Debug Setting
  Else
    End
  EndIf
Next i

Debug "-----"
Debug "Long day names:"

For i = #LOCALE_SDAYNAME1 To #LOCALE_SDAYNAME7
  Setting = GetLocaleSetting(i)

  If Setting <> ""
    Debug Setting
  Else
    End
  EndIf
Next i

Debug "-----"
Debug "Abbreviated day names:"

For i = #LOCALE_SABBREVDAYNAME1 To #LOCALE_SABBREVDAYNAME7
  Setting = GetLocaleSetting(i)

  If Setting <> ""
    Debug Setting
  Else
    End
  EndIf
Next i
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

ah yes, thank you - this one is Win95/NT3.1 compatible.

so here is the FormatDate2 :

Code: Select all

Procedure.s GetLocaleInfo(type.l)
  Protected result.s = Space(GetLocaleInfo_(#LOCALE_USER_DEFAULT, type, 0, 0))
  If GetLocaleInfo_(#LOCALE_USER_DEFAULT, type, @result, Len(result))
    ProcedureReturn UCase(Left(result, 1)) + Right(result, Len(result) - 1)
  EndIf
EndProcedure

Procedure.s FormatDate2(mask.s, date.l)
  mask = ReplaceString(mask, "%dddd", GetLocaleInfo(#LOCALE_SDAYNAME1         + DayOfWeek(date) - 1))
  mask = ReplaceString(mask, "%mmmm", GetLocaleInfo(#LOCALE_SMONTHNAME1       + Month(date)     - 1))
  mask = ReplaceString(mask, "%ddd",  GetLocaleInfo(#LOCALE_SABBREVDAYNAME1   + DayOfWeek(date) - 1))
  mask = ReplaceString(mask, "%mmm",  GetLocaleInfo(#LOCALE_SABBREVMONTHNAME1 + Month(date)     - 1))
  ProcedureReturn FormatDate(mask, date)
EndProcedure

Debug FormatDate2("%ddd %dd %mmm %yyyy  %hh:%ii:%ss", Date())
Debug FormatDate2("%dddd %dd %mmmm %yyyy  %hh:%ii:%ss", Date()) 
Last edited by Flype on Thu Jan 18, 2007 9:09 am, edited 1 time in total.
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Post by Shardik »

@Flype

You don't need to set the first character to uppercase

Code: Select all

ProcedureReturn UCase(Left(result, 1)) + Right(result, Len(result) - 1)
A simple

Code: Select all

ProcedureReturn result
is sufficient because the day and month names are already returned correctly in upper/lowercase from the Win API call...
Post Reply