Create Effective Date of Birth Form
This article outlines best practices for creating a properly-localized date of birth (DOB) form to make the application more inclusive and accessible. ##
Key challenges
Collecting dates of birth from international users can present several challenges, including differences in date format, language barriers, and cultural differences in how dates are expressed.
Despite these challenges, it is necessary to normalize dates into a standard format for use in a global system like, which accepts only dates of birth that are in ISO 8601 format (YYYY-MM-DD) for consistency and accuracy.
Best practices
Consider these best practices for capturing and translating user dates of birth into ISO 8601 format:
-
Identify the user's location through their IP address, language preferences, or other means, and differentiate between locales such as
en-USanden-GB. Knowing the user's location and language can help to validate their date of birth accurately by applying country-specific date validation rules and providing localized date format options. -
Present a DOB input field with a localized format hint for that locale. For example:
- For US and Canada: YYYY-MM-DD
- For Europe: DD/MM/YYYY
- For China: YYYY-MM-DD
-
When the user submits the DOB form, do the following:
-
Use a locale-specific date parser to parse the input date. For example:
- In Java, use the
DateTimeFormatterclass to parse and format date and time values. Use aLocaleobject to specify the language and cultural norms to be used in formatting and parsing. - In JavaScript, use the
Intl.DateTimeFormatobject to create a formatter for displaying dates and times according to the locale and options specified.
- In Java, use the
-
Capture the date, month, and year components from the parsed data.
-
Reassemble these components in the ISO 8601 format when passing the DOB to the RiskOS™ endpoint.
The following script can be used to assist in this process:
import re from datetime import datetimedef convert_date(date_string): # Define a dictionary to map each date format to a regular expression date_regexes = { "YYYY-MM-DD": r"^\d{4}-\d{2}-\d{2}$", # ISO 8601 standard, used in China, Japan, Korea, Hungary, Sweden, etc. "MM/DD/YYYY": r"^\d{2}/\d{2}/\d{4}$", # Used in the United States and English Canada "DD/MM/YYYY": r"^\d{2}/\d{2}/\d{4}$", # Used in the United Kingdom, Ireland, Australia, New Zealand, India, etc. "YY-MM-DD": r"^\d{2}-\d{2}-\d{2}$", # Used in Taiwan, Hong Kong, Macau. "DD-MM-YY": r"^\d{2}-\d{2}-\d{2}$", # Used in Egypt, Malaysia, Singapore, South Africa, etc. "MM-DD-YY": r"^\d{2}-\d{2}-\d{2}$", # Used in the Philippines, Saudi Arabia. "YYYY/MM/DD": r"^\d{4}/\d{2}/\d{2}$", # Used in Iran, Iraq. "YYYY.MM.DD": r"^\d{4}\.\d{2}\.\d{2}$", # Used in Indonesia, Mongolia, Malaysia, Singapore, South Korea, etc. "DD.MM.YYYY": r"^\d{2}\.\d{2}\.\d{4}$", # Used in Bosnia and Herzegovina, Croatia, Lithuania, Serbia, Slovakia, etc. "YY/MM/DD": r"^\d{2}/\d{2}/\d{2}$", # Used in Vietnam, Cambodia. "DD/MM": r"^\d{2}/\d{2}$", # Used in the Netherlands, Lithuania, Portugal, Brazil, etc. "MM-DD": r"^\d{2}-\d{2}$", # Used in the United States (primarily in business/government). "YYYYMMDD": r"^\d{8}$", # Used in China, Hong Kong, Taiwan, Japan, Korea. "DDMMYYYY": r"^\d{2}\d{2}\d{4}$", # Used in Australia, New Zealand, and the United Kingdom "MMM DD, YYYY": r"^[A-Za-z]{3} \d{1,2}, \d{4}$", # E.g. Jan 30, 2020 - Used in the United States and English Canada. "DD MMM YYYY": r"^\d{1,2} [A-Za-z]{3} \d{4}$", # E.g. 30 Jan 2020 - Used in India, Pakistan, Malaysia, Singapore. "YYYY년 M월 D일": r"^\\d{4}년 \\d{1,2}월 \\d{1,2}일$", # Used in North and South Korea. "D MMM YYYY": r"^\\d{1,2} \[A-Za-z\]{3} \\d{4}$", # Used in Singapore, Malaysia, Brunei. "DD/MMM/YY": r"^\\d{2}/\[A-Za-z\]{3}/\\d{2}$", # Used in Kenya, Tanzania, Rwanda, Uganda, Zambia. "YYYY'년' MM'월' DD'일'": r"^\\d{4}년 \\d{2}월 \\d{2}일$", # Used in South Korea. "DD. MMMM YYYY.": r"^\\d{1,2}\\. \[a-zšđćčž\]{4,} \\d{4}\\.$", #Used in Croatia, Bosnia, Serbia. "DD.MM.YYYY.": r"^\\d{2}\\.\\d{2}\\.\\d{4}\\.$", # Used in Russia, Bulgaria, Ukraine, Macedonia. "YYYY.M.D.": r"^\\d{4}\\.\\d{1,2}\\.\\d{1,2}$", # Used in China, Japan, Korea, Taiwan, Hong Kong. "YYYY-M-D": r"^\\d{4}-\\d{1,2}-\\d{1,2}$", # Used in China, Japan, Korea, Taiwan, Hong Kong. "YYYYMMDD日": r"^\\d{8}日$", # Used in Japan. } # Iterate over the dictionary of regexes for date_format, date_regex in date_regexes.items(): # Check if the date string matches the regular expression for the current date format if re.match(date_regex, date_string): # If it does, convert the date string to a datetime object using the corresponding format string return datetime.strptime(date_string, date_format)# If the date string doesn't match any of the regular expressions, raise a ValueError raise ValueError(f"Unrecognized date format: {date_string}") print(convert_date("01/02/2020")) # 2020-01-02 print(convert_date("02-01-2020")) # 2020-01-02 print(convert_date("2020年1月2日")) # 2020-01-02 -
-
Gracefully handle invalid dates or dates with missing components by displaying an appropriate error message requesting a valid date of birth in the proper format for that locale.
You can use the following regex to determine when an exception needs to be displayed:
^([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])([Zz]| [+-][0-9]{2}:[0-9]{2})?$
Updated 3 months ago
