diff --git a/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlDbFunctionsExtensions.cs b/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlDbFunctionsExtensions.cs
index 9488c8ec8..15cf1ae2f 100644
--- a/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlDbFunctionsExtensions.cs
+++ b/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlDbFunctionsExtensions.cs
@@ -141,4 +141,24 @@ public static int Distance(this DbFunctions _, DateOnly a, DateOnly b)
///
public static TimeSpan Distance(this DbFunctions _, DateTime a, DateTime b)
=> throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Distance)));
+
+ ///
+ /// Converts string to date according to the given format.
+ ///
+ /// The instance.
+ /// The string to be converted.
+ /// The format of the input date.
+ ///
+ public static DateOnly? ToDate(this DbFunctions _, string? value, string? format)
+ => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(ToDate)));
+
+ ///
+ /// Converts string to time stamp according to the given format.
+ ///
+ /// The instance.
+ /// The string to be converted
+ /// The format of the input date
+ ///
+ public static DateTime? ToTimestamp(this DbFunctions _, string? value, string? format)
+ => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(ToTimestamp)));
}
diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlStringMethodTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlStringMethodTranslator.cs
index 3a97d91e8..4cf7a59de 100644
--- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlStringMethodTranslator.cs
+++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlStringMethodTranslator.cs
@@ -78,6 +78,12 @@ public class NpgsqlStringMethodTranslator : IMethodCallTranslator
private static readonly MethodInfo StringToArrayNullString = typeof(NpgsqlDbFunctionsExtensions).GetRuntimeMethod(
nameof(NpgsqlDbFunctionsExtensions.StringToArray), [typeof(DbFunctions), typeof(string), typeof(string), typeof(string)])!;
+ private static readonly MethodInfo ToDate = typeof(NpgsqlDbFunctionsExtensions).GetRuntimeMethod(
+ nameof(NpgsqlDbFunctionsExtensions.ToDate), [typeof(DbFunctions), typeof(string), typeof(string)])!;
+
+ private static readonly MethodInfo ToTimestamp = typeof(NpgsqlDbFunctionsExtensions).GetRuntimeMethod(
+ nameof(NpgsqlDbFunctionsExtensions.ToTimestamp), [typeof(DbFunctions), typeof(string), typeof(string)])!;
+
private static readonly MethodInfo FirstOrDefaultMethodInfoWithoutArgs
= typeof(Enumerable).GetRuntimeMethods().Single(
m => m.Name == nameof(Enumerable.FirstOrDefault)
@@ -425,6 +431,30 @@ public NpgsqlStringMethodTranslator(NpgsqlTypeMappingSource typeMappingSource, I
_typeMappingSource.FindMapping(typeof(string[])));
}
+ if (method == ToDate)
+ {
+ return _sqlExpressionFactory.Function(
+ "to_date",
+ new[] { arguments[1], arguments[2] },
+ nullable: true,
+ argumentsPropagateNullability: new[] { true, true },
+ typeof(DateOnly?),
+ _typeMappingSource.FindMapping(typeof(DateOnly))
+ );
+ }
+
+ if (method == ToTimestamp)
+ {
+ return _sqlExpressionFactory.Function(
+ "to_timestamp",
+ new[] { arguments[1], arguments[2] },
+ nullable: true,
+ argumentsPropagateNullability: new[] { true, true },
+ typeof(DateTime?),
+ _typeMappingSource.FindMapping(typeof(DateTime))
+ );
+ }
+
return null;
}
diff --git a/test/EFCore.PG.FunctionalTests/Query/NorthwindDbFunctionsQueryNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Query/NorthwindDbFunctionsQueryNpgsqlTest.cs
index 46d03dc14..4b9f7a5da 100644
--- a/test/EFCore.PG.FunctionalTests/Query/NorthwindDbFunctionsQueryNpgsqlTest.cs
+++ b/test/EFCore.PG.FunctionalTests/Query/NorthwindDbFunctionsQueryNpgsqlTest.cs
@@ -227,6 +227,34 @@ WHERE string_to_array(c."ContactName", ' ', 'Maria') = ARRAY[NULL,'Anders']::tex
""");
}
+ [Fact]
+ public void ToDate()
+ {
+ using var context = CreateContext();
+ var count = context.Orders.Count(c => EF.Functions.ToDate(c.OrderDate.ToString(), "YYYY-MM-DD") < new DateOnly(2000, 01, 01));
+ Assert.Equal(830, count);
+ AssertSql(
+"""
+SELECT count(*)::int
+FROM "Orders" AS o
+WHERE to_date(o."OrderDate"::text, 'YYYY-MM-DD') < DATE '2000-01-01'
+""");
+ }
+
+ [Fact]
+ public void ToTimestamp()
+ {
+ using var context = CreateContext();
+ var count = context.Orders.Count(c => EF.Functions.ToTimestamp(c.OrderDate.ToString(), "YYYY-MM-DD") < new DateTime(2000, 01, 01, 0,0,0, DateTimeKind.Utc));
+ Assert.Equal(830, count);
+ AssertSql(
+ """
+SELECT count(*)::int
+FROM "Orders" AS o
+WHERE to_timestamp(o."OrderDate"::text, 'YYYY-MM-DD') < TIMESTAMPTZ '2000-01-01T00:00:00Z'
+""");
+ }
+
#endregion
private void AssertSql(params string[] expected)