* Validate and convert date

For plugin authors to discuss plugin programming
Post Reply
avatar
jelv
Megastar
Posts: 649
Joined: 03 Feb 2020 22:57
Family Historian: V7
Location: Mere, Wiltshire

Validate and convert date

Post by jelv »

On a form I have a text box in to which a date of birth is supposed to be entered.

I'd like it if the DOB could be entered in any of the ways FH recognises, validated as being a simple date (I'd also be checking if it was within the FH calculated EarliestBirth and LatestBirth range) and if so update the text box with the formatted in the FH standard (d mmm yyyy).

Could I have some pointers on how to go about this please?

Edit: also to take account of locale so it knows whether 10/03/2024 is March or October.
John Elvin
User avatar
tatewise
Megastar
Posts: 28498
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: Validate and convert date

Post by tatewise »

To manipulate FH pointers you use fhNewItemPtr() and the Item Pointer object Methods.
To manipulate FH dates you use fhNewDate() and the Date object Methods.
You may also need to use fhNewDatePt() and the Date Point object Methods.
Those are all covered by the How to Write Plugins help Function Index and Objects.
e.g.
dtDate = fhNewDate()
bResult = dtDate:SetValueAsText( strText, True )
strType = dtDate:GetType()
where:
strText is the text string entered by the user.
strType will be "Simple" for a single date.

strText = dtDate:GetDisplayText( strFormat )
will display the date as text in the chosen format such as "Compact" for dd Mmm yyyy.

Dealing with locale is rather more complex.
One method is ask user to set Tools > Preferences > General > Preferred Short Date Format: mm/dd/yyyy
Otherwise, I think it involves dabbling with the Windows Registry!
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry
User avatar
tatewise
Megastar
Posts: 28498
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: Validate and convert date

Post by tatewise »

Note that the EstimatedBirthDate function returns a Date Point value and not a Date value.
local dtpMin = fhCallBuiltInFunction( "EstimatedBirthDate", ptrIndi, "EARLIEST", 5 )

So you must use dtDate:GetDatePt1() to be able to compare with dtpMin.
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry
User avatar
Mark1834
Megastar
Posts: 2538
Joined: 27 Oct 2017 19:33
Family Historian: V7
Location: South Cheshire, UK

Re: Validate and convert date

Post by Mark1834 »

tatewise wrote: 13 Apr 2024 17:56 Otherwise, I think it involves dabbling with the Windows Registry!
Which must be read-only for published plugins of course, not changing a system setting, even temporarily…
Mark Draper
User avatar
tatewise
Megastar
Posts: 28498
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: Validate and convert date

Post by tatewise »

Mark, that is NOT entirely what Privacy and Security Standards for Published Plugins says!

That would allow the PC locale settings to be read from the Windows Registry, and then the Preferences Date setting to be changed (temporarily) in the Windows Registry as it would be "essential to the stated plugin function" of handling dates in accordance with the locale.
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry
User avatar
Mark1834
Megastar
Posts: 2538
Joined: 27 Oct 2017 19:33
Family Historian: V7
Location: South Cheshire, UK

Re: Validate and convert date

Post by Mark1834 »

I’m not clear why a user would want or need to do that. I read John’s PS as simply being that the plugin is aware of the user’s date preference, so it understands how to interpret a numerical date format.

That comes from reading the relevant Registry key, but why should the plugin need to change it? If the user is in the US (say) but has set FH to use European date format, are you suggesting that the plugin should overrule that preference and force it to the system locale?

It’s John’s plugin, so it’s his call on how it works of course. What is off-limits is changing the system locale.
Mark Draper
avatar
jelv
Megastar
Posts: 649
Joined: 03 Feb 2020 22:57
Family Historian: V7
Location: Mere, Wiltshire

Re: Validate and convert date

Post by jelv »

Either I've not interpreted what you said correctly, or FH isn't doing what it should.
DateValidation.png
DateValidation.png (30.76 KiB) Viewed 413 times
John Elvin
avatar
jelv
Megastar
Posts: 649
Joined: 03 Feb 2020 22:57
Family Historian: V7
Location: Mere, Wiltshire

Re: Validate and convert date

