Sign in Join
Wiki copytemporary

DateTimeCtrls Package: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11## About
22
33The DateTimeCtrls package contains two controls:
44
55![](/wiki-images/6/63/TDateTimePicker.png) TDateTimePicker and ![](/wiki-images/3/34/TDBDateTimePicker.png)TDBDateTimePicker
66
77Delphi's VCL has a control named [TDateTimePicker](http://docwiki.embarcadero.com/Libraries/en/Vcl.ComCtrls.TDateTimePicker), which I find very useful for editing dates. LCL, however, does not have this control.
88
99Therefore, I tried to create a cross-platform Lazarus control which would resemble VCL's TDateTimePicker as much as possible.
1010
1111The TDateTimePicker does not use [native Win control](http://msdn.microsoft.com/en-us/library/system.windows.forms.datetimepicker.aspx). It descends from LCL-s TCustomControl to be cross-platform. It has been tested on Windows with Win32/64 and qt widgetsets and on Linux with gtk2 and qt widgetsets.
1212
1313Note that the TDateTimePicker control does not descend from TEdit, so it does not have unnecessary caret. The VCL's control doesn't have caret either.
1414
1515## Author
1616
1717
1818Zoran Vučenović
1919
2020## License
2121
2222Modified LGPL (same as the FPC RTL and the Lazarus LCL).
2323
2424## Getting the package
2525
2626This package is part of Lazarus distribution (since Lazarus 1.4). You can find it in \<*your_lazarus_folder*\>/components/datetimectrls.
2727
2828The components are installed on Component palette by default (if you build the IDE yourself, they are installed with "make bigide"). The components TDateTimePicker and TDBDateTimePicker are located in [[Common Controls tab|Common Controls]] and [[Data Controls tab|Data Controls]] palette pages, respectively.
2929
3030Since Lazarus 1.8 the designtime code is separated to another package DateTimeCtrlsDsgn. Normally, you should not care about this, but only if you are installing the controls in the IDE manually, you should know that it is actually the designtime package DateTimeCtrlsDsgn which is installed in the IDE.
3131
3232This separation of designtime code to different package is done to prevent the code which is needed only in design time to be linked in final executable. [[Lazarus 1.8.0 release notes|See the 1.8 release notes.]]
3333
3434## TDateTimePicker ![](/wiki-images/6/63/TDateTimePicker.png)
3535
3636### Properties
3737
3838I'll explain some properties of TDateTimePicker control:
3939
4040#### DateTime: TDateTime (public)
4141
4242
4343The DateTime value displayed on the control. This property is not published in object inspector, but its value is actually the same as Date and Time properties composed in one value. This property is provided to allow setting or reading of both date and time value at once in program code. In design time, Date and Time can be set in object inspector. There is also component editor which provides easy way of setting this property in design time.
4444
4545#### Date: TDate
4646
4747
4848The date displayed on the control which the user can edit.
4949
5050#### Time: TTime
5151
5252
5353The time displayed on the control which the user can edit.
5454
5555#### MinDate: TDate
5656
5757
5858The minimal date user can enter.
5959
6060#### MaxDate: TDate
6161
6262
6363The maximal date user can enter.
6464
6565#### NullInputAllowed: Boolean
6666
6767
6868When True, the user can set the date to NullDate constant by pressing N key.
6969
7070#### CenturyFrom: Word
7171
7272
7373When user enters the year in two-digit format, then the CenturyFrom property is used to determine which century the year belongs to. The default is 1941, which means that when two digit year is entered, it falls in interval 1941 – 2040. Note that MinDate and MaxDate properties can also have influence on the decision – for example, if the CenturyFrom is set to 1941 and MaxDate to 31. 12. 2010, if user enters year 23, it will be set to 1923, because it can’t be 2033, due to MaxDate limit.
7474
7575#### Kind: TDateTimeKind
7676
7777
7878**type** TDateTimeKind = (dtkDate, dtkTime, dtkDateTime);
7979
8080
8181The control displays only date, only time or both.
8282
83-<figure>
84-<img src="DateControls03.PNG" title="DateControls03.PNG" />
85-<figcaption>DateControls03.PNG</figcaption>
86-</figure>
83+![](/wiki-images/e/e3/DateControls03.PNG)
8784
8885#### DateMode: TDTDateMode
8986
9087
9188**type** TDTDateMode = (dmComboBox, dmUpDown, dmNone)
9289
9390
9491When DateMode is set to dmComboBox, there is a button on the right side of the control. When user clicks the button, [the calendar control](http://lazarus-ccr.sourceforge.net/docs/lcl/calendar/tcalendar.html) is shown, allowing the user to pick the date. When set to dmUpDown, then UpDown buttons are shown.
9592
9693
9794In my opinion the UpDown buttons aren't really useful in this control, they are provided for compatibility with Delphi's TDateTimePicker. Up and down keys can always serve for same purpose, so can mouse wheel.
9895
9996
10097In the picture the first control's DateMode is set to dmComboBox and the second control's to dmUpDown:
10198
102-<figure>
103-<img src="DateControls01.PNG" title="DateControls01.PNG" />
104-<figcaption>DateControls01.PNG</figcaption>
105-</figure>
99+![](/wiki-images/3/3d/DateControls01.PNG)
106100
107101#### ShowCheckBox: Boolean
108102
109103
110104When set, there is a check box on the left side of the control.
111105
112106By default, when unchecked, the display appears grayed and user interaction with the date is not possible. (The control is still enabled, though, only in sense that the check box remains enabled). This behaviour may be changed if dtpoEnabledIfUnchecked is added to Options property -- then this check box is shown, but does nothing by itself (doesn't disable the control) and the programmer can decide how it will be used (by using OnCheckBoxChange event).
113107
114-<figure>
115-<img src="DateControls02.PNG" title="DateControls02.PNG" />
116-<figcaption>DateControls02.PNG</figcaption>
117-</figure>
108+![](/wiki-images/2/2e/DateControls02.PNG)
118109
119110#### Checked: Boolean
120111
121112
122113If ShowCheckBox is set to True, this property determines whether the check box is checked or not. If ShowCheckBox is False, this property has no purpose and is automatically set to True.
123114
124115#### DateDisplayOrder: TDateDisplayOrder
125116
126117
127118**type** TDateDisplayOrder = (ddoDMY, ddoMDY, ddoYMD, ddoTryDefault);
128119
129120
130121Defines the order for displaying day, month and year part of the date. When ddoTryDefault is set, then the controls tries to determine the order from [ShortDateFormat global variable](http://lazarus-ccr.sourceforge.net/docs/rtl/sysutils/shortdateformat.html).
131122
132123This is similar to DateEdit's [DateOrder](http://lazarus-ccr.sourceforge.net/docs/lcl/editbtn/tdateedit.dateorder.html) property.
133124
134125#### DateSeparator: String
135126
136127
137128Defines the string used to separate date, month and year date parts. Setting this property automatically sets the UseDefaultSeparators property to False. To ensure that date and time separators are set to user's system defaults, set UseDefaultSeparators property to True.
138129
139130#### TimeSeparator: String
140131
141132
142133Defines the string used to separate hour, minute, second and millisecond time parts. Setting this property automatically sets the UseDefaultSeparators property to False. To ensure that date and time separators are set to user's system defaults, set UseDefaultSeparators property to True.
143134
144135#### UseDefaultSeparators: Boolean
145136
146137
147138When this property is set to True, then the DateSeparator and TimeSeparator properties will be set to [DateSeparator](http://lazarus-ccr.sourceforge.net/docs/rtl/sysutils/dateseparator.html) and [TimeSeparator](http://lazarus-ccr.sourceforge.net/docs/rtl/sysutils/timeseparator.html) global variables, which are set to user system defaults when application initializes.
148139
149140#### TrailingSeparator: Boolean
150141
151142
152143When set to True, then the DateSeparator is shown once more, after the last date part. This property exists because in some languages the correct format is 31. 1. 2010. including the last point, after the year.
153144
154145#### LeadingZeros: Boolean
155146
156147
157148Determines whether the date parts are displayed with or without leading zeros (this actually affects day, month and hour parts of date and time display).
158149
159150#### TimeDisplay: TTimeDisplay
160151
161152
162153**type** TTimeDisplay = (tdHM, tdHMS, tdHMSMs);
163154
164155
165156If Kind is dtkTime or dtkDateTime, then TimeDisplay value of tdHM means that only hours and minutes are displayed, tdHMS adds displaying of seconds and value of tdHMSMs means that milliseconds are displayed too.
166157
167158#### TimeFormat: TTimeFormat
168159
169160
170161**type** TTimeFormat = (tf12, tf24);
171162
172163
173164The value of tf12 sets the display of time to 12 hours format, with AM/PM string and tf24 sets to 24 hours format.
174165
175166#### TextForNullDate: String
176167
177168
178169Text which appears when the null date is set and control does not have focus. When control is focused, the text changes to defined format, but displaying zeros, which is appropriate to user input. User can set the date to NullDate by pressing N key, provided NullInputAllowed property is True.
179170
180171When TextForNullDate is set to empty string, zeros/nines format is displayed even when control does not have focus. If you want empty display, this can be achieved by setting TextForNullDate to one or more space characters.
181172
182173#### AutoAdvance: Boolean
183174
184175
185176When true, then when user is entering valid text, the selection automatically advances to next part of date/time. The default is True, because it makes user interaction easier and this behaviour is what a user should expect.
186177
187178#### Cascade: Boolean
188179
189180
190181When true, then when user is increasing or decreasing one date/time part (using up-down keys or mouse wheel), it can increase or decrease by one another date/time part. For example, when date is 31.08.2013. and user increases the day, the day becomes 1 and month increases by one and becomes 9, so the date becomes 01.09.2013. If Cascade were set to False, the month would not change and the date would become 01.08.2013.
191182
192183#### AutoButtonSize: Boolean
193184
194185
195186When true, the width of the arrow button (or up-down control, if it is shown instead) is automatically adjusted proportionally to the height.
196187
197188#### HideDateTimeParts: TDateTimeParts
198189
199190
200191**type**
201192
202193
203194
204195TDateTimePart = (dtpDay, dtpMonth, dtpYear, dtpHour, dtpMinute, dtpSecond, dtpMiliSec, dtpAMPM);
205196
206197
207198
208199TDateTimeParts = set of dtpDay..dtpMiliSec;
209200
210201
211202With HideDateTimeParts property, you can chose which date/time parts will not be shown. Most of the time you do not need to use this property and you can get the format you want by using other properties (see Kind, TimeDisplay). However, if you need more control (for example, you might want to let user edit only days, months and hours), you can additionally hide any date/time parts with this control. Keep in mind that, with this property, you cannot show any date/time part which is hidden by another property (for example, if TimeDisplay is tdHM, the second part is not shown, regardless of this property).
212203
213204#### CalendarWrapperClass: TCalendarControlWrapperClass (public)
214205
215206
216207When assigned, this property determines the type of the calendar control used for drop-down calendar. When set to nil, which is the default, the value of global variable DefaultCalendarWrapperClass is used. More details here.
217208
218209#### ShowMonthNames: Boolean
219210
220211
221212When this property is set to True, month names, set in MonthNames property, will be displayed instead of numbers.
222213
223214#### MonthNames: String
224215
225216
226217When ShowMonthNames is set to True, this property determines which month names should appear.
227218
228219If MonthNames is set to 'Short' or 'Long', then month names are set to [ShortMonthNames](http://www.freepascal.org/docs-html/rtl/sysutils/shortmonthnames.html) or [LongMonthNames](http://www.freepascal.org/docs-html/rtl/sysutils/longmonthnames.html) respectively.
229220
230221To set the month names explicitly, this property should be set to string which starts with a character which will be used to separate months and then twelve names separated by this character. For example ',I,II,III,IV,V,VI,VII,VIII,IX,X,XI,XII' — roman numbers are used for months — the first character is comma, which means that comma is used to separate the months. Another valid example ';jan;feb;mar;apr;maj;jun;jul;avg;sep;okt;nov;dec'.
231222
232223So, the separator should be the first character, before the first month name, and then only if there are twelve month names separated by that separator, the format is valid.
233224
234225The default value of this property is 'Long'.
235226
236227#### Options: TDateTimePickerOptions
237228
238229- dtpoDoChangeOnSetDateTime: the OnChange handler will be called also when DateTime is programatically changed.
239230- dtpoEnabledIfUnchecked: enable the date time picker if the checkbox is unchecked.
240231- dtpoAutoCheck: auto-check an unchecked checkbox when DateTime is changed (makes sense only if dtpoEnabledIfUnchecked is set).
241232- dtpoFlatButton: use flat button for calendar picker.
242233- dtpoResetSelection: when the control receives focus, the selection is always in the first part (the control does not remember which part was selected).
243234
244235### DateTimePicker Editor
245236
246-<figure>
247-<img src="datetimepickereditor.png" title="datetimepickereditor.png" />
248-<figcaption>datetimepickereditor.png</figcaption>
249-</figure>
237+![](/wiki-images/d/d5/Datetimepickereditor.png)
250238
251239
252240DateTimePicker Editor is a dialog which provides easy way to edit Date, Time, MinDate and MaxDate properties in design time. It is invoked when DateTimePicker control is double-clicked in form designer. It is also shown when the ellipsis (…) button shown in Date, Time, MinDate and MaxDate properties in Object inspector gets clicked.
253241
254242### User interaction in runtime
255243
256244
257245The goal was to provide same user interaction as native DateTimePicker from Windows. The keyboard input is restricted to valid date/time values only. Up and down buttons can be used too. The controls behave just like VCL's control.
258246
259247
260248After this behaviour is achieved it is further improved with mouse wheel interaction. Date and time parts can be edited using mouse wheel, which is very fast and comes handy.
261249
262250### Using some custom calendar control for drop-down
263251
264252Instead of LCL's TCalendar, some other calendar control can be used for drop-down. This calendar control has to provide a way to determine if the coordinates (within the calendar control) are on the date or not (see AreCoordinatesOnDate function). DateTimePicker needs it to decide if it should close the drop-down calendar and take its date when the calendar gets clicked (see AreCoordinatesOnDate function). The calendar only needs to be derived from TControl. The mouse interaction with calendar will work and, if it is also TWinControl's descendant, the keyboard interaction will also work.
265253
266254Now, let's see how to use some calendar control for drop-down control. First, we need to define the "wrapper" class, then we will have to tell the DateTimePicker control to use this wrapper instead of default one.
267255
268256#### Defining the wrapper class
269257
270258
271259In unit calendarcontrolwrapper.pas, there is an abstract class TCalendarControlWrapper. We need to derive a new class from this abstract class. There are four abstract methods which new class has to override - GetCalendarControlClass, SetDate, GetDate and AreCoordinatesOnDate.
272260
273261This should be pretty simple, please see the file lclcalendarwrapper.pas, where TLCLCalendarWrapper (the default wrapper) is defined.
274262
275263##### GetCalendarControlClass
276264
277265:
278266
279267``` pascal
280268class function GetCalendarControlClass: TControlClass; virtual abstract;
281269```
282270
283271
284272This class function should return the class of the wrapped calendar control.
285273
286274##### SetDate
287275
288276:
289277
290278``` pascal
291279procedure SetDate(Date: TDate); virtual abstract;
292280```
293281
294282
295283Should be overridden to set the date in the calendar control.
296284
297285##### GetDate
298286
299287:
300288
301289``` pascal
302290function GetDate: TDate; virtual abstract;
303291```
304292
305293
306294Should be overridden to get the date from the calendar control.
307295
308296##### AreCoordinatesOnDate
309297
310298:
311299
312300``` pascal
313301function AreCoordinatesOnDate(X, Y: Integer): Boolean; virtual abstract;
314302```
315303
316304
317305This function should return True if coordinates (X, Y) are on the date in the calendar control (DateTimePicker calls this function when the calendar is clicked, to determine whether the drop-down calendar should return the date or not). The calendar control must at least provide a way to determine whether the coordinates are on the date (when this control gets clicked, we must decide if the date has just been chosen — then we should respond by closing the drop-down form and setting the date from calendar to DateTimePicker — for example in LCL's TCalendar we will respond when the calendar is clicked on date, but not when the user clicks in title area changing months or years, then we let the user keep browsing the calendar).
318306
319307#### Telling to the DateTimePicker to use new wrapper
320308
321309
322310Now, when we have the wrapper class defined, the easiest way to make all DateTimePickers use the new control is setting global variable DefaultCalendarWrapperClass (declared in unit datetimepicker.pas) and all DateTimePickers in the project will use the new control.
323311
324312
325313There is public property CalendarWrapperClass in DateTimePicker. We can set it and DateTimePicker will use it.
326314
327315
328316This pseudo code shows how a DateTimePicker decides which calendar control to use:
329317
330318```text
331319if property DateTimePicker.CalendarWrapperClass is not nil
332320 the property is used
333321else if global variable DefaultCalendarWrapperClass is not nil
334322 the global variable is used
335323else
336324 LCL's TCalendar (implemented through TLCLCalendarWrapper class) is used
337325```
338326
339327## TDBDateTimePicker ![](/wiki-images/3/34/TDBDateTimePicker.png)
340328
341329
342330TDBDateTimePicker is a data-aware version of TDateTimePicker, with nice way of handling null database values.
343331
344332### Handling of null values
345333
346334#### Displaying null values
347335
348336
349337When the underlying DB field has null value, then:
350338
351339
352340
353341If the control is not focused, then it displays the text defined in TextForNullDate property. The default is "NULL".
354342
355343
356344
357345When the control gets focus, the text changes to defined format, but displaying zeros for date parts and nines for time parts (for example "00/00/0000 99:99:99"), which is appropriate to user input.
358346
359347#### Setting the field value to null
360348
361349
362350
363351If NullInputAllowed property is True, the user can set the date and time to null, by pressing N key.
364352
365353---
366354*From the Free Pascal wiki, page "DateTimeCtrls Package", as it stood on 2022-01-26 after a change by Zoran, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
367355Category: Components
368356Category: Lazarus

Back to history