parser xml FEATURE validate eventTime value
diff --git a/src/parser_xml.c b/src/parser_xml.c
index 5e9d5c3..b76c929 100644
--- a/src/parser_xml.c
+++ b/src/parser_xml.c
@@ -29,6 +29,8 @@
 #include "parser_data.h"
 #include "parser_internal.h"
 #include "plugins_exts.h"
+#include "plugins_internal.h"
+#include "schema_compile_node.h"
 #include "set.h"
 #include "tree.h"
 #include "tree_data.h"
@@ -1016,6 +1018,54 @@
 }
 
 /**
+ * @brief Validate eventTime date-and-time value.
+ *
+ * @param[in] node Opaque eventTime node.
+ * @return LY_SUCCESS on success.
+ * @return LY_ERR value on error.
+ */
+static LY_ERR
+lydxml_env_netconf_eventtime_validate(const struct lyd_node *node)
+{
+    LY_ERR rc = LY_SUCCESS;
+    struct ly_ctx *ctx = (struct ly_ctx *)LYD_CTX(node);
+    struct lysc_ctx cctx = {.ctx = ctx};
+    const struct lys_module *mod;
+    LY_ARRAY_COUNT_TYPE u;
+    struct ly_err_item *err = NULL;
+    struct lysp_type *type_p;
+    struct lysc_pattern **patterns = NULL;
+    const char *value;
+
+    /* get date-and-time parsed type */
+    mod = ly_ctx_get_module_latest(ctx, "ietf-yang-types");
+    LY_ARRAY_FOR(mod->parsed->typedefs, u) {
+        if (!strcmp(mod->parsed->typedefs[u].name, "date-and-time")) {
+            type_p = &mod->parsed->typedefs[u].type;
+            break;
+        }
+    }
+    assert(type_p);
+
+    /* compile patterns */
+    assert(type_p->patterns);
+    LY_CHECK_GOTO(rc = lys_compile_type_patterns(&cctx, type_p->patterns, NULL, &patterns), cleanup);
+
+    /* validate */
+    value = lyd_get_value(node);
+    rc = lyplg_type_validate_patterns(patterns, value, strlen(value), &err);
+
+cleanup:
+    FREE_ARRAY(ctx, patterns, lysc_pattern_free);
+    if (rc && err) {
+        LOGVAL_ERRITEM(ctx, err);
+        ly_err_free(err);
+        LOGVAL(ctx, LYVE_DATA, "Invalid \"eventTime\" in the notification.");
+    }
+    return rc;
+}
+
+/**
  * @brief Parse all expected non-data XML elements of a NETCONF notification message.
  *
  * @param[in] xmlctx XML parser context.
@@ -1056,7 +1106,8 @@
     lyd_insert_node(*envp, NULL, child, 0);
 
     /* validate value */
-    /* TODO validate child->value as yang:date-and-time */
+    r = lydxml_env_netconf_eventtime_validate(child);
+    LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
 
     /* finish child parsing */
     if (xmlctx->status != LYXML_ELEM_CLOSE) {
diff --git a/src/schema_compile_node.c b/src/schema_compile_node.c
index 46a6f8d..47c3825 100644
--- a/src/schema_compile_node.c
+++ b/src/schema_compile_node.c
@@ -1246,16 +1246,7 @@
 #undef URANGE_LEN
 }
 
-/**
- * @brief Compile parsed pattern restriction in conjunction with the patterns from base type.
- * @param[in] ctx Compile context.
- * @param[in] patterns_p Array of parsed patterns from the current type to compile.
- * @param[in] base_patterns Compiled patterns from the type from which the current type is derived.
- * Patterns from the base type are inherited to have all the patterns that have to match at one place.
- * @param[out] patterns Pointer to the storage for the patterns of the current type.
- * @return LY_ERR LY_SUCCESS, LY_EMEM, LY_EVALID.
- */
-static LY_ERR
+LY_ERR
 lys_compile_type_patterns(struct lysc_ctx *ctx, struct lysp_restr *patterns_p,
         struct lysc_pattern **base_patterns, struct lysc_pattern ***patterns)
 {
diff --git a/src/schema_compile_node.h b/src/schema_compile_node.h
index 7933b82..7a57da5 100644
--- a/src/schema_compile_node.h
+++ b/src/schema_compile_node.h
@@ -55,6 +55,18 @@
 LY_ERR lys_compile_type_pattern_check(struct ly_ctx *ctx, const char *pattern, pcre2_code **code);
 
 /**
+ * @brief Compile parsed pattern restriction in conjunction with the patterns from base type.
+ * @param[in] ctx Compile context.
+ * @param[in] patterns_p Array of parsed patterns from the current type to compile.
+ * @param[in] base_patterns Compiled patterns from the type from which the current type is derived.
+ * Patterns from the base type are inherited to have all the patterns that have to match at one place.
+ * @param[out] patterns Pointer to the storage for the patterns of the current type.
+ * @return LY_ERR LY_SUCCESS, LY_EMEM, LY_EVALID.
+ */
+LY_ERR lys_compile_type_patterns(struct lysc_ctx *ctx, struct lysp_restr *patterns_p,
+        struct lysc_pattern **base_patterns, struct lysc_pattern ***patterns);
+
+/**
  * @brief Compile information about the leaf/leaf-list's type.
  *
  * @param[in] ctx Compile context.
diff --git a/src/tree_schema_free.c b/src/tree_schema_free.c
index 07f32cb..c6fa656 100644
--- a/src/tree_schema_free.c
+++ b/src/tree_schema_free.c
@@ -715,7 +715,7 @@
     FREE_ARRAY(ctx, range->exts, lysc_ext_instance_free);
 }
 
-static void
+void
 lysc_pattern_free(struct ly_ctx *ctx, struct lysc_pattern **pattern)
 {
     if (--(*pattern)->refcount) {
diff --git a/src/tree_schema_internal.h b/src/tree_schema_internal.h
index a62f273..9fe27cd 100644
--- a/src/tree_schema_internal.h
+++ b/src/tree_schema_internal.h
@@ -694,6 +694,14 @@
 void lysp_node_free(struct ly_ctx *ctx, struct lysp_node *node);
 
 /**
+ * @brief Free a compiled pattern.
+ *
+ * @param[in] ctx libyang context.
+ * @param[in] pattern Pointer to the pattern to free.
+ */
+void lysc_pattern_free(struct ly_ctx *ctx, struct lysc_pattern **pattern);
+
+/**
  * @brief Free a bit/enum item.
  *
  * @param[in] ctx libyang context.