* Validate and convert date
Validate and convert date
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.
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
- tatewise
- Megastar
- Posts: 28953
- Joined: 25 May 2010 11:00
- Family Historian: V7
- Location: Torbay, Devon, UK
- Contact:
Re: Validate and convert date
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!
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
- tatewise
- Megastar
- Posts: 28953
- Joined: 25 May 2010 11:00
- Family Historian: V7
- Location: Torbay, Devon, UK
- Contact:
Re: Validate and convert date
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.
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
- Mark1834
- Megastar
- Posts: 2653
- Joined: 27 Oct 2017 19:33
- Family Historian: V7
- Location: South Cheshire, UK
Re: Validate and convert date
Which must be read-only for published plugins of course, not changing a system setting, even temporarily…
Mark Draper
- tatewise
- Megastar
- Posts: 28953
- Joined: 25 May 2010 11:00
- Family Historian: V7
- Location: Torbay, Devon, UK
- Contact:
Re: Validate and convert date
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.
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
- Mark1834
- Megastar
- Posts: 2653
- Joined: 27 Oct 2017 19:33
- Family Historian: V7
- Location: South Cheshire, UK
Re: Validate and convert date
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.
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
Re: Validate and convert date
Either I've not interpreted what you said correctly, or FH isn't doing what it should.
John Elvin
Re: Validate and convert date
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.
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
- Mark1834
- Megastar
- Posts: 2653
- Joined: 27 Oct 2017 19:33
- Family Historian: V7
- Location: South Cheshire, UK
Re: Validate and convert date
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.
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
Re: Validate and convert date
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
- tatewise
- Megastar
- Posts: 28953
- Joined: 25 May 2010 11:00
- Family Historian: V7
- Location: Torbay, Devon, UK
- Contact:
Re: Validate and convert date
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",...)
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
Re: Validate and convert date
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:
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.
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
Last edited by jelv on 14 Apr 2024 13:53, edited 1 time in total.
John Elvin
- Mark1834
- Megastar
- Posts: 2653
- Joined: 27 Oct 2017 19:33
- Family Historian: V7
- Location: South Cheshire, UK
Re: Validate and convert date
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
- tatewise
- Megastar
- Posts: 28953
- Joined: 25 May 2010 11:00
- Family Historian: V7
- Location: Torbay, Devon, UK
- Contact:
Re: Validate and convert date
John, it is a bit more efficient to use the following to get day, month & year as integers.
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.
Code: Select all
local dpDatePt = dtDate:GetDatePt1()
local Day = dpDatePt:GetDay()
local Month = dpDatePt:GetMonth()
local Year = dpDatePt:GetYear()
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
Re: Validate and convert date
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
- Mark1834
- Megastar
- Posts: 2653
- Joined: 27 Oct 2017 19:33
- Family Historian: V7
- Location: South Cheshire, UK
Re: Validate and convert date
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.
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
- tatewise
- Megastar
- Posts: 28953
- Joined: 25 May 2010 11:00
- Family Historian: V7
- Location: Torbay, Devon, UK
- Contact:
Re: Validate and convert date
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).
See Casting template data as a particular data-type (22911).
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry
- Mark1834
- Megastar
- Posts: 2653
- Joined: 27 Oct 2017 19:33
- Family Historian: V7
- Location: South Cheshire, UK
Re: Validate and convert date
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)!
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