Get localized day and month names?

Linux specific forum
Little John
Addict
Addict
Posts: 4527
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Get localized day and month names?

Post 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?
User avatar
Keya
Addict
Addict
Posts: 1891
Joined: Thu Jun 04, 2015 7:10 am

Re: Get localized day and month names?

Post 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
cas
Enthusiast
Enthusiast
Posts: 597
Joined: Mon Nov 03, 2008 9:56 pm

Re: Get localized day and month names?

Post 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().
Little John
Addict
Addict
Posts: 4527
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Get localized day and month names?

Post 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
Post Reply