Notable days improvement (global days, recent days)

This commit is contained in:
2025-12-24 23:32:14 +08:00
parent 7811545726
commit 1b45be225a
3 changed files with 193 additions and 0 deletions

View File

@@ -28,6 +28,7 @@ public class NotableDay
public Instant Date { get; set; }
public string? LocalName { get; set; }
public string? GlobalName { get; set; }
public string? LocalizableKey { get; set; }
public string? CountryCode { get; set; }
public NotableHolidayType[] Holidays { get; set; } = [];

View File

@@ -77,4 +77,52 @@ public class NotableDaysController(NotableDaysService days) : ControllerBase
}
return Ok(result);
}
[HttpGet("{regionCode}/current")]
public async Task<ActionResult<NotableDay?>> GetCurrentHoliday(string regionCode)
{
var result = await days.GetCurrentHoliday(regionCode);
if (result == null)
{
return NotFound("No holiday today");
}
return Ok(result);
}
[HttpGet("me/current")]
[Authorize]
public async Task<ActionResult<NotableDay?>> GetAccountCurrentHoliday()
{
if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized();
var region = currentUser.Region;
if (string.IsNullOrWhiteSpace(region)) region = "us";
var result = await days.GetCurrentHoliday(region);
if (result == null)
{
return NotFound("No holiday today");
}
return Ok(result);
}
[HttpGet("{regionCode}/recent")]
public async Task<ActionResult<List<NotableDay>>> GetRecentNotableDay(string regionCode)
{
var result = await days.GetCurrentAndNextHoliday(regionCode);
return Ok(result);
}
[HttpGet("me/recent")]
[Authorize]
public async Task<ActionResult<List<NotableDay>>> GetAccountRecentNotableDay()
{
if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized();
var region = currentUser.Region;
if (string.IsNullOrWhiteSpace(region)) region = "us";
var result = await days.GetCurrentAndNextHoliday(region);
return Ok(result);
}
}

View File

@@ -27,12 +27,123 @@ public class NotableDaysService(ICacheService cache)
var holidays = await holidayClient.GetHolidaysAsync(year.Value, regionCode);
var days = holidays?.Select(NotableDay.FromNagerHoliday).ToList() ?? [];
// Add global holidays that are available for all regions
var globalDays = GetGlobalHolidays(year.Value);
foreach (var globalDay in globalDays.Where(globalDay =>
!days.Any(d => d.Date.Equals(globalDay.Date) && d.GlobalName == globalDay.GlobalName)))
{
days.Add(globalDay);
}
// Cache the result for 1 day (holiday data doesn't change frequently)
await cache.SetAsync(cacheKey, days, TimeSpan.FromDays(1));
return days;
}
private static List<NotableDay> GetGlobalHolidays(int year)
{
var globalDays = new List<NotableDay>();
// Christmas Day - December 25
var christmas = new NotableDay
{
Date = Instant.FromDateTimeUtc(new DateTime(year, 12, 25, 0, 0, 0, DateTimeKind.Utc)),
LocalName = "Christmas",
GlobalName = "Christmas",
LocalizableKey = "Christmas",
CountryCode = null,
Holidays = [NotableHolidayType.Public]
};
globalDays.Add(christmas);
// New Year's Day - January 1
var newYear = new NotableDay
{
Date = Instant.FromDateTimeUtc(new DateTime(year, 1, 1, 0, 0, 0, DateTimeKind.Utc)),
LocalName = "New Year's Day",
GlobalName = "New Year's Day",
LocalizableKey = "NewYear",
CountryCode = null,
Holidays = [NotableHolidayType.Public]
};
globalDays.Add(newYear);
// Valentine's Day - February 14
var valentine = new NotableDay
{
Date = Instant.FromDateTimeUtc(new DateTime(year, 2, 14, 0, 0, 0, DateTimeKind.Utc)),
LocalName = "Valentine's Day",
GlobalName = "Valentine's Day",
LocalizableKey = "ValentineDay",
CountryCode = null,
Holidays = [NotableHolidayType.Observance]
};
globalDays.Add(valentine);
// April Fools' Day - April 1
var aprilFools = new NotableDay
{
Date = Instant.FromDateTimeUtc(new DateTime(year, 4, 1, 0, 0, 0, DateTimeKind.Utc)),
LocalName = "April Fools' Day",
GlobalName = "April Fools' Day",
LocalizableKey = "AprilFoolsDay",
CountryCode = null,
Holidays = [NotableHolidayType.Observance]
};
globalDays.Add(aprilFools);
// International Workers' Day - May 1
var workersDay = new NotableDay
{
Date = Instant.FromDateTimeUtc(new DateTime(year, 5, 1, 0, 0, 0, DateTimeKind.Utc)),
LocalName = "International Workers' Day",
GlobalName = "International Workers' Day",
LocalizableKey = "WorkersDay",
CountryCode = null,
Holidays = [NotableHolidayType.Public]
};
globalDays.Add(workersDay);
// Children's Day - June 1
var childrenDay = new NotableDay
{
Date = Instant.FromDateTimeUtc(new DateTime(year, 6, 1, 0, 0, 0, DateTimeKind.Utc)),
LocalName = "Children's Day",
GlobalName = "Children's Day",
LocalizableKey = "ChildrenDay",
CountryCode = null,
Holidays = [NotableHolidayType.Public]
};
globalDays.Add(childrenDay);
// World Environment Day - June 5
var environmentDay = new NotableDay
{
Date = Instant.FromDateTimeUtc(new DateTime(year, 6, 5, 0, 0, 0, DateTimeKind.Utc)),
LocalName = "World Environment Day",
GlobalName = "World Environment Day",
LocalizableKey = "EnvironmentDay",
CountryCode = null,
Holidays = [NotableHolidayType.Observance]
};
globalDays.Add(environmentDay);
// Halloween - October 31
var halloween = new NotableDay
{
Date = Instant.FromDateTimeUtc(new DateTime(year, 10, 31, 0, 0, 0, DateTimeKind.Utc)),
LocalName = "Halloween",
GlobalName = "Halloween",
LocalizableKey = "Halloween",
CountryCode = null,
Holidays = [NotableHolidayType.Observance]
};
globalDays.Add(halloween);
return globalDays;
}
public async Task<NotableDay?> GetNextHoliday(string regionCode)
{
var currentDate = SystemClock.Instance.GetCurrentInstant();
@@ -52,4 +163,37 @@ public class NotableDaysService(ICacheService cache)
return nextHoliday;
}
public async Task<NotableDay?> GetCurrentHoliday(string regionCode)
{
var currentDate = SystemClock.Instance.GetCurrentInstant();
var currentYear = currentDate.InUtc().Year;
var currentYearHolidays = await GetNotableDays(currentYear, regionCode);
// Find the holiday that is today
var todayHoliday = currentYearHolidays
.FirstOrDefault(day => day.Date.InUtc().Date == currentDate.InUtc().Date);
return todayHoliday;
}
public async Task<List<NotableDay>> GetCurrentAndNextHoliday(string regionCode)
{
var result = new List<NotableDay>();
var current = await GetCurrentHoliday(regionCode);
if (current != null)
{
result.Add(current);
}
var next = await GetNextHoliday(regionCode);
if (next != null && (current == null || !next.Date.Equals(current.Date)))
{
result.Add(next);
}
return result;
}
}