Use AM/PM in timectrl.TimeCtrl (Windows)

When the last reference to the wx.Locale object is gone, and it’s destroyed, then the locale reverts to the setting that was in effect before the object was created.

Thus the self.locale = part is necessary, by design.

1 Like

Hi, Jalkhov

I tested your code on Windows 10 (JP) with Python 3.8.6 & wx 4.1.1 and It works on my PC if I added a few lines as follows (Please ignore check_locale):

import wx
import locale
from wx.lib.masked import TimeCtrl

## locale.setlocale(locale.LC_ALL, 'es_VE')
def check_locale():
    import time
    print(wx.GetLocale().Name)
    print(locale.getlocale(locale.LC_TIME))
    print(time.strftime('Now, %B %d %a %p %I:%M:%S'))
    try:
        wxdt = wx.DateTime.FromDMY(1, 0, 1970)
        print(wxdt.Format('%p'))
    except Exception:
        print('no support for am/pm')

class TimeFrame(wx.Frame):
    def __init__(self):
        
        wx.Frame.__init__(self, None, -1, 'TimeCtrl', wx.DefaultPosition, (200, 100))
        
        self.wxloc = wx.Locale(wx.LANGUAGE_SPANISH_VENEZUELA) # keep refs
        ## locale.setlocale(locale.LC_ALL, 'es_VE') # a.m./p.m. doesn't work.
        locale.setlocale(locale.LC_ALL, 'C') # %p must be formatted as 'AM/PM'
        check_locale()
        
        self.time_ctrl = TimeCtrl(self, -1,
                                  displaySeconds=False,
                                  size=wx.DefaultSize,
                                  fmt24hr=False,
                                  validator=wx.DefaultValidator,
                                  style=wx.TE_PROCESS_TAB)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.time_ctrl, 0, 0, 0)
        self.SetSizer(sizer)
        self.Layout()

class App(wx.App):
    def OnInit(self):
        frame = TimeFrame()
        frame.Show(True)
        return True
        
if __name__ == "__main__":
    app = App(0)
    app.MainLoop()

Clipboard20

Reading the original code of wx.lib.masked.timectrl.TimeCtrl, the fmt24hr seems to be set True if wx.DateTime object doesn’t format ‘%p’ as ‘AM’ or ‘PM’. Thus, ‘C’ (CPython’s default?) or ‘en_US’ should be used for the locale.

1 Like

Excelent, this works perectly. One doubt, does it also matter where the lines are added?:

self.wxloc = wx.Locale(wx.LANGUAGE_SPANISH_VENEZUELA)
locale.setlocale(locale.LC_ALL, 'C')

In this case you have done it in the __init__ and not in the OnInit.

The point is before the TimeCtrl object is created.
Normally, wx.App.InitLocale is a better place.

see also:

2 Likes

Yes, I understand. Thank you very much, and thanks to the others who also contributed n.n Issue resolved.