diff --git a/src/Client/Features/FreeAgents/Detail/BidCountdown.razor.cs b/src/Client/Features/FreeAgents/Detail/BidCountdown.razor.cs
index f4678c0..d9867ff 100644
--- a/src/Client/Features/FreeAgents/Detail/BidCountdown.razor.cs
+++ b/src/Client/Features/FreeAgents/Detail/BidCountdown.razor.cs
@@ -7,7 +7,7 @@ namespace DynamoLeagueBlazor.Client.Features.FreeAgents.Detail;
public partial class BidCountdown
{
- [Parameter, EditorRequired] public DateTime DateTime { get; set; }
+ [Parameter, EditorRequired] public DateTimeOffset DateTime { get; set; }
private readonly Timer _timer = new(1000);
private string _remainingTime = string.Empty;
@@ -21,7 +21,7 @@ protected override void OnInitialized()
private void CountDown(object? source, ElapsedEventArgs e)
{
- var remainingTime = DateTime - DateTime.Now;
+ var remainingTime = DateTime - DateTimeOffset.UtcNow;
if (remainingTime <= TimeSpan.FromDays(1))
{
diff --git a/src/Client/Features/FreeAgents/List.razor b/src/Client/Features/FreeAgents/List.razor
index 9f7181e..3a17152 100644
--- a/src/Client/Features/FreeAgents/List.razor
+++ b/src/Client/Features/FreeAgents/List.razor
@@ -41,7 +41,7 @@
@context.Position
@context.Team
- @context.BiddingEnds.ToShortDateString()
+ @context.BiddingEnds.LocalDateTime.ToShortDateString()
diff --git a/src/Client/Features/Rules/Cost.razor b/src/Client/Features/Rules/Cost.razor
index fba8041..b37f5be 100644
--- a/src/Client/Features/Rules/Cost.razor
+++ b/src/Client/Features/Rules/Cost.razor
@@ -5,7 +5,7 @@
Dues must be paid by January 1st each season. If an owner does not pay by one week before the season, that owner will be removed from the league.
- @foreach(var year in Enumerable.Range(DateTime.Today.Year, 5))
+ @foreach(var year in Enumerable.Range(DateTimeOffset.UtcNow.Year, 5))
{
var date = new DateOnly(year, 1, 1);
diff --git a/src/Server/Features/Admin/StartSeason.cs b/src/Server/Features/Admin/StartSeason.cs
index edca0fd..95bca42 100644
--- a/src/Server/Features/Admin/StartSeason.cs
+++ b/src/Server/Features/Admin/StartSeason.cs
@@ -53,8 +53,8 @@ public record StartSeasonCommand : IRequest { }
public class StartSeasonHandler : IRequestHandler
{
private readonly ApplicationDbContext _dbContext;
- private readonly DateTime _boundaryStartDate = new(DateTime.Today.Year, 6, 25);
- private readonly DateTime _boundaryEndDate = new(DateTime.Today.Year, 8, 20);
+ private readonly DateTimeOffset _boundaryStartDate = new(DateTimeOffset.UtcNow.Year, 6, 25, 0, 0, 0, TimeSpan.Zero);
+ private readonly DateTimeOffset _boundaryEndDate = new(DateTimeOffset.UtcNow.Year, 8, 20, 0, 0, 0, TimeSpan.Zero);
public StartSeasonHandler(ApplicationDbContext dbContext)
{
@@ -66,7 +66,7 @@ public async Task Handle(StartSeasonCommand request, CancellationToken cancellat
var random = new Random();
var players = _dbContext.Players
- .Where(p => p.YearContractExpires < DateTime.Today.Year)
+ .Where(p => p.YearContractExpires < DateTimeOffset.UtcNow.Year)
.AsTracking();
foreach (var player in players)
@@ -76,14 +76,14 @@ public async Task Handle(StartSeasonCommand request, CancellationToken cancellat
player.BeginNewSeason(endOfFreeAgency);
}
- var startOfTheCurrentYear = new DateTime(DateTime.Today.Year, 1, 1);
+ var startOfTheCurrentYear = new DateTimeOffset(DateTimeOffset.UtcNow.Year, 1, 1, 0, 0, 0, TimeSpan.Zero);
var fines = _dbContext.Fines.Where(f => f.CreatedOn < startOfTheCurrentYear);
_dbContext.Fines.RemoveRange(fines);
await _dbContext.SaveChangesAsync(cancellationToken);
}
- private static DateTime GetRandomBoundariedDate(Random seed, DateTime boundaryStartDate, DateTime boundaryEndDate)
+ private static DateTimeOffset GetRandomBoundariedDate(Random seed, DateTimeOffset boundaryStartDate, DateTimeOffset boundaryEndDate)
{
var maximumDaysToAdd = (boundaryEndDate - boundaryStartDate).Days;
var daysToAdd = seed.Next(maximumDaysToAdd);
diff --git a/src/Server/Features/FreeAgents/Detail/AddBid.cs b/src/Server/Features/FreeAgents/Detail/AddBid.cs
index 3fd19c6..809fd30 100644
--- a/src/Server/Features/FreeAgents/Detail/AddBid.cs
+++ b/src/Server/Features/FreeAgents/Detail/AddBid.cs
@@ -106,7 +106,7 @@ public async Task HasNotEndedAsync(AddBidRequest request, CancellationToke
{
var player = await _dbContext.Players.FindAsync(new object[] { request.PlayerId }, cancellationToken);
- var hasNotEnded = player!.EndOfFreeAgency > DateTime.Now;
+ var hasNotEnded = player!.EndOfFreeAgency > DateTimeOffset.UtcNow;
return hasNotEnded;
}
diff --git a/src/Server/Features/FreeAgents/EndBidding.cs b/src/Server/Features/FreeAgents/EndBidding.cs
index f7ddee1..fe15e41 100644
--- a/src/Server/Features/FreeAgents/EndBidding.cs
+++ b/src/Server/Features/FreeAgents/EndBidding.cs
@@ -19,7 +19,7 @@ public async Task Invoke()
var players = await _dbContext.Players
.AsTracking()
.Where(p => p.State == PlayerState.FreeAgent
- && p.EndOfFreeAgency <= DateTime.Now)
+ && p.EndOfFreeAgency <= DateTimeOffset.UtcNow)
.ToListAsync();
if (!players.Any()) return;
diff --git a/src/Server/Features/OfferMatching/ExpireOfferMatching.cs b/src/Server/Features/OfferMatching/ExpireOfferMatching.cs
index 56a33a8..08adb0f 100644
--- a/src/Server/Features/OfferMatching/ExpireOfferMatching.cs
+++ b/src/Server/Features/OfferMatching/ExpireOfferMatching.cs
@@ -20,7 +20,7 @@ public async Task Invoke()
.AsTracking()
.Include(p => p.Bids)
.Where(p => p.State == PlayerState.OfferMatching
- && p.EndOfFreeAgency!.Value.AddDays(3) <= DateTime.Today)
+ && p.EndOfFreeAgency!.Value.AddDays(3) <= DateTimeOffset.UtcNow)
.ToListAsync();
if (!players.Any()) return;
diff --git a/src/Server/Features/Teams/List.cs b/src/Server/Features/Teams/List.cs
index 1531d20..b9ce5b8 100644
--- a/src/Server/Features/Teams/List.cs
+++ b/src/Server/Features/Teams/List.cs
@@ -74,7 +74,7 @@ await Parallel.ForEachAsync(teams, async (team, cancellationToken) =>
var unsignedPlayersContractValue = await unsignedPlayersQuery.SumAsync(rp => rp.ContractValue, cancellationToken);
- team.CapSpace = CapSpaceUtilities.GetRemainingCapSpace(DateOnly.FromDateTime(DateTime.Today), rosteredPlayersContractValue, unrosteredPlayersContractValue, unsignedPlayersContractValue).ToString("C0");
+ team.CapSpace = CapSpaceUtilities.GetRemainingCapSpace(DateOnly.FromDateTime(DateTimeOffset.UtcNow.DateTime), rosteredPlayersContractValue, unrosteredPlayersContractValue, unsignedPlayersContractValue).ToString("C0");
});
return new TeamListResult
diff --git a/src/Server/Infrastructure/Migrations/20230302013711_ChangeToDateTimeOffset.Designer.cs b/src/Server/Infrastructure/Migrations/20230302013711_ChangeToDateTimeOffset.Designer.cs
new file mode 100644
index 0000000..895271b
--- /dev/null
+++ b/src/Server/Infrastructure/Migrations/20230302013711_ChangeToDateTimeOffset.Designer.cs
@@ -0,0 +1,638 @@
+//
+using System;
+using DynamoLeagueBlazor.Server.Infrastructure;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace DynamoLeagueBlazor.Server.Infrastructure.Migrations
+{
+ [DbContext(typeof(ApplicationDbContext))]
+ [Migration("20230302013711_ChangeToDateTimeOffset")]
+ partial class ChangeToDateTimeOffset
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.3")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("Duende.IdentityServer.EntityFramework.Entities.DeviceFlowCodes", b =>
+ {
+ b.Property("UserCode")
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.Property("ClientId")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2");
+
+ b.Property("Data")
+ .IsRequired()
+ .HasMaxLength(50000)
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Description")
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.Property("DeviceCode")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.Property("Expiration")
+ .IsRequired()
+ .HasColumnType("datetime2");
+
+ b.Property("SessionId")
+ .HasMaxLength(100)
+ .HasColumnType("nvarchar(100)");
+
+ b.Property("SubjectId")
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.HasKey("UserCode");
+
+ b.HasIndex("DeviceCode")
+ .IsUnique();
+
+ b.HasIndex("Expiration");
+
+ b.ToTable("DeviceCodes", (string)null);
+ });
+
+ modelBuilder.Entity("Duende.IdentityServer.EntityFramework.Entities.Key", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("Algorithm")
+ .IsRequired()
+ .HasMaxLength(100)
+ .HasColumnType("nvarchar(100)");
+
+ b.Property("Created")
+ .HasColumnType("datetime2");
+
+ b.Property("Data")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DataProtected")
+ .HasColumnType("bit");
+
+ b.Property("IsX509Certificate")
+ .HasColumnType("bit");
+
+ b.Property("Use")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("Version")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Use");
+
+ b.ToTable("Keys", (string)null);
+ });
+
+ modelBuilder.Entity("Duende.IdentityServer.EntityFramework.Entities.PersistedGrant", b =>
+ {
+ b.Property("Key")
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.Property("ClientId")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.Property("ConsumedTime")
+ .HasColumnType("datetime2");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2");
+
+ b.Property("Data")
+ .IsRequired()
+ .HasMaxLength(50000)
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Description")
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.Property("Expiration")
+ .HasColumnType("datetime2");
+
+ b.Property("SessionId")
+ .HasMaxLength(100)
+ .HasColumnType("nvarchar(100)");
+
+ b.Property("SubjectId")
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("nvarchar(50)");
+
+ b.HasKey("Key");
+
+ b.HasIndex("ConsumedTime");
+
+ b.HasIndex("Expiration");
+
+ b.HasIndex("SubjectId", "ClientId", "Type");
+
+ b.HasIndex("SubjectId", "SessionId", "Type");
+
+ b.ToTable("PersistedGrants", (string)null);
+ });
+
+ modelBuilder.Entity("DynamoLeagueBlazor.Server.Infrastructure.Identity.ApplicationRole", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Name")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("NormalizedName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName")
+ .IsUnique()
+ .HasDatabaseName("RoleNameIndex")
+ .HasFilter("[NormalizedName] IS NOT NULL");
+
+ b.ToTable("AspNetRoles", (string)null);
+ });
+
+ modelBuilder.Entity("DynamoLeagueBlazor.Server.Infrastructure.Identity.ApplicationUser", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("AccessFailedCount")
+ .HasColumnType("int");
+
+ b.Property("Approved")
+ .HasColumnType("bit");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Email")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("EmailConfirmed")
+ .HasColumnType("bit");
+
+ b.Property("LockoutEnabled")
+ .HasColumnType("bit");
+
+ b.Property("LockoutEnd")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("NormalizedEmail")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("NormalizedUserName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("PasswordHash")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PhoneNumber")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PhoneNumberConfirmed")
+ .HasColumnType("bit");
+
+ b.Property("SecurityStamp")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("TeamId")
+ .HasColumnType("int");
+
+ b.Property("TwoFactorEnabled")
+ .HasColumnType("bit");
+
+ b.Property("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedEmail")
+ .HasDatabaseName("EmailIndex");
+
+ b.HasIndex("NormalizedUserName")
+ .IsUnique()
+ .HasDatabaseName("UserNameIndex")
+ .HasFilter("[NormalizedUserName] IS NOT NULL");
+
+ b.HasIndex("TeamId");
+
+ b.ToTable("AspNetUsers", (string)null);
+ });
+
+ modelBuilder.Entity("DynamoLeagueBlazor.Server.Models.Bid", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Amount")
+ .HasColumnType("int");
+
+ b.Property("CreatedOn")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("IsOverBid")
+ .HasColumnType("bit");
+
+ b.Property("PlayerId")
+ .HasColumnType("int");
+
+ b.Property("TeamId")
+ .HasColumnType("int");
+
+ b.Property("UpdatedOn")
+ .HasColumnType("datetimeoffset");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PlayerId");
+
+ b.HasIndex("TeamId");
+
+ b.ToTable("Bids");
+ });
+
+ modelBuilder.Entity("DynamoLeagueBlazor.Server.Models.Fine", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Amount")
+ .HasColumnType("decimal(18,0)");
+
+ b.Property("CreatedOn")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("PlayerId")
+ .HasColumnType("int");
+
+ b.Property("Reason")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Status")
+ .HasColumnType("bit");
+
+ b.Property("TeamId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PlayerId");
+
+ b.HasIndex("TeamId");
+
+ b.ToTable("Fines");
+ });
+
+ modelBuilder.Entity("DynamoLeagueBlazor.Server.Models.Player", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("ContractValue")
+ .HasColumnType("int");
+
+ b.Property("EndOfFreeAgency")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("HeadShotUrl")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Position")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("State")
+ .HasColumnType("int");
+
+ b.Property("TeamId")
+ .HasColumnType("int");
+
+ b.Property("YearAcquired")
+ .HasColumnType("int");
+
+ b.Property("YearContractExpires")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TeamId");
+
+ b.ToTable("Players");
+ });
+
+ modelBuilder.Entity("DynamoLeagueBlazor.Server.Models.Team", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("LogoUrl")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Teams");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("ClaimType")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ClaimValue")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("RoleId")
+ .IsRequired()
+ .HasColumnType("nvarchar(450)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetRoleClaims", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("ClaimType")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ClaimValue")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UserId")
+ .IsRequired()
+ .HasColumnType("nvarchar(450)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserClaims", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.Property("LoginProvider")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("ProviderKey")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("ProviderDisplayName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UserId")
+ .IsRequired()
+ .HasColumnType("nvarchar(450)");
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserLogins", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("RoleId")
+ .HasColumnType("nvarchar(450)");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetUserRoles", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("LoginProvider")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("Name")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("Value")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AspNetUserTokens", (string)null);
+ });
+
+ modelBuilder.Entity("DynamoLeagueBlazor.Server.Infrastructure.Identity.ApplicationUser", b =>
+ {
+ b.HasOne("DynamoLeagueBlazor.Server.Models.Team", "Team")
+ .WithMany()
+ .HasForeignKey("TeamId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Team");
+ });
+
+ modelBuilder.Entity("DynamoLeagueBlazor.Server.Models.Bid", b =>
+ {
+ b.HasOne("DynamoLeagueBlazor.Server.Models.Player", "Player")
+ .WithMany("Bids")
+ .HasForeignKey("PlayerId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DynamoLeagueBlazor.Server.Models.Team", "Team")
+ .WithMany()
+ .HasForeignKey("TeamId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Player");
+
+ b.Navigation("Team");
+ });
+
+ modelBuilder.Entity("DynamoLeagueBlazor.Server.Models.Fine", b =>
+ {
+ b.HasOne("DynamoLeagueBlazor.Server.Models.Player", "Player")
+ .WithMany("Fines")
+ .HasForeignKey("PlayerId");
+
+ b.HasOne("DynamoLeagueBlazor.Server.Models.Team", "Team")
+ .WithMany("Fines")
+ .HasForeignKey("TeamId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Player");
+
+ b.Navigation("Team");
+ });
+
+ modelBuilder.Entity("DynamoLeagueBlazor.Server.Models.Player", b =>
+ {
+ b.HasOne("DynamoLeagueBlazor.Server.Models.Team", "Team")
+ .WithMany("Players")
+ .HasForeignKey("TeamId");
+
+ b.Navigation("Team");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
+ {
+ b.HasOne("DynamoLeagueBlazor.Server.Infrastructure.Identity.ApplicationRole", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.HasOne("DynamoLeagueBlazor.Server.Infrastructure.Identity.ApplicationUser", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.HasOne("DynamoLeagueBlazor.Server.Infrastructure.Identity.ApplicationUser", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
+ {
+ b.HasOne("DynamoLeagueBlazor.Server.Infrastructure.Identity.ApplicationRole", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DynamoLeagueBlazor.Server.Infrastructure.Identity.ApplicationUser", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
+ {
+ b.HasOne("DynamoLeagueBlazor.Server.Infrastructure.Identity.ApplicationUser", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("DynamoLeagueBlazor.Server.Models.Player", b =>
+ {
+ b.Navigation("Bids");
+
+ b.Navigation("Fines");
+ });
+
+ modelBuilder.Entity("DynamoLeagueBlazor.Server.Models.Team", b =>
+ {
+ b.Navigation("Fines");
+
+ b.Navigation("Players");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/Server/Infrastructure/Migrations/20230302013711_ChangeToDateTimeOffset.cs b/src/Server/Infrastructure/Migrations/20230302013711_ChangeToDateTimeOffset.cs
new file mode 100644
index 0000000..90fc46c
--- /dev/null
+++ b/src/Server/Infrastructure/Migrations/20230302013711_ChangeToDateTimeOffset.cs
@@ -0,0 +1,68 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace DynamoLeagueBlazor.Server.Infrastructure.Migrations
+{
+ ///
+ public partial class ChangeToDateTimeOffset : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AlterColumn(
+ name: "EndOfFreeAgency",
+ table: "Players",
+ type: "datetimeoffset",
+ nullable: true,
+ oldClrType: typeof(DateTime),
+ oldType: "datetime2",
+ oldNullable: true);
+
+ migrationBuilder.AlterColumn(
+ name: "CreatedOn",
+ table: "Fines",
+ type: "datetimeoffset",
+ nullable: false,
+ oldClrType: typeof(DateTime),
+ oldType: "datetime2");
+
+ migrationBuilder.AlterColumn(
+ name: "CreatedOn",
+ table: "Bids",
+ type: "datetimeoffset",
+ nullable: false,
+ oldClrType: typeof(DateTime),
+ oldType: "datetime2");
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AlterColumn(
+ name: "EndOfFreeAgency",
+ table: "Players",
+ type: "datetime2",
+ nullable: true,
+ oldClrType: typeof(DateTimeOffset),
+ oldType: "datetimeoffset",
+ oldNullable: true);
+
+ migrationBuilder.AlterColumn(
+ name: "CreatedOn",
+ table: "Fines",
+ type: "datetime2",
+ nullable: false,
+ oldClrType: typeof(DateTimeOffset),
+ oldType: "datetimeoffset");
+
+ migrationBuilder.AlterColumn(
+ name: "CreatedOn",
+ table: "Bids",
+ type: "datetime2",
+ nullable: false,
+ oldClrType: typeof(DateTimeOffset),
+ oldType: "datetimeoffset");
+ }
+ }
+}
diff --git a/src/Server/Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs b/src/Server/Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs
index eab536f..a14a260 100644
--- a/src/Server/Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs
+++ b/src/Server/Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs
@@ -17,10 +17,10 @@ protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
- .HasAnnotation("ProductVersion", "6.0.8")
+ .HasAnnotation("ProductVersion", "7.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
- SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("Duende.IdentityServer.EntityFramework.Entities.DeviceFlowCodes", b =>
{
@@ -105,7 +105,7 @@ protected override void BuildModel(ModelBuilder modelBuilder)
b.HasIndex("Use");
- b.ToTable("Keys");
+ b.ToTable("Keys", (string)null);
});
modelBuilder.Entity("Duende.IdentityServer.EntityFramework.Entities.PersistedGrant", b =>
@@ -269,13 +269,13 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.ValueGeneratedOnAdd()
.HasColumnType("int");
- SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
b.Property("Amount")
.HasColumnType("int");
- b.Property("CreatedOn")
- .HasColumnType("datetime2");
+ b.Property("CreatedOn")
+ .HasColumnType("datetimeoffset");
b.Property("IsOverBid")
.HasColumnType("bit");
@@ -304,13 +304,13 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.ValueGeneratedOnAdd()
.HasColumnType("int");
- SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
b.Property("Amount")
.HasColumnType("decimal(18,0)");
- b.Property("CreatedOn")
- .HasColumnType("datetime2");
+ b.Property("CreatedOn")
+ .HasColumnType("datetimeoffset");
b.Property("PlayerId")
.HasColumnType("int");
@@ -340,13 +340,13 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.ValueGeneratedOnAdd()
.HasColumnType("int");
- SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
b.Property("ContractValue")
.HasColumnType("int");
- b.Property("EndOfFreeAgency")
- .HasColumnType("datetime2");
+ b.Property("EndOfFreeAgency")
+ .HasColumnType("datetimeoffset");
b.Property("HeadShotUrl")
.HasColumnType("nvarchar(max)");
@@ -384,7 +384,7 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.ValueGeneratedOnAdd()
.HasColumnType("int");
- SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
b.Property("LogoUrl")
.IsRequired()
@@ -405,7 +405,7 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.ValueGeneratedOnAdd()
.HasColumnType("int");
- SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
b.Property("ClaimType")
.HasColumnType("nvarchar(max)");
@@ -430,7 +430,7 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.ValueGeneratedOnAdd()
.HasColumnType("int");
- SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
b.Property("ClaimType")
.HasColumnType("nvarchar(max)");
diff --git a/src/Server/Infrastructure/MsSqlContainerFactory.cs b/src/Server/Infrastructure/MsSqlContainerFactory.cs
index 26b53f7..95526e7 100644
--- a/src/Server/Infrastructure/MsSqlContainerFactory.cs
+++ b/src/Server/Infrastructure/MsSqlContainerFactory.cs
@@ -19,10 +19,6 @@ public static async Task CreateAsync()
Password = "yourStrong!Password123"
})
.WithImage("mcr.microsoft.com/mssql/server:2019-latest")
- .WithCreateContainerParametersModifier(parameters =>
- {
- parameters.Env.Add("TZ=America/Chicago"); // TODO: All dates and comparisons should be UTC. Some tests fail because they use DateTime.Now in production or in the test.
- })
.Build();
await _msSqlTestContainer.StartAsync();
diff --git a/src/Server/Infrastructure/SeedDataCommand.cs b/src/Server/Infrastructure/SeedDataCommand.cs
index 13c541e..1bd5cd5 100644
--- a/src/Server/Infrastructure/SeedDataCommand.cs
+++ b/src/Server/Infrastructure/SeedDataCommand.cs
@@ -94,11 +94,11 @@ private async Task SeedApplicationDataAsync(CancellationToken cancellationToken)
if (i % 2 == 0)
{
- player.SignForCurrentTeam(DateTime.Today.AddYears(1).Year, i);
+ player.SignForCurrentTeam(DateTimeOffset.UtcNow.AddYears(1).Year, i);
if (i % 4 == 0)
{
- player.BeginNewSeason(DateTime.Today.AddYears(1));
+ player.BeginNewSeason(DateTimeOffset.UtcNow.AddYears(1));
}
if (i % 8 == 0)
diff --git a/src/Server/Models/Bid.cs b/src/Server/Models/Bid.cs
index 8f8d5f4..661c927 100644
--- a/src/Server/Models/Bid.cs
+++ b/src/Server/Models/Bid.cs
@@ -8,8 +8,8 @@ public record Bid : BaseEntity
public required int PlayerId { get; init; }
public required int TeamId { get; init; }
public bool IsOverBid { get; set; }
- public DateTime CreatedOn { get; private set; } = DateTime.Now;
- public DateTimeOffset UpdatedOn { get; set; } = DateTimeOffset.Now;
+ public DateTimeOffset CreatedOn { get; private set; } = DateTimeOffset.UtcNow;
+ public DateTimeOffset UpdatedOn { get; set; } = DateTimeOffset.UtcNow;
public Team Team { get; private set; } = null!;
public Player Player { get; private set; } = null!;
}
diff --git a/src/Server/Models/Fine.cs b/src/Server/Models/Fine.cs
index ba3bba4..97a1418 100644
--- a/src/Server/Models/Fine.cs
+++ b/src/Server/Models/Fine.cs
@@ -7,7 +7,7 @@ public record Fine : BaseEntity
[Column(TypeName = "decimal(18,0)")]
public required decimal Amount { get; set; }
public bool Status { get; set; }
- public DateTime CreatedOn { get; set; } = DateTime.Now;
+ public DateTimeOffset CreatedOn { get; set; } = DateTimeOffset.UtcNow;
public required string Reason { get; set; }
public required int TeamId { get; set; }
public int? PlayerId { get; set; }
diff --git a/src/Server/Models/Player.cs b/src/Server/Models/Player.cs
index 7825cd8..a634fb8 100644
--- a/src/Server/Models/Player.cs
+++ b/src/Server/Models/Player.cs
@@ -6,7 +6,7 @@ public record Player : BaseEntity
{
private readonly StateMachine _machine;
private readonly StateMachine.TriggerWithParameters _rosteredTrigger;
- private readonly StateMachine.TriggerWithParameters _freeAgentTrigger;
+ private readonly StateMachine.TriggerWithParameters _freeAgentTrigger;
public Player()
{
@@ -19,11 +19,11 @@ public Player()
_rosteredTrigger = _machine.SetTriggerParameters(PlayerStateTrigger.SignedByTeam);
_machine.Configure(PlayerState.Rostered)
- .OnEntryFrom(_rosteredTrigger, (yearContractExpires, contractValue) => SetToRostered(yearContractExpires, contractValue))
+ .OnEntryFrom(_rosteredTrigger, SetToRostered)
.Permit(PlayerStateTrigger.UnrosteredByTeam, PlayerState.Unrostered)
.Permit(PlayerStateTrigger.NewSeasonStarted, PlayerState.FreeAgent);
- _freeAgentTrigger = _machine.SetTriggerParameters(PlayerStateTrigger.NewSeasonStarted);
+ _freeAgentTrigger = _machine.SetTriggerParameters(PlayerStateTrigger.NewSeasonStarted);
_machine.Configure(PlayerState.FreeAgent)
.OnEntryFrom(_freeAgentTrigger, (endOfFreeAgency) => EndOfFreeAgency = endOfFreeAgency)
.Permit(PlayerStateTrigger.BiddingEnded, PlayerState.OfferMatching);
@@ -40,7 +40,7 @@ public Player()
public int ContractValue { get; set; }
public int YearAcquired { get; set; }
public int? TeamId { get; set; }
- public DateTime? EndOfFreeAgency { get; set; }
+ public DateTimeOffset? EndOfFreeAgency { get; set; }
public PlayerState State { get; set; } = PlayerState.Unsigned;
public Team Team { get; private set; } = null!;
@@ -83,7 +83,7 @@ private void SetToRostered(int yearContractExpires, int contractValue)
EndOfFreeAgency = null;
}
- public void BeginNewSeason(DateTime endOfFreeAgency) => _machine.Fire(_freeAgentTrigger, endOfFreeAgency);
+ public void BeginNewSeason(DateTimeOffset endOfFreeAgency) => _machine.Fire(_freeAgentTrigger, endOfFreeAgency);
// TODO: Refactor this into an event so its easier to understand each individual piece.
public void AddBid(int amount, int teamIdOfBidder)
@@ -119,7 +119,7 @@ public void AddBid(int amount, int teamIdOfBidder)
if (shouldUpdateOverBid)
{
currentHighestBid!.Amount = amount;
- currentHighestBid.UpdatedOn = DateTimeOffset.Now;
+ currentHighestBid.UpdatedOn = DateTimeOffset.UtcNow;
}
else if (!isBidByTheSameTeam && currentHighestBid != null)
{
@@ -142,7 +142,7 @@ void AddCounterBid(Bid currentHighestBid)
else if (currentHighestBid!.Amount == amount)
{
currentHighestBid.IsOverBid = false;
- currentHighestBid.UpdatedOn = DateTimeOffset.Now;
+ currentHighestBid.UpdatedOn = DateTimeOffset.UtcNow;
}
}
@@ -157,11 +157,11 @@ bool IsEligibleForFreeAgencyExtension()
{
if (isBidByTheSameTeam) return false;
- var maxFreeAgencyExtensionDate = new DateTime(DateTime.Now.Year, 8, 28);
+ var maxFreeAgencyExtensionDate = new DateTimeOffset(DateTimeOffset.UtcNow.Year, 8, 28, 0, 0, 0, TimeSpan.Zero);
var isBeforeMaximumExtensionDate = EndOfFreeAgency < maxFreeAgencyExtensionDate;
const int maxFreeAgencyExtensionDays = 3;
- var isBeforeMaximumExtensionDays = EndOfFreeAgency < DateTime.Now.AddDays(maxFreeAgencyExtensionDays);
+ var isBeforeMaximumExtensionDays = EndOfFreeAgency < DateTimeOffset.UtcNow.AddDays(maxFreeAgencyExtensionDays);
return isBeforeMaximumExtensionDate && isBeforeMaximumExtensionDays;
}
@@ -189,5 +189,5 @@ public Fine AddFine(decimal amount, string reason)
public int GetHighestBidAmount() => Bids.Any(b => b.IsOverBid == false) ? Bids.Where(b => b.IsOverBid == false).FindHighestBid()!.Amount : Bid.MinimumAmount;
public string GetOfferingTeam() => Bids.Any() ? Bids.FindHighestBid()!.Team.Name : string.Empty;
- public TimeSpan GetRemainingFreeAgencyTime() => EndOfFreeAgency!.Value.AddDays(3) - DateTime.Now;
+ public TimeSpan GetRemainingFreeAgencyTime() => EndOfFreeAgency!.Value.AddDays(3) - DateTimeOffset.UtcNow;
}
diff --git a/src/Server/Program.cs b/src/Server/Program.cs
index 26aa6db..fe0fc60 100644
--- a/src/Server/Program.cs
+++ b/src/Server/Program.cs
@@ -141,9 +141,9 @@
app.Services.UseScheduler(scheduler =>
{
- var centralStandardTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
+ // All bidding closes at 10PM CST.
+ var centralStandardTimeZone = TimeZoneInfo.FindSystemTimeZoneById("America/Chicago");
- // Hosting provider is in pacific time.
scheduler.Schedule()
.DailyAtHour(22)
.Zoned(centralStandardTimeZone)
@@ -155,7 +155,7 @@
.RunOnceAtStart();
}).OnError((ex) =>
{
- Log.Logger.Error(ex, "An exception occured when trying to run a scheduled job.");
+ Log.Error(ex, "An exception occured when trying to run a scheduled job.");
});
}
diff --git a/src/Shared/Features/FreeAgents/Detail/Detail.cs b/src/Shared/Features/FreeAgents/Detail/Detail.cs
index 026eede..a81f28c 100644
--- a/src/Shared/Features/FreeAgents/Detail/Detail.cs
+++ b/src/Shared/Features/FreeAgents/Detail/Detail.cs
@@ -6,7 +6,7 @@ public class FreeAgentDetailResult
public required string Position { get; set; }
public required string HeadShotUrl { get; set; }
public required string Team { get; set; }
- public DateTime EndOfFreeAgency { get; set; }
+ public DateTimeOffset EndOfFreeAgency { get; set; }
public BidItem? OverBid { get; set; }
diff --git a/src/Shared/Features/FreeAgents/List.cs b/src/Shared/Features/FreeAgents/List.cs
index d4f1024..9f7ad7e 100644
--- a/src/Shared/Features/FreeAgents/List.cs
+++ b/src/Shared/Features/FreeAgents/List.cs
@@ -11,7 +11,7 @@ public class FreeAgentItem
public string Position { get; set; } = null!;
public string Team { get; set; } = null!;
public string HeadShotUrl { get; set; } = null!;
- public DateTime BiddingEnds { get; set; }
+ public DateTimeOffset BiddingEnds { get; set; }
public int HighestBid { get; set; }
public bool CurrentUserIsHighestBidder { get; set; }
public string? WinningTeam { get; set; }
diff --git a/src/Tests/Features/Admin/StartSeasonTests.cs b/src/Tests/Features/Admin/StartSeasonTests.cs
index d72b440..5e4b8ce 100644
--- a/src/Tests/Features/Admin/StartSeasonTests.cs
+++ b/src/Tests/Features/Admin/StartSeasonTests.cs
@@ -35,7 +35,7 @@ public async Task GivenAuthenticatedAdmin_WhenAPlayerIsAFreeAgent_ThenReturnsTru
var application = GetAdminAuthenticatedApplication();
var mockPlayer = CreateFakePlayer();
mockPlayer.State = PlayerState.Rostered;
- mockPlayer.BeginNewSeason(DateTime.MaxValue);
+ mockPlayer.BeginNewSeason(DateTimeOffset.MaxValue);
await AddAsync(mockPlayer);
var client = application.CreateClient();
@@ -71,7 +71,7 @@ public async Task GivenAuthenticatedAdmin_WhenAFineExistsBeforeJanuary1stOfTheCu
await AddAsync(mockPlayer);
var mockFine = mockPlayer.AddFine(int.MaxValue, RandomString);
- mockFine.CreatedOn = DateTime.MinValue;
+ mockFine.CreatedOn = DateTimeOffset.MinValue;
await UpdateAsync(mockPlayer);
var client = application.CreateClient();
@@ -98,7 +98,7 @@ public async Task GivenAuthenticatedAdmin_WhenAFineExistsOnOrAfterJanuary1stOfTh
await AddAsync(mockPlayer);
var mockFine = mockPlayer.AddFine(int.MaxValue, RandomString);
- mockFine.CreatedOn = new DateTime(DateTime.Today.Year, 1, 1);
+ mockFine.CreatedOn = new DateTimeOffset(DateTimeOffset.UtcNow.Year, 1, 1, 0, 0, 0, TimeSpan.Zero);
await UpdateAsync(mockPlayer);
var client = application.CreateClient();
diff --git a/src/Tests/Features/FreeAgents/Detail/AddBidTests.cs b/src/Tests/Features/FreeAgents/Detail/AddBidTests.cs
index d4025cb..464c498 100644
--- a/src/Tests/Features/FreeAgents/Detail/AddBidTests.cs
+++ b/src/Tests/Features/FreeAgents/Detail/AddBidTests.cs
@@ -69,7 +69,7 @@ public async Task GivenAnyAuthenticatedUser_WhenHasNotEnded_ThenReturnsTrue()
var client = application.CreateClient();
var mockPlayer = CreateFakePlayer();
- mockPlayer.EndOfFreeAgency = DateTime.Now.AddSeconds(1);
+ mockPlayer.EndOfFreeAgency = DateTimeOffset.UtcNow.AddSeconds(1);
await AddAsync(mockPlayer);
var request = CreateFakeValidRequest();
request.PlayerId = mockPlayer.Id;
@@ -86,7 +86,7 @@ public async Task GivenAnyAuthenticatedUser_WhenHasEnded_ThenReturnsFalse()
var client = application.CreateClient();
var mockPlayer = CreateFakePlayer();
- mockPlayer.EndOfFreeAgency = DateTime.Now.AddSeconds(-1);
+ mockPlayer.EndOfFreeAgency = DateTimeOffset.UtcNow.AddSeconds(-1);
await AddAsync(mockPlayer);
var request = CreateFakeValidRequest();
request.PlayerId = mockPlayer.Id;
@@ -114,7 +114,7 @@ public async Task POST_GivenAnyAuthenticatedUser_WhenIsHighestBid_ThenSavesTheBi
await AddAsync(mockTeam);
var mockPlayer = CreateFakePlayer();
- mockPlayer.EndOfFreeAgency = DateTime.Now.AddDays(1);
+ mockPlayer.EndOfFreeAgency = DateTimeOffset.UtcNow.AddDays(1);
await AddAsync(mockPlayer);
var request = CreateFakeValidRequest();
@@ -133,7 +133,7 @@ public async Task POST_GivenAnyAuthenticatedUser_WhenIsHighestBid_ThenSavesTheBi
bid!.Amount.Should().Be(request.Amount);
bid.PlayerId.Should().Be(request.PlayerId);
bid.TeamId.Should().Be(mockTeam.Id);
- bid.CreatedOn.Should().BeCloseTo(DateTime.Now, TimeSpan.FromSeconds(5));
+ bid.CreatedOn.Should().BeCloseTo(DateTimeOffset.UtcNow, TimeSpan.FromSeconds(5));
}
[Fact]
@@ -143,7 +143,7 @@ public async Task POST_GivenAnyAuthenticatedUser_WhenIsHighestPublicBid_ButThere
await AddAsync(originalTeam);
var mockPlayer = CreateFakePlayer();
- mockPlayer.EndOfFreeAgency = DateTime.Now.AddDays(1);
+ mockPlayer.EndOfFreeAgency = DateTimeOffset.UtcNow.AddDays(1);
await AddAsync(mockPlayer);
const int privateBidAmount = 2;
@@ -233,7 +233,7 @@ public async Task GivenAPlayerEndOfFreeAgencyOfNow_WhenItIsNow_ThenIsNotValid()
var stubTeam = CreateFakeTeam();
await AddAsync(stubTeam);
var mockPlayer = CreateFakePlayer();
- mockPlayer.EndOfFreeAgency = DateTime.Now;
+ mockPlayer.EndOfFreeAgency = DateTimeOffset.UtcNow;
await AddAsync(mockPlayer);
var request = new AddBidRequest { PlayerId = mockPlayer.Id, Amount = int.MaxValue };
@@ -249,7 +249,7 @@ public async Task GivenAPlayerEndOfFreeAgencyOfNowPlusOneSecond_WhenItIsNow_Then
var stubTeam = CreateFakeTeam();
await AddAsync(stubTeam);
var mockPlayer = CreateFakePlayer();
- mockPlayer.EndOfFreeAgency = DateTime.Now.AddSeconds(1);
+ mockPlayer.EndOfFreeAgency = DateTimeOffset.UtcNow.AddSeconds(1);
await AddAsync(mockPlayer);
var request = new AddBidRequest { PlayerId = mockPlayer.Id, Amount = int.MaxValue };
diff --git a/src/Tests/Features/FreeAgents/Detail/BidCountdownTests.cs b/src/Tests/Features/FreeAgents/Detail/BidCountdownTests.cs
index 7ed7277..c89516a 100644
--- a/src/Tests/Features/FreeAgents/Detail/BidCountdownTests.cs
+++ b/src/Tests/Features/FreeAgents/Detail/BidCountdownTests.cs
@@ -9,7 +9,7 @@ public void CountsDownEverySecondUntilZero()
{
var cut = RenderComponent(parameters =>
{
- parameters.Add(p => p.DateTime, DateTime.Now.AddSeconds(2));
+ parameters.Add(p => p.DateTime, DateTimeOffset.UtcNow.AddSeconds(2));
});
cut.WaitForState(() => cut.Markup.Contains("0 seconds"), TimeSpan.FromSeconds(5));
@@ -20,7 +20,7 @@ public void GivenLessThanADayAway_ThenShowsRedText()
{
var cut = RenderComponent(parameters =>
{
- parameters.Add(p => p.DateTime, DateTime.Now.AddSeconds(1));
+ parameters.Add(p => p.DateTime, DateTimeOffset.UtcNow.AddSeconds(1));
});
cut.Markup.Contains("mud-text-error");
@@ -31,7 +31,7 @@ public void GivenMoreThanADayAway_ThenShowsYellowText()
{
var cut = RenderComponent(parameters =>
{
- parameters.Add(p => p.DateTime, DateTime.Now.AddDays(1));
+ parameters.Add(p => p.DateTime, DateTimeOffset.UtcNow.AddDays(1));
});
cut.Markup.Contains("mud-text-warning");
diff --git a/src/Tests/Features/FreeAgents/Detail/DetailTests.cs b/src/Tests/Features/FreeAgents/Detail/DetailTests.cs
index a30634e..4a6a6e8 100644
--- a/src/Tests/Features/FreeAgents/Detail/DetailTests.cs
+++ b/src/Tests/Features/FreeAgents/Detail/DetailTests.cs
@@ -51,7 +51,7 @@ public async Task GivenAnyAuthenticatedUser_WhenGivenValidPlayerId_ThenReturnsEx
var bid = response.Bids.First();
bid.Team.Should().Be(mockTeam.Name);
bid.Amount.Should().Be(Bid.MinimumAmount);
- DateTime.Parse(bid.CreatedOn).Should().BeExactly(TimeSpan.FromSeconds(0));
+ DateTimeOffset.Parse(bid.CreatedOn).Should().BeExactly(TimeSpan.FromSeconds(0));
}
}
diff --git a/src/Tests/Features/FreeAgents/EndBiddingTests.cs b/src/Tests/Features/FreeAgents/EndBiddingTests.cs
index 5bfa13f..c602445 100644
--- a/src/Tests/Features/FreeAgents/EndBiddingTests.cs
+++ b/src/Tests/Features/FreeAgents/EndBiddingTests.cs
@@ -24,7 +24,7 @@ public async Task GivenAPlayerWhoIsAFreeAgentAndEndFreeAgencyIsNowOrBeforeNow_Th
{
var mockPlayer = CreateFakePlayer();
mockPlayer.State = PlayerState.FreeAgent;
- mockPlayer.EndOfFreeAgency = DateTime.Now.AddDays(-1);
+ mockPlayer.EndOfFreeAgency = DateTimeOffset.UtcNow.AddDays(-1);
await AddAsync(mockPlayer);
var sut = GetRequiredService();
diff --git a/src/Tests/Features/FreeAgents/ListTests.cs b/src/Tests/Features/FreeAgents/ListTests.cs
index 556a623..a74f25b 100644
--- a/src/Tests/Features/FreeAgents/ListTests.cs
+++ b/src/Tests/Features/FreeAgents/ListTests.cs
@@ -37,8 +37,8 @@ public async Task GivenAnyAuthenticatedUser_WhenThereIsOnePlayerWhoIsAFreeAgent_
var mockPlayer = CreateFakePlayer();
mockPlayer.TeamId = mockTeam.Id;
- mockPlayer.SignForCurrentTeam(DateTime.MinValue.Year, int.MaxValue);
- var biddingEnds = DateTime.MaxValue;
+ mockPlayer.SignForCurrentTeam(DateTimeOffset.MinValue.Year, int.MaxValue);
+ var biddingEnds = DateTimeOffset.MaxValue;
mockPlayer.BeginNewSeason(biddingEnds);
await AddAsync(mockPlayer);
@@ -74,8 +74,8 @@ public async Task GivenAnyAuthenticatedUser_WhenAFreeAgentHasABidByAnotherTeam_T
var mockPlayer = CreateFakePlayer();
mockPlayer.TeamId = mockTeam.Id;
- mockPlayer.SignForCurrentTeam(DateTime.MinValue.Year, int.MaxValue);
- var biddingEnds = DateTime.MaxValue;
+ mockPlayer.SignForCurrentTeam(DateTimeOffset.MinValue.Year, int.MaxValue);
+ var biddingEnds = DateTimeOffset.MaxValue;
mockPlayer.BeginNewSeason(biddingEnds);
await AddAsync(mockPlayer);
diff --git a/src/Tests/Features/OfferMatching/ExpireOfferMatchingTests.cs b/src/Tests/Features/OfferMatching/ExpireOfferMatchingTests.cs
index 00313c1..9202dd0 100644
--- a/src/Tests/Features/OfferMatching/ExpireOfferMatchingTests.cs
+++ b/src/Tests/Features/OfferMatching/ExpireOfferMatchingTests.cs
@@ -23,7 +23,7 @@ public async Task GivenAnNonOfferMatchingPlayer_ThenDoesNothing()
public async Task GivenAnOfferMatchingPlayer_WhenTodayIsTwoDaysOrLessAfterEndOfFreeAgency_ThenDoesNothing(int daysAgo)
{
var mockPlayer = CreateFakePlayer();
- mockPlayer.EndOfFreeAgency = DateTime.Today.AddDays(daysAgo);
+ mockPlayer.EndOfFreeAgency = DateTimeOffset.UtcNow.AddDays(daysAgo);
mockPlayer.State = PlayerState.OfferMatching;
await AddAsync(mockPlayer);
@@ -44,7 +44,7 @@ public async Task GivenAnOfferMatchingPlayerWithBids_WhenTodayIsThreeDaysOrMoreA
var mockPlayer = CreateFakePlayer();
mockPlayer.State = PlayerState.OfferMatching;
mockPlayer.AddBid(Bid.MinimumAmount, biddingTeam.Id);
- mockPlayer.EndOfFreeAgency = DateTime.Today.AddDays(-3);
+ mockPlayer.EndOfFreeAgency = DateTimeOffset.UtcNow.AddDays(-3);
await AddAsync(mockPlayer);
var sut = GetRequiredService();
@@ -61,7 +61,7 @@ public async Task GivenAnOfferMatchingPlayerWithBids_WhenTodayIsThreeDaysOrMoreA
public async Task GivenAnOfferMatchingPlayerWithoutBids_WhenTodayIsThreeDaysOrMoreAfterEndOfFreeAgency_ThenIsRemovedFromTheLeague()
{
var mockPlayer = CreateFakePlayer();
- mockPlayer.EndOfFreeAgency = DateTime.Today.AddDays(-3);
+ mockPlayer.EndOfFreeAgency = DateTimeOffset.UtcNow.AddDays(-3);
mockPlayer.State = PlayerState.OfferMatching;
await AddAsync(mockPlayer);
diff --git a/src/Tests/Features/OfferMatching/MatchPlayerTests.cs b/src/Tests/Features/OfferMatching/MatchPlayerTests.cs
index 00fc245..0f7f10a 100644
--- a/src/Tests/Features/OfferMatching/MatchPlayerTests.cs
+++ b/src/Tests/Features/OfferMatching/MatchPlayerTests.cs
@@ -17,7 +17,7 @@ public async Task GivenAnyAuthenticatedUser_WhenPlayerIsMatchedAndHasBids_ThenPl
mockPlayer.TeamId = matchingTeam.Id;
mockPlayer.State = PlayerState.OfferMatching;
mockPlayer.AddBid(Bid.MinimumAmount, biddingTeam.Id);
- mockPlayer.EndOfFreeAgency = DateTime.Today.AddDays(-3);
+ mockPlayer.EndOfFreeAgency = DateTimeOffset.UtcNow.AddDays(-3);
await AddAsync(mockPlayer);
var request = new MatchPlayerRequest(mockPlayer.Id);
@@ -31,7 +31,7 @@ public async Task GivenAnyAuthenticatedUser_WhenPlayerIsMatchedAndHasBids_ThenPl
var unsignedPlayer = await FirstOrDefaultAsync();
unsignedPlayer!.YearContractExpires.Should().Be(null);
unsignedPlayer.EndOfFreeAgency.Should().Be(null);
- unsignedPlayer.YearAcquired.Should().Be(DateTime.Today.Year);
+ unsignedPlayer.YearAcquired.Should().Be(DateTimeOffset.UtcNow.Year);
unsignedPlayer.ContractValue.Should().Be(Bid.MinimumAmount);
unsignedPlayer.State.Should().Be(PlayerState.Unsigned);
unsignedPlayer.TeamId.Should().Be(matchingTeam.Id);
diff --git a/src/Tests/Features/Teams/DetailTests.cs b/src/Tests/Features/Teams/DetailTests.cs
index 7d716df..c6426f9 100644
--- a/src/Tests/Features/Teams/DetailTests.cs
+++ b/src/Tests/Features/Teams/DetailTests.cs
@@ -30,7 +30,7 @@ public async Task GivenAnyAuthenticatedUser_WhenGivenValidTeamId_ThenReturnsExpe
var mockRosteredPlayer = CreateFakePlayer();
mockRosteredPlayer.TeamId = stubTeam.Id;
- mockRosteredPlayer.SignForCurrentTeam(DateTime.MaxValue.Year, 1);
+ mockRosteredPlayer.SignForCurrentTeam(DateTimeOffset.MaxValue.Year, 1);
mockRosteredPlayer.State = PlayerState.Rostered;
await AddAsync(mockRosteredPlayer);
@@ -52,7 +52,7 @@ public async Task GivenAnyAuthenticatedUser_WhenGivenValidTeamId_ThenReturnsExpe
response.Should().NotBeNull();
response!.Name.Should().Be(stubTeam.Name);
var expectedCapSpace = CapSpaceUtilities.GetRemainingCapSpace(
- DateOnly.FromDateTime(DateTime.Today),
+ DateOnly.FromDateTime(DateTimeOffset.UtcNow.DateTime),
mockRosteredPlayer.ContractValue,
mockUnrosteredPlayer.ContractValue,
mockUnsignedPlayer.ContractValue).ToString("C0");
diff --git a/src/Tests/Features/Teams/SignPlayerTests.cs b/src/Tests/Features/Teams/SignPlayerTests.cs
index b5556e9..7fbd36f 100644
--- a/src/Tests/Features/Teams/SignPlayerTests.cs
+++ b/src/Tests/Features/Teams/SignPlayerTests.cs
@@ -32,7 +32,7 @@ public async Task GivenAuthenticatedUser_ThenSignsPlayer()
var application = GetUserAuthenticatedApplication();
var player = CreateFakePlayer();
player.Position = Position.QuarterBack.Name;
- player.YearContractExpires = DateTime.Now.Year;
+ player.YearContractExpires = DateTimeOffset.UtcNow.Year;
await AddAsync(player);
var request = CreateFakeValidRequest();
request.YearContractExpires = (int)player.YearContractExpires;
diff --git a/src/Tests/Models/PlayerTests.cs b/src/Tests/Models/PlayerTests.cs
index 0dbf7a1..b60fe80 100644
--- a/src/Tests/Models/PlayerTests.cs
+++ b/src/Tests/Models/PlayerTests.cs
@@ -194,7 +194,7 @@ public void GivenAnRosteredPlayer_WhenANewSeasonStarts_ThenMovesToFreeAgent()
var rosteredPlayer = CreateFakePlayer();
rosteredPlayer.State = PlayerState.Rostered;
- rosteredPlayer.BeginNewSeason(DateTime.MaxValue);
+ rosteredPlayer.BeginNewSeason(DateTimeOffset.MaxValue);
rosteredPlayer.State.Should().Be(PlayerState.FreeAgent);
}
@@ -208,7 +208,7 @@ public void GivenABrandNewPlayer_ThenCanGoThroughTheCompleteLifecycle()
FluentActions.Invoking(() =>
{
player.SignForCurrentTeam(int.MaxValue, int.MaxValue);
- player.BeginNewSeason(DateTime.MaxValue);
+ player.BeginNewSeason(DateTimeOffset.MaxValue);
player.EndBidding();
player.MatchOffer();
}).Should().NotThrow();