diff --git a/src/Umbraco.Infrastructure/PropertyEditors/DateTimePropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/DateTimePropertyEditor.cs
index 3c1e7cd683..50d06b725b 100644
--- a/src/Umbraco.Infrastructure/PropertyEditors/DateTimePropertyEditor.cs
+++ b/src/Umbraco.Infrastructure/PropertyEditors/DateTimePropertyEditor.cs
@@ -1,8 +1,16 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
+using System.Data.SqlTypes;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Core.Models;
+using Umbraco.Cms.Core.Models.Editors;
using Umbraco.Cms.Core.PropertyEditors.Validators;
+using Umbraco.Cms.Core.Serialization;
+using Umbraco.Cms.Core.Strings;
+using Umbraco.Extensions;
namespace Umbraco.Cms.Core.PropertyEditors;
@@ -25,8 +33,91 @@ public class DateTimePropertyEditor : DataEditor
///
protected override IDataValueEditor CreateValueEditor()
{
- IDataValueEditor editor = base.CreateValueEditor();
+ DateTimePropertyValueEditor editor = DataValueEditorFactory.Create(Attribute!);
editor.Validators.Add(new DateTimeValidator());
return editor;
}
+
+ ///
+ /// Provides a value editor for the datetime property editor.
+ ///
+ internal sealed class DateTimePropertyValueEditor : DataValueEditor
+ {
+ ///
+ /// The key used to retrieve the date format from the data type configuration.
+ ///
+ internal const string DateTypeConfigurationFormatKey = "format";
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public DateTimePropertyValueEditor(
+ IShortStringHelper shortStringHelper,
+ IJsonSerializer jsonSerializer,
+ IIOHelper ioHelper,
+ DataEditorAttribute attribute)
+ : base(shortStringHelper, jsonSerializer, ioHelper, attribute)
+ {
+ }
+
+ ///
+ public override object? FromEditor(ContentPropertyData editorValue, object? currentValue)
+ {
+ if (editorValue.Value is null)
+ {
+ return base.FromEditor(editorValue, currentValue);
+ }
+
+ if (TryGetConfiguredDateTimeFormat(editorValue, out string? format) is false)
+ {
+ return base.FromEditor(editorValue, currentValue);
+ }
+
+ if (IsTimeOnlyFormat(format) is false)
+ {
+ return base.FromEditor(editorValue, currentValue);
+ }
+
+ // We have a time-only format, so we need to ensure the date part is valid for SQL Server, so we can persist
+ // without error.
+ // If we have a date part that is less than the minimum date, we need to adjust it to be the minimum date.
+ Attempt