Page 1 of 1

Get localized day and month names?

Posted: Sun Jun 12, 2016 7:32 pm
by Little John
Hi,

Gnozal has shown here, how to get localized day and month names on Windows. This is pretty comfortable, because when doing it this way in a multi-language program, we don't have to create long lists of the names ourselves.

How can we get localized day and month names with API functions on Linux?

Re: Get localized day and month names?

Posted: Mon Jun 13, 2016 3:41 am
by Keya
my goognizzling suggests strftime() :)
http://man7.org/linux/man-pages/man3/strftime.3.html

i managed to put this demo together which is working so it's probably the right way to go, but its a bit rough!!
i tested in OSX and it works there too, always love two birds with one stone :)
... strangely, it also works on Windows! (not sure if its supposed to be Import or ImportC - they both seem to work!)
make that all 3 of our birds!?

Make sure you compile with Ascii for this demo, i dont know yet if it works with Unicode
(it returns 3 with Ascii, 1 with Unicode, but perhaps the buffer just needs more space or something i dont know)
anyway i have to head out for a bit now but i will check further when i get home :)

note: we're supposed to fill in the tm structure with the current date before calling, which im not doing in this demo (so it's showing the current time for '0')

Code: Select all

ImportC ""
  strftime.i (*s, max, *fmt, *tm)
EndImport

Structure _tm
  tm_sec.i
  tm_min.i
  tm_hour.i
  tm_mday.i
  tm_mon.i
  tm_year.i
  tm_wday.i
  tm_yday.i
  tm_isdst.i
EndStructure

s.s = Space(256)  ;buffer for result
fmt.s = "%a"
max = Len(s)
Define tm._tm
retval = strftime(@s, Len(s), @fmt, @tm)
Debug "Result=" + Str(retval)
Debug "s=" + s
it seems this api has only been used in 3 other PB posts according to google:
http://forum.purebasic.com/english/view ... 12&t=26950
http://forum.purebasic.com/english/view ... 13&t=61044
http://www.purebasic.fr/english/viewtopic.php?t=30293

Re: Get localized day and month names?

Posted: Mon Jun 13, 2016 12:01 pm
by cas
This should work for both x86 and x64, ascii and unicode. Tested on windows and linux, should work also on osx:

Code: Select all

EnableExplicit

ImportC ""
  time(*timer=#Null)
  localtime(*timer)
  strftime(*ptr, maxsize, format.p-ascii, *tm)
EndImport

Structure tm
  tm_sec.l
  tm_min.l
  tm_hour.l
  tm_mday.l
  tm_mon.l
  tm_year.l
  tm_wday.l
  tm_yday.l
  tm_isdst.l
EndStructure

Define rawtime = time()
Define *tm.tm = localtime(@rawtime)
Define s.s = Space(80)  ;buffer for result
Define fmt.s = "month=%B day=%A"
Define retval = strftime(@s, StringByteLength(s.s)+1, fmt.s, *tm)
Debug PeekS(@s, -1, #PB_Ascii)
Instead of calling time() and localtime(), you can fill tm structure manually before calling strftime().

Re: Get localized day and month names?

Posted: Mon Jun 13, 2016 5:47 pm
by Little John
Hi,

thanks for pointing to the right track. :-)

Yes, strftime() also works on Windows. But it returns English day and month names here (on Windows 10), not the localized German names.
( On English Windows versions, there is no difference between "English" and "localized". :-) )

On Linux, strftime() returns localized German day and month names (tested on Linux Mint 17.3).
This is the code that I needed, maybe it's also useful for someone else (works in ASCII mode and Unicode mode):

Code: Select all

; PB 5.42 LTS

EnableExplicit

Structure tm
   tm_sec.l
   tm_min.l
   tm_hour.l
   tm_mday.l
   tm_mon.l
   tm_year.l
   tm_wday.l
   tm_yday.l
   tm_isdst.l
EndStructure


Procedure.s LocalizedDayName (DayOfWeek.i, short.i=#False)
   ; in : DayOfWeek: Sunday=0, ..., Saturday=6
   ;                 (compliant with PureBasic's DayOfWeek() function)
   ;      short    : #True/#False
   ; out: short or full localized name of given weekday
   Protected tm.tm, fmt.i, numBytes.i, buffer$, bufferSize.i=80
   
   If short
      fmt = $6125      ; "%a"
   Else
      fmt = $4125      ; "%A"
   EndIf
   
   buffer$ = Space(bufferSize)
   tm\tm_wday = DayOfWeek
   numBytes = strftime_(@buffer$, bufferSize*SizeOf(Character), @fmt, @tm)
   
   ProcedureReturn PeekS(@buffer$, numBytes, #PB_UTF8|#PB_ByteLength)
EndProcedure


Procedure.s LocalizedMonthName (MonthOfYear.i, short.i=#False)
   ; in : MonthOfYear: January=1, ..., December=12
   ;                   (compliant with PureBasic's Month() function)
   ;      short      : #True/#False
   ; out: short or full localized name of given month
   Protected tm.tm, fmt.i, numBytes.i, buffer$, bufferSize.i=80
   
   If short
      fmt = $6225      ; "%b"
   Else
      fmt = $4225      ; "%B"
   EndIf
   
   buffer$ = Space(bufferSize)
   tm\tm_mon = MonthOfYear - 1
   numBytes = strftime_(@buffer$, bufferSize*SizeOf(Character), @fmt, @tm)
   
   ProcedureReturn PeekS(@buffer$, numBytes, #PB_UTF8|#PB_ByteLength)
EndProcedure


; -- Demo
Define i.i

For i = 0 To 6
   Debug LocalizedDayName(i)
Next
Debug "--------"
For i = 0 To 6
   Debug LocalizedDayName(i, #True)
Next

Debug "========"

For i = 1 To 12
   Debug LocalizedMonthName(i)
Next
Debug "--------"
For i = 1 To 12
   Debug LocalizedMonthName(i, #True)
Next