I'm using NodaTime Instant for date/time storage in my DTOs with ServiceStack. I have specified the SQL type in the DTO as datetimeoffset, and ServiceStack correctly creates the table with that type. However, upon saving, I get an InvalidCastException.
Simple example:
public class ItemWithInstant
{
public int Id { get; set; }
public string Name { get; set; }
[CustomField("DateTimeOffset")
public Instant DateCreated { get; set; }
}
In the service:
public object Post(CreateItemWithInstant request)
{
var dto = request.ConvertTo<ItemWithInstant>();
Db.Save(dto); // ERROR here
return dto;
}
The specific error is an InvalidCastException with the detail of Failed to convert parameter value from a Instant to a String.
No idea why it's converting to a string when the database type is DateTimeOffset. Do I need to tell ServiceStack how to convert the value to something that works with the SQL type?
Update
Thanks to #mythz answer, I created a custom converter. I also ended up going to DATETIME2 for the SQL data type (don't think that makes much of a difference):
public class SqlServerInstantToDatetimeConverter : OrmLiteConverter
{
public override string ColumnDefinition { get { return "DATETIME2"; } }
public override DbType DbType { get { return DbType.DateTimeOffset; } }
public override object ToDbValue(Type fieldType, object value)
{
var instantValue = (Instant) value;
return instantValue.ToDateTimeUtc();
}
public override object FromDbValue(Type fieldType, object value)
{
var datetimeValue = DateTime.SpecifyKind((DateTime)value, DateTimeKind.Utc);
return Instant.FromDateTimeUtc(datetimeValue);
}
}
I then registered it in my AppHost.cs file:
Register<IDbConnectionFactory>(new OrmLiteConnectionFactory(Settings.Default.LocalSqlConnectionString, SqlServerDialect.Provider));
SqlServerDialect.Provider.RegisterConverter<Instant>(new SqlServerInstantConverter());
Don't forget the FromDbType override. I forgot it initially and the field wasn't being output.
One other caveat -- since ServiceStack wants to localize all dates, I had to use the info in this answer to force all dates to a DateTimeKind.Local
[CustomField] just tells OrmLite what column definition to use when creating the table, i.e. it doesn't provide any indication on how OrmLite should treat unknown types.
You can support new fields types by registering a Custom Type Converter that's now available in the latest v4.0.44 release.
I have an object that represents a scheduled payment. My database has a list of these payments, but I have one instance of a payment.
I need to write a method that gets the next payment after the one I have, as well as the previous date of the previous payment.
I'd like to write a method that return the two dates. But the return type of 'DateTime' only allows for one. I could return a List<DateTime> but that seems strange and ma be ambiguous. Which is the previous and which is the next?
I can also create a DTO object that has:
DateTime previousPayment {get; set;}
DateTime nextPayment {get; set;}
Tuple<DateTime, DateTime> might be another options, but it too is ambiguous. Unless I can name the properties of it?
But - is there a better way to allow for a method to return two dates? Anonymous types or something?
Use the "ref" modifier. (You may use "out" instead if you do not need to read the variable before it is assigned)
public void GetNextPayment(ref DateTime previousPayment, ref DateTime nextPayment){
// do stuff here
}
Usage:
DateTime previousPayment = DateTime.Now(); //Example
DateTime nextPayment = DateTime.Now(); // example
GetNextPayment(ref previousPayment, ref nextPayment); // Forgot to add "ref" when calling it
previousPayment and nextPayment will be modified in the function and maintain the value.
Update with Dictionary
As Anik mentioned, it might be better to use a Dictionary;
public Dictionary<string,DateTime> GetNextPayment(DateTime previousPayment, DateTime nextPayment){
// modify payments
Dictionary<string,DateTime> myDict = new Dictionary(string, DateTime);
myDict.Add("PreviousPayment", [date]);
myDict.Add("NextPayment", [date]);
return myDict;
}
Use Class
Ilya. N. mentioned to use a class. I would have to agree with this if you're going to have lots of payment objects going to be used more than once. But I firmly believe it's better to give you all the tools available at your disposal because you never know when you might want to use out parameters or Dictionaries.
public class Payment {
public string Name {get;set;}
public DateTime previousPayment {get;set;}
public DateTime nextPayment {get;set;}
public GetNextPayment(){
// code to get the next payment
this.previousPayment = //whatever
this.nextPayment = //whatever
}
}
If you only have ONE payment you are going to be using, like ever. (good to future proof with a class), then you might use a method or dictionary.
Besides the two options you listed, there are two more:
Return a Tuple<DateTime, DateTime>
Use out parameters
Why not simply return a class?
public class DateCombo {
DateTime PreviousPayment {get; set;}
DateTime NextPayment {get; set;}
}
try this ...
private void Form1_Load(object sender, EventArgs e)
{
DateTime previousPayment =new DateTime();
DateTime nextPayment=new DateTime();
getdate(ref previousPayment, ref nextPayment);
}
public void getdate(ref DateTime previousPayment, ref DateTime nextPayment)
{
previousPayment = System.DateTime.Now;
nextPayment = System.DateTime.Now.AddDays(1);
}
What is the best way to compare all properties of two objects where some of them have different formats (e.g. DateTime in one and DateTime.ToString() with custom format in other)?
I was able to do that by using 2 assertions:
o1.ShouldHave().AllPropertiesBut(dto1 => dto1.Date).EqualTo(o2);
o1.Date.Should().Be(DateTime.Parse(o2.Date));
I would think about the following, but that does not compile because EqualTo<T>() is void.
o1.ShouldHave().AllProperties().But(d => d.Date).EqualTo(o2)
.And.Date.Should().Be((DateTime.Parse(o2.Date));
types are:
public class Dto1
{
public int ID { get { return 1; } }
public DateTime Date { get { return DateTime.Now.Date; } }
}
public class Dto2
{
public int ID { get { return 1; } }
public string Date { get { return DateTime.Now.Date.ToShortDateString(); } }
}
var o1 = new Dto1();
var o2 = new Dto2();
The first example is typically the best way. However, if you would switch o1 and o2, it might work in a single call. Fluent Assertions will try to convert (using Convert.ChangeType) the actual value of a property to the expected value of the property with the same name. In your particular example, it would try to convert the DateTime in Dto1 to a string in Dto2 before comparing the values. But since the string representation of a DateTime is dependent on the culture of the thread, it would not give you predictable results. However, if you would switch o1 and o2, I wouldn't be surprised if Convert.ChangeType would succesfully convert your short datetime back to a DateTIme object.
As a side-note, my DTOs usually just pass the DateTime to the caller without any string conversion. I believe that the actual representation of the DateTime is purely a UI responsibility.
HTH
Dennis
This question already has answers here:
Unit Testing: DateTime.Now
(22 answers)
Closed last year.
I have this method which is dependent on current date. It checks if today is Sun, Mon, Tue or Wed, then it gives 5 days of lead time for arrival of shipped items. If its Thur, Fri or Sat then it gives 6 days of lead time to account for the weekend.
private DateTime GetEstimatedArrivalDate()
{
DateTime estimatedDate;
if (DateTime.Now.DayOfWeek >= DayOfWeek.Thursday)
{
estimatedDate = DateTime.Now.Date.AddDays(6);
}
else
{
estimatedDate = DateTime.Now.Date.AddDays(5);
}
return estimatedDate;
}
The actual estimation logic is more complex. I have simplified it for the purpose of this question. My question is how do I write a unit test for something like this which depends on todays date?
You need to pass the current date in as a parameter:
private DateTime GetEstimatedArrivalDate(DateTime currentDate)
{
DateTime estimatedDate;
if (currentDate.DayOfWeek >= DayOfWeek.Thursday)
{
estimatedDate = currentDate.AddDays(6);
}
else
{
estimatedDate = currentDate.AddDays(5);
}
return estimatedDate;
}
In real code you call it like this:
DateTime estimatedDate = GetEstimatedArrivalDate(DateTime.Now.Date);
Then you can test it as follows:
DateTime actual = GetEstimatedArrivalDate(new DateTime(2010, 2, 10));
DateTime expected = ...;
// etc...
Note that this also fixes a potential bug in your program where the date changes between consecutive calls to DateTime.Now.
Generally speaking, you'd want to abstract the method of obtaining the current date and time behind an interface, eg:
public interface IDateTimeProvider
{
DateTime Now { get; }
}
The real service would be:
public class DateTimeProvider: IDateTimeProvider
{
public DateTime Now
{
get
{
return DateTime.Now;
}
}
}
And a test service would be:
public class TestDateTimeProvider: IDateTimeProvider
{
private DateTime timeToProvide;
public TestDateTimeProvider(DateTime timeToProvide)
{
this.timeToProvide = timeToProvide;
}
public DateTime Now
{
get
{
return timeToProvide;
}
}
}
For services that require the current time, have them take an IDateTimeProvider as a dependency. For the real thing, pass a new DateTimeProvider(); when you're a component, pass in a new TestDateTimeProvider(timeToTestFor).
Make your class take an IClock parameter (via constructor or property)
interface IClock
{
DateTime Now { get; }
}
You can then use a fake implementation for testing
class FakeClock : IClock
{
DateTime Now { get; set }
}
and a real implementation the rest of the time.
class SystemClock : IClock
{
DateTime Now { get { return DateTime.Now; } }
}
I would suggest doing this as Mark suggests, but with the addition of a overloaded call for production use that takes no parameter and uses DateTime.Now
private DateTime GetEstimatedArrivalDate()
{
return GetEstimatedArrivalDate(DateTime.Now);
}
private DateTime GetEstimatedArrivalDate(DateTime currentDate)
{
DateTime estimatedDate;
if (currentDate.DayOfWeek >= DayOfWeek.Thursday)
{
estimatedDate = currentDate.AddDays(6);
}
else
{
estimatedDate = currentDate.AddDays(5);
}
return estimatedDate;
}
One "common" way of doing so is to "fake" the current system date (that can be done in several ways) and then test your code on "known" dates.
Another interesting way is to change your implementation slightly to:
private DateTime GetEstimatedArrivalDate()
{
return GetEstimatedArrivalDate(DateTime.Now);
}
private DateTime GetEstimatedArrivalDate(DateTime forDate)
{
DateTime estimatedDate;
if (forDate.DayOfWeek >= DayOfWeek.Thursday)
{
estimatedDate = forDate.Date.AddDays(6);
}
else
{
estimatedDate = forDate.Date.AddDays(5);
}
return estimatedDate;
}
And then use the method with a parameter to test on "immediate" dates.
Seems like there are a limited enough number of cases that you could test them each explicitly. The method depends on today's date, but the output depends only on the day of week, and every date has a day of week.
You could pass in a delegate that returns DateTime.Now during normal execution, and then in your test pass in another delegate that returns a fixed date, and assert your result based on that.
I'll give the controversial answer, don't test it.
The logic is trivial and it has zero dependencies, i believe in good code coverage but not when it increases complexity for no real gain.
Does any one know how I can specify the Default value for a DateTime property using the System.ComponentModel DefaultValue Attribute?
for example I try this:
[DefaultValue(typeof(DateTime),DateTime.Now.ToString("yyyy-MM-dd"))]
public DateTime DateCreated { get; set; }
And it expects the value to be a constant expression.
This is in the context of using with ASP.NET Dynamic Data. I do not want to scaffold the DateCreated column but simply supply the DateTime.Now if it is not present. I am using the Entity Framework as my Data Layer
Cheers.
You cannot do this with an attribute because they are just meta information generated at compile time. Just add code to the constructor to initialize the date if required, create a trigger and handle missing values in the database, or implement the getter in a way that it returns DateTime.Now if the backing field is not initialized.
public DateTime DateCreated
{
get
{
return this.dateCreated.HasValue
? this.dateCreated.Value
: DateTime.Now;
}
set { this.dateCreated = value; }
}
private DateTime? dateCreated = null;
Add below to the DateTime property
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
I have tested this on EF core 2.1
Here you cannot use either Conventions or Data Annotations. You must use the Fluent API.
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.Created)
.HasDefaultValueSql("getdate()");
}
}
Official doc
There's no reason I can come up with that it shouldn't be possible to do through an attribute. It might be in Microsoft's backlog. Who knows.
The best solution I have found is to use the defaultValueSql parameter in the code first migration.
CreateTable(
"dbo.SomeTable",
c => new
{
TheDateField = c.DateTime(defaultValueSql: "GETDATE()")
});
I don't like the often reference solution of setting it in the entity class constructor because if anything other than Entity Framework sticks a record in that table, the date field won't get a default value. And the idea of using a trigger to handle that case just seems wrong to me.
It is possible and quite simple:
for DateTime.MinValue
[System.ComponentModel.DefaultValue(typeof(DateTime), "")]
for any other value as last argument of DefaultValueAttribute specify string that represent desired DateTime value.
This value must be constant expression and is required to create object (DateTime) using TypeConverter.
Just found this looking for something different, but in the new C# version, you can use an even shorter version for that:
public DateTime DateCreated { get; set; } = DateTime.Now;
A simple solution if you are using the Entity Framework is the add a partical class and define a constructor for the entity as the framework does not define one. For example if you have an entity named Example you would put the following code in a seperate file.
namespace EntityExample
{
public partial class Example : EntityObject
{
public Example()
{
// Initialize certain default values here.
this._DateCreated = DateTime.Now;
}
}
}
I think the easiest solution is to set
Created DATETIME2 NOT NULL DEFAULT GETDATE()
in column declaration and in VS2010 EntityModel designer set corresponding column property StoreGeneratedPattern = Computed.
Creating a new attribute class is a good suggestion. In my case, I wanted to specify 'default(DateTime)' or 'DateTime.MinValue' so that the Newtonsoft.Json serializer would ignore DateTime members without real values.
[JsonProperty( DefaultValueHandling = DefaultValueHandling.Ignore )]
[DefaultDateTime]
public DateTime EndTime;
public class DefaultDateTimeAttribute : DefaultValueAttribute
{
public DefaultDateTimeAttribute()
: base( default( DateTime ) ) { }
public DefaultDateTimeAttribute( string dateTime )
: base( DateTime.Parse( dateTime ) ) { }
}
Without the DefaultValue attribute, the JSON serializer would output "1/1/0001 12:00:00 AM" even though the DefaultValueHandling.Ignore option was set.
Simply consider setting its value in the constructor of your entity class
public class Foo
{
public DateTime DateCreated { get; set; }
public Foo()
{
DateCreated = DateTime.Now;
}
}
using System.ComponentModel.DataAnnotations.Schema;
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime CreatedOn { get; private set; }
I needed a UTC Timestamp as a default value and so modified Daniel's solution like this:
[Column(TypeName = "datetime2")]
[XmlAttribute]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
[Display(Name = "Date Modified")]
[DateRange(Min = "1900-01-01", Max = "2999-12-31")]
public DateTime DateModified {
get { return dateModified; }
set { dateModified = value; }
}
private DateTime dateModified = DateTime.Now.ToUniversalTime();
For DateRangeAttribute tutorial, see this awesome blog post
There is a way. Add these classes:
DefaultDateTimeValueAttribute.cs
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using Custom.Extensions;
namespace Custom.DefaultValueAttributes
{
/// <summary>
/// This class's DefaultValue attribute allows the programmer to use DateTime.Now as a default value for a property.
/// Inspired from https://code.msdn.microsoft.com/A-flexible-Default-Value-11c2db19.
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public sealed class DefaultDateTimeValueAttribute : DefaultValueAttribute
{
public string DefaultValue { get; set; }
private object _value;
public override object Value
{
get
{
if (_value == null)
return _value = GetDefaultValue();
return _value;
}
}
/// <summary>
/// Initialized a new instance of this class using the desired DateTime value. A string is expected, because the value must be generated at runtime.
/// Example of value to pass: Now. This will return the current date and time as a default value.
/// Programmer tip: Even if the parameter is passed to the base class, it is not used at all. The property Value is overridden.
/// </summary>
/// <param name="defaultValue">Default value to render from an instance of <see cref="DateTime"/></param>
public DefaultDateTimeValueAttribute(string defaultValue) : base(defaultValue)
{
DefaultValue = defaultValue;
}
public static DateTime GetDefaultValue(Type objectType, string propertyName)
{
var property = objectType.GetProperty(propertyName);
var attribute = property.GetCustomAttributes(typeof(DefaultDateTimeValueAttribute), false)
?.Cast<DefaultDateTimeValueAttribute>()
?.FirstOrDefault();
return attribute.GetDefaultValue();
}
private DateTime GetDefaultValue()
{
// Resolve a named property of DateTime, like "Now"
if (this.IsProperty)
{
return GetPropertyValue();
}
// Resolve a named extension method of DateTime, like "LastOfMonth"
if (this.IsExtensionMethod)
{
return GetExtensionMethodValue();
}
// Parse a relative date
if (this.IsRelativeValue)
{
return GetRelativeValue();
}
// Parse an absolute date
return GetAbsoluteValue();
}
private bool IsProperty
=> typeof(DateTime).GetProperties()
.Select(p => p.Name).Contains(this.DefaultValue);
private bool IsExtensionMethod
=> typeof(DefaultDateTimeValueAttribute).Assembly
.GetType(typeof(DefaultDateTimeExtensions).FullName)
.GetMethods()
.Where(m => m.IsDefined(typeof(ExtensionAttribute), false))
.Select(p => p.Name).Contains(this.DefaultValue);
private bool IsRelativeValue
=> this.DefaultValue.Contains(":");
private DateTime GetPropertyValue()
{
var instance = Activator.CreateInstance<DateTime>();
var value = (DateTime)instance.GetType()
.GetProperty(this.DefaultValue)
.GetValue(instance);
return value;
}
private DateTime GetExtensionMethodValue()
{
var instance = Activator.CreateInstance<DateTime>();
var value = (DateTime)typeof(DefaultDateTimeValueAttribute).Assembly
.GetType(typeof(DefaultDateTimeExtensions).FullName)
.GetMethod(this.DefaultValue)
.Invoke(instance, new object[] { DateTime.Now });
return value;
}
private DateTime GetRelativeValue()
{
TimeSpan timeSpan;
if (!TimeSpan.TryParse(this.DefaultValue, out timeSpan))
{
return default(DateTime);
}
return DateTime.Now.Add(timeSpan);
}
private DateTime GetAbsoluteValue()
{
DateTime value;
if (!DateTime.TryParse(this.DefaultValue, out value))
{
return default(DateTime);
}
return value;
}
}
}
DefaultDateTimeExtensions.cs
using System;
namespace Custom.Extensions
{
/// <summary>
/// Inspired from https://code.msdn.microsoft.com/A-flexible-Default-Value-11c2db19. See usage for more information.
/// </summary>
public static class DefaultDateTimeExtensions
{
public static DateTime FirstOfYear(this DateTime dateTime)
=> new DateTime(dateTime.Year, 1, 1, dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond);
public static DateTime LastOfYear(this DateTime dateTime)
=> new DateTime(dateTime.Year, 12, 31, dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond);
public static DateTime FirstOfMonth(this DateTime dateTime)
=> new DateTime(dateTime.Year, dateTime.Month, 1, dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond);
public static DateTime LastOfMonth(this DateTime dateTime)
=> new DateTime(dateTime.Year, dateTime.Month, DateTime.DaysInMonth(dateTime.Year, dateTime.Month), dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond);
}
}
And use DefaultDateTimeValue as an attribute to your properties. Value to input to your validation attribute are things like "Now", which will be rendered at run time from a DateTime instance created with an Activator. The source code is inspired from this thread: https://code.msdn.microsoft.com/A-flexible-Default-Value-11c2db19. I changed it to make my class inherit with DefaultValueAttribute instead of a ValidationAttribute.
I faced the same issue, but the one which works for me best is below:
public DateTime CreatedOn { get; set; } = DateTime.Now;
In C# Version 6 it's possible to provide a default value
public DateTime fieldname { get; set; } = DateTime.Now;
Using EntityTypeConfiguration, I get it like this:
public class UserMap : IEntityTypeConfiguration<User>
{
public void Configure(EntityTypeBuilder<User> builder)
{
//throw new NotImplementedException();
builder.Property(u => u.Id).ValueGeneratedOnAdd();
builder.Property(u => u.Name).IsRequired().HasMaxLength(100);
builder.HasIndex(u => u.Email).IsUnique();
builder.Property(u => u.Status).IsRequired();
builder.Property(u => u.Password).IsRequired();
builder.Property(u => u.Registration).HasDefaultValueSql("getdate()");
builder.HasMany(u => u.DrawUser).WithOne(u => u.User);
builder.ToTable("User");
}
}
Using the Fluent API, in OnModelCreating function in your Context class add following.
builder.Property(u => u.CreatedAt).ValueGeneratedOnAdd();
builder.Property(u => u.UpdatedAt).ValueGeneratedOnAddOrUpdate();
Note I'm using a separate type configuration class. If you did right in the function would be like:
builder.Enitity<User>().Property(u => u.CreatedAt).ValueGeneratedOnAdd();
public DateTime DateCreated
{
get
{
return (this.dateCreated == default(DateTime))
? this.dateCreated = DateTime.Now
: this.dateCreated;
}
set { this.dateCreated = value; }
}
private DateTime dateCreated = default(DateTime);
How you deal with this at the moment depends on what model you are using Linq to SQL or EntityFramework?
In L2S you can add
public partial class NWDataContext
{
partial void InsertCategory(Category instance)
{
if(Instance.Date == null)
Instance.Data = DateTime.Now;
ExecuteDynamicInsert(instance);
}
}
EF is a little more complicated see http://msdn.microsoft.com/en-us/library/cc716714.aspx for more info on EF buisiness logic.
I know this post is a little old, but a have a suggestion that may help some.
I used an Enum to determine what to set in the attribute constructor.
Property declaration :
[DbProperty(initialValue: EInitialValue.DateTime_Now)]
public DateTime CreationDate { get; set; }
Property constructor :
Public Class DbProperty Inherits System.Attribute
Public Property InitialValue As Object
Public Sub New(ByVal initialValue As EInitialValue)
Select Case initialValue
Case EInitialValue.DateTime_Now
Me.InitialValue = System.DateTime.Now
Case EInitialValue.DateTime_Min
Me.InitialValue = System.DateTime.MinValue
Case EInitialValue.DateTime_Max
Me.InitialValue = System.DateTime.MaxValue
End Select
End Sub
End Class
Enum :
Public Enum EInitialValue
DateTime_Now
DateTime_Min
DateTime_Max
End Enum
I think you can do this using StoreGeneratedPattern = Identity (set in the model designer properties window).
I wouldn't have guessed that would be how to do it, but while trying to figure it out I noticed that some of my date columns were already defaulting to CURRENT_TIMESTAMP() and some weren't. Checking the model, I see that the only difference between the two columns besides the name is that the one getting the default value has StoreGeneratedPattern set to Identity.
I wouldn't have expected that to be the way, but reading the description, it sort of makes sense:
Determines if the corresponding column in the database will be auto-generated during insert and update operations.
Also, while this does make the database column have a default value of "now", I guess it does not actually set the property to be DateTime.Now in the POCO. This hasn't been an issue for me as I have a customized .tt file that already sets all of my date columns to DateTime.Now automatically (it's actually not hard to modify the .tt file yourself, especially if you have ReSharper and get a syntax highlighting plugin. (Newer versions of VS may already syntax highlight .tt files, not sure.))
The issue for me was: how do I get the database column to have a default so that existing queries that omit that column will still work? And the above setting worked for that.
I haven't tested it yet but it's also possible that setting this will interfere with setting your own explicit value. (I only stumbled upon this in the first place because EF6 Database First wrote the model for me this way.)
below works in .NET 5.0
private DateTime _DateCreated= DateTime.Now;
public DateTime DateCreated
{
get
{
return this._DateCreated;
}
set { this._DateCreated = value; }
}
You can also consider using the DatabaseGenerated attribute, example
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public DateTime DateCreated { get; set; }
https://learn.microsoft.com/en-us/ef/core/modeling/generated-properties?tabs=data-annotations
I also wanted this and came up with this solution (I'm only using the date part - a default time makes no sense as a PropertyGrid default):
public class DefaultDateAttribute : DefaultValueAttribute {
public DefaultDateAttribute(short yearoffset)
: base(DateTime.Now.AddYears(yearoffset).Date) {
}
}
This just creates a new attribute that you can add to your DateTime property.
E.g. if it defaults to DateTime.Now.Date:
[DefaultDate(0)]