无法在Razor页面使用Hangfire API的HTML Helper显示相对时间
解决Hangfire.Dashboard RelativeTime API无法调用的问题
我之前也碰到过类似的困扰——Hangfire.Dashboard里的RelativeTime类其实是内部类型(internal修饰),哪怕你引入了对应的命名空间,外部项目也没法直接访问它,这就是你调用报错的核心原因。下面给你两个靠谱的解决方案:
方案1:复制Hangfire的RelativeTime逻辑到自己项目(推荐)
Hangfire是开源项目,它的相对时间转换逻辑很清晰,你可以直接把核心代码复制过来,自己维护,完全不依赖内部API。这里给你一个简化后的实现版本:
public static class CustomRelativeTime { public static string ToRelativeString(DateTimeOffset dateTime) { var now = DateTimeOffset.UtcNow; var timeSpan = now - dateTime; // 按时间跨度从大到小判断 if (timeSpan.TotalDays >= 365) return $"about {Math.Floor(timeSpan.TotalDays / 365)} year{(timeSpan.TotalDays >= 730 ? "s" : "")} ago"; if (timeSpan.TotalDays >= 30) return $"about {Math.Floor(timeSpan.TotalDays / 30)} month{(timeSpan.TotalDays >= 60 ? "s" : "")} ago"; if (timeSpan.TotalDays >= 7) return $"about {Math.Floor(timeSpan.TotalDays / 7)} week{(timeSpan.TotalDays >= 14 ? "s" : "")} ago"; if (timeSpan.TotalDays >= 1) return $"{timeSpan.Days} day{(timeSpan.Days > 1 ? "s" : "")} ago"; if (timeSpan.TotalHours >= 1) return $"{timeSpan.Hours} hour{(timeSpan.Hours > 1 ? "s" : "")} ago"; if (timeSpan.TotalMinutes >= 1) return $"{timeSpan.Minutes} minute{(timeSpan.Minutes > 1 ? "s" : "")} ago"; if (timeSpan.TotalSeconds >= 5) return $"{timeSpan.Seconds} second{(timeSpan.Seconds > 1 ? "s" : "")} ago"; return "just now"; } }
使用时只需要把你的DateTime转成DateTimeOffset传入即可:
var targetTime = DateTime.Parse("2018-04-16 20:59:41.870"); var relativeText = CustomRelativeTime.ToRelativeString(new DateTimeOffset(targetTime));
如果你的时间是本地时区,记得在转换DateTimeOffset时指定正确的时区,避免计算误差。
方案2:通过反射调用Hangfire的内部RelativeTime(不推荐)
这种方式能直接调用Hangfire的实现,但缺点是不稳定——一旦Hangfire升级修改了RelativeTime的类名、方法或参数,代码就会失效。如果一定要用,可以试试这段代码:
using System.Reflection; public static string GetHangfireRelativeTime(DateTime dateTime) { var dateTimeOffset = new DateTimeOffset(dateTime); // 获取Hangfire程序集中的RelativeTime类型 var relativeTimeType = typeof(Hangfire.Dashboard.DashboardRoutes).Assembly.GetType("Hangfire.Dashboard.RelativeTime"); // 获取ToRelativeString静态方法 var toRelativeMethod = relativeTimeType.GetMethod("ToRelativeString", BindingFlags.Public | BindingFlags.Static); return (string)toRelativeMethod.Invoke(null, new object[] { dateTimeOffset }); }
最后提醒
优先选方案1,自己实现的逻辑可控性更强,也不会受Hangfire版本更新的影响。
内容的提问来源于stack exchange,提问作者I Love Stackoverflow
相关产品推荐
相关产品推荐