Post by jelv »

It's also saying "Jan 2020" and "2020" are valid so I'll need to use GetDisplayText to check that DAY and MONTH_NUMBER are not blank.

I've tried entering valid dates in all sorts of formats and it seems to be doing the interpretation correctly.

The one odd one I've found is "04/25/2024" which gets returned as "4 2024" (i.e. no month), but I'd pick that up.

Edit: It doesn't like 2024/03/15 which I would have hoped it might like as that is unambiguous.
John Elvin
User avatar
Mark1834
Megastar
Posts: 2538
Joined: 27 Oct 2017 19:33
Family Historian: V7
Location: South Cheshire, UK

Re: Validate and convert date

Post by Mark1834 »

John - I've been experimenting as well, and how FH interprets numeric date formats seems to be determined by the preferred Short Date Format in the Preferences menu.

I copied your function, and was puzzled that it was returning false for today entered as either '13/3/2024' or '13.3.2024'. However, my preferred Short Date Format is yyyy-mm-dd, and if I enter today as any of 2024-4-13, 2024-04-13, 2024.4.13, or 2024.04.13, they all return the correct date in standard form.

The Date Entry Assistant in the main UI shows the same behaviour - it does not recognise 13/4/2024 as a valid date for me, but does recognise 2024/4/13.

You don't need to read this setting to interpret what is entered, as FH just gets on with using it anyway, but it might be a useful prompt for the user to display the expected format in the UI. It's a user-level setting at Computer\HKEY_CURRENT_USER\SOFTWARE\Calico Pie\Family Historian\2.0\Preferences.

TBH, I'd forgotten what my setting was when I replied to Mike, as I rarely use numeric dates, but I think it's actually a good illustration of the point I was making. IMO, the plugin should use my preferred format rather than force me to the standard locale setting of dd/mm/yyyy.
Mark Draper
avatar
jelv
Megastar
Posts: 649
Joined: 03 Feb 2020 22:57
Family Historian: V7
Location: Mere, Wiltshire

Re: Validate and convert date

Post by jelv »

jelv wrote: 13 Apr 2024 21:38 The one odd one I've found is "04/25/2024" which gets returned as "4 2024" (i.e. no month), but I'd pick that up.
Checking further using dtDate:GetDisplayText('MONTH_NUMBER') it returns 25.

It appears that all SetValueAsText does is identify the parts of the date without doing any validation that month is 1-12 and day is valid for the month.
John Elvin
User avatar
tatewise
Megastar
Posts: 28498
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: Validate and convert date

Post by tatewise »

Mark, it was HKCU\SOFTWARE\Calico Pie\Family Historian\2.0\Preferences\ that I thought might need adjusting to match the PC locale date format read from the Windows Registry. Your suggestion of reminding the user of the expected short date format is probably better.

John, yes, it is odd that SetValueAsText(...) does not complain about invalid days or months.
Via the FH UI Date entry it does complain about the 25 and offers various options.

You could use dpDatePt = dtDate:GetDatePt1() and then it is easier to extract and check day, month & year, because they are returned as integers, whereas GetDisplayText( "..." ) returns text which must be converted to an integer before checking its validity.

Also, investigate GetDataWarning(...) which can only be used after setting a fact Date field.
However, it does perform the same validation that applies when a user enters a Date field.
It must be called via fnValue = fhCallBuiltInFunction("GetDataWarning",...)
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry
avatar
jelv
Megastar
Posts: 649
Joined: 03 Feb 2020 22:57
Family Historian: V7
Location: Mere, Wiltshire

Re: Validate and convert date

Post by jelv »

From testing I don't think I need to go near the registry.

I believe dtDate:SetValueAsText(strDate, false) is recognising dates in the order specified by preference Preferred Short Date Format and dtDate:GetDisplayText('COMPACT') takes account of the Preferred Standard Date Format.

GetDataWarning(...) is no use as I want to do the validation of the data entered on my dialog way before I go anywhere near modifying/adding dates to the file.

This is what I've ended up with:

Code: Select all

	function ValidateDate(strDate)		-- Returns true/false, date formated to FH preferred short date format
										-- and a date object if valid
		local dtDate = fhNewDate()
		if not dtDate:SetValueAsText(strDate, false) then
			return false
		end
		local strType = dtDate:GetType()
		if strType ~= 'Simple' then
			return false
		end
		local Day = tonumber(dtDate:GetDisplayText('DAY'))
		local Month = tonumber(dtDate:GetDisplayText('MONTH_NUMBER'))
		local Year = tonumber(dtDate:GetDisplayText('YEAR'))
		if Day == 0 or Month == 0 or Month > 12 then
			return false
		end

		local DaysInMonth = {31,29,31,30,31,30,31,31,30,31,30,31}
		if Day > DaysInMonth[Month] then
			return false
		end
		if Month ==2 and Day == 29 then
			if Year%4 ~= 0 then
				return false
			end
			if Year%100 == 0 and Year%400 ~=0 then
				return false
			end
		end

		local FmtDate = dtDate:GetDisplayText('COMPACT')
		return true, FmtDate, dtDate
	end
The date can be entered in many different ways and it will return it the standard way it would be displayed when a date is entered in the property box.
Last edited by jelv on 14 Apr 2024 13:53, edited 1 time in total.
John Elvin
User avatar
Mark1834
Megastar
Posts: 2538
Joined: 27 Oct 2017 19:33
Family Historian: V7
Location: South Cheshire, UK

Re: Validate and convert date

Post by Mark1834 »

Agree - you only need to read the Registry if you want to remind users what their setting is. None of the main app forms do that (not even the Date Entry Assistant), so it would be the plugin leading the way if you included it :).
Mark Draper
User avatar
tatewise
Megastar
Posts: 28498
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: Validate and convert date

Post by tatewise »

John, it is a bit more efficient to use the following to get day, month & year as integers.

Code: Select all

local dpDatePt = dtDate:GetDatePt1()
local Day   = dpDatePt:GetDay()
local Month = dpDatePt:GetMonth()
local Year  = dpDatePt:GetYear()
Once you have added the Date to a Fact it may be a good idea to use GetDataWarning(...) to provide users with the same warnings that they would get if adding the Date to the Fact themselves directly via FH.

Remember, that the Windows Registry discussion was prompted by your OP request to take account of locale so it knows whether 10/03/2024 is March or October. That requirement seems to have dwindled away.
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry
avatar
jelv
Megastar
Posts: 649
Joined: 03 Feb 2020 22:57
Family Historian: V7
Location: Mere, Wiltshire

Re: Validate and convert date

Post by jelv »

The thing about the locale vanished when I realised that the FH Preferred Short Date Format should take care of that - it responds the same way as the entry of dates in the main FH program. I would hope that people have the FH short date format set to the same as the Windows short date format; if they haven't they'd be experiencing more issues than any plugin.
John Elvin
User avatar
Mark1834
Megastar
Posts: 2538
Joined: 27 Oct 2017 19:33
Family Historian: V7
Location: South Cheshire, UK

Re: Validate and convert date

Post by Mark1834 »

Does FH take any notice of the Windows locale setting and date format? It seems to be the app date format options that drive how entered and reported dates are presented.

My FH and Windows short date formats are different (yyyy-m-d and dd-mm-yyyy, respectively), with no issues that I’ve noticed.
Mark Draper
User avatar
tatewise
Megastar
Posts: 28498
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: Validate and convert date

Post by tatewise »

An issue was discussed recently with regard to AS that has a SYSTEM.DATE option which is based on the PC locale format and may get mishandled when entered into FH source templates where the Short Date Format is different.
See Casting template data as a particular data-type (22911).
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry
User avatar
Mark1834
Megastar
Posts: 2538
Joined: 27 Oct 2017 19:33
Family Historian: V7
Location: South Cheshire, UK

Re: Validate and convert date

Post by Mark1834 »

I’d forgotten that one. It doesn’t impact me as I don’t use AS, but that problem of mangling text-based dates on transfer has been around forever.

I generally avoid numerical dates for anything other than trivial applications, as I spent most of my former professional life in global teams that had three different ways of writing them (ymd in Asia, mdy in USA, and dmy virtually everywhere else)!
Mark Draper
Post Reply