-
Notifications
You must be signed in to change notification settings - Fork 176
Open
Description
有按天、按周、按月、按年分表路由,缺少按季度的分表路由,我参照做了实现,请问有错误的地方吗?
/// <summary>
/// 按季度分表的虚拟表路由
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public abstract class
AbstractSimpleShardingQuarterKeyDateTimeVirtualTableRoute<TEntity> :
AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute<TEntity>
where TEntity : class
{
/// <summary>
/// 提前创建表,补全之前的季度表
/// </summary>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
protected override List<string> CalcTailsOnStart()
{
var beginTime = GetBeginTime();
var currentQuarterStart = DateTime.Now.GetQuarterStartDate();
if (beginTime > currentQuarterStart)
throw new ArgumentException("Begin time cannot be after the current quarter start.");
var tails = new List<string>();
var current = beginTime;
while (current <= currentQuarterStart)
{
tails.Add(TimeFormatToTail(current));
current = current.GetNextQuarterStartDate(); // Move to the next quarter
}
return tails;
}
protected override string TimeFormatToTail(DateTime time)
{
return $"{time:yyyy}Q{time.GetQuarter()}";
}
public override Func<string, bool> GetRouteToFilter(DateTime shardingKey, ShardingOperatorEnum shardingOperator)
{
var t = TimeFormatToTail(shardingKey);
switch (shardingOperator)
{
case ShardingOperatorEnum.GreaterThan:
case ShardingOperatorEnum.GreaterThanOrEqual:
return tail => String.Compare(tail, t, StringComparison.Ordinal) >= 0;
case ShardingOperatorEnum.LessThan:
{
var currentQuarter = shardingKey.GetQuarterStartDate();
//处于临界值 o=>o.time < [2021-01-01 00:00:00] 尾巴20210101不应该被返回
if (currentQuarter == shardingKey)
return tail => String.Compare(tail, t, StringComparison.Ordinal) < 0;
return tail => String.Compare(tail, t, StringComparison.Ordinal) <= 0;
}
case ShardingOperatorEnum.LessThanOrEqual:
return tail => String.Compare(tail, t, StringComparison.Ordinal) <= 0;
case ShardingOperatorEnum.Equal: return tail => tail == t;
default:
{
#if DEBUG
Console.WriteLine($"shardingOperator is not equal scan all table tail");
#endif
return tail => true;
}
}
}
/// <summary>
/// 在几时执行创建对应的表
/// </summary>
/// <returns></returns>
public override string[] GetCronExpressions()
{
return
[
"0 59 23 31 3 ?", // 3月31日23:59执行
"0 59 23 30 6 ?", // 6月30日23:59执行
"0 59 23 30 9 ?", // 9月30日23:59执行
"0 59 23 31 12 ?", // 12月31日23:59执行
"0 0 0 1 1,4,7,10 ?", // 每季度的第一天0点执行
"0 1 0 1 1,4,7,10 ?" // 每季度的第一天1点执行
];
}
public override string[] GetJobCronExpressions()
{
return GetCronExpressions().Concat([
"0 0 0 1 1,4,7,10 ?" // 每季度的第一天0点执行
]).Distinct().ToArray();
}
}
public static class DateTimeExtensions
{
/// <summary>
/// 获取日期所在的季度
/// </summary>
/// <param name="date"></param>
/// <returns></returns>
public static int GetQuarter(this DateTime date)
{
return (date.Month - 1) / 3 + 1;
}
/// <summary>
/// 获取季度的开始日期
/// </summary>
/// <param name="date"></param>
/// <returns></returns>
public static DateTime GetQuarterStartDate(this DateTime date)
{
int quarter = date.GetQuarter();
int startMonth = (quarter - 1) * 3 + 1; // 季度首月(1/4/7/10月)
return new DateTime(date.Year, startMonth, 1);
}
/// <summary>
/// 获取季度的结束日期
/// </summary>
/// <param name="date"></param>
/// <returns></returns>
public static DateTime GetQuarterEndDate(this DateTime date)
{
DateTime start = date.GetQuarterStartDate();
return start.AddMonths(3).AddDays(-1); // 下一季度首日前一天
}
/// <summary>
/// 获取下一个季度的开始日期
/// </summary>
/// <param name="date"></param>
/// <returns></returns>
public static DateTime GetNextQuarterStartDate(this DateTime date)
{
// int nextQuarter = date.GetQuarter() % 4 + 1; // 下一个季度
// int startMonth = (nextQuarter - 1) * 3 + 1; // 下一个季度首月(1/4/7/10月)
// return new DateTime(date.Year + (nextQuarter == 1 ? 1 : 0), startMonth, 1);
var start = date.GetQuarterStartDate();
return start.AddMonths(3); // 下一个季度首月
}
}
Metadata
Metadata
Assignees
Labels
No labels