diff --git a/README.md b/README.md
index 05f63775a..e52ada8fe 100644
--- a/README.md
+++ b/README.md
@@ -128,6 +128,7 @@ Validator | Description
**isJWT(str)** | check if the string is valid JWT token.
**isLatLong(str)** | check if the string is a valid latitude-longitude coordinate in the format `lat,long` or `lat, long`.
**isLength(str [, options])** | check if the string's length falls in a range.
`options` is an object which defaults to `{min:0, max: undefined}`. Note: this function takes into account surrogate pairs.
+**isLocale(str)** | check if the string is a locale
**isLowercase(str)** | check if the string is lowercase.
**isMACAddress(str)** | check if the string is a MAC address.
`options` is an object which defaults to `{no_colons: false}`. If `no_colons` is true, the validator will allow MAC addresses without the colons. Also, it allows the use of hyphens or spaces e.g '01 02 03 04 05 ab' or '01-02-03-04-05-ab'.
**isMagnetURI(str)** | check if the string is a [magnet uri format](https://en.wikipedia.org/wiki/Magnet_URI_scheme).
diff --git a/src/index.js b/src/index.js
index 4ab3aaf62..ac8244589 100644
--- a/src/index.js
+++ b/src/index.js
@@ -14,6 +14,7 @@ import isIPRange from './lib/isIPRange';
import isFQDN from './lib/isFQDN';
import isBoolean from './lib/isBoolean';
+import isLocale from './lib/isLocale';
import isAlpha, { locales as isAlphaLocales } from './lib/isAlpha';
import isAlphanumeric, { locales as isAlphanumericLocales } from './lib/isAlphanumeric';
@@ -157,6 +158,7 @@ const validator = {
isJSON,
isEmpty,
isLength,
+ isLocale,
isByteLength,
isUUID,
isMongoId,
diff --git a/src/lib/isLocale.js b/src/lib/isLocale.js
new file mode 100644
index 000000000..ab66e5c59
--- /dev/null
+++ b/src/lib/isLocale.js
@@ -0,0 +1,11 @@
+import assertString from './util/assertString';
+
+const localeReg = /^[A-z]{2,4}([_-]([A-z]{4}|[\d]{3}))?([_-]([A-z]{2}|[\d]{3}))?$/;
+
+export default function isLocale(str) {
+ assertString(str);
+ if (str === 'en_US_POSIX' || str === 'ca_ES_VALENCIA') {
+ return true;
+ }
+ return localeReg.test(str);
+}
diff --git a/test/validators.js b/test/validators.js
index a1b01cea3..acab8734a 100644
--- a/test/validators.js
+++ b/test/validators.js
@@ -2939,6 +2939,27 @@ describe('Validators', () => {
});
});
+ it('should validate isLocale codes', () => {
+ test({
+ validator: 'isLocale',
+ valid: [
+ 'uz_Latn_UZ',
+ 'en',
+ 'gsw',
+ 'es_ES',
+ 'sw_KE',
+ 'am_ET',
+ 'ca_ES_VALENCIA',
+ 'en_US_POSIX',
+ ],
+ invalid: [
+ 'lo_POP',
+ '12',
+ '12_DD',
+ ],
+ });
+ });
+
it('should validate strings by byte length (deprecated api)', () => {
test({
validator: 'isByteLength',