根据大致时间跨度计算大致日期

Posted

技术标签:

【中文标题】根据大致时间跨度计算大致日期【英文标题】:Calculate approximate date from approximate timespan 【发布时间】:2013-11-12 01:42:56 【问题描述】:

由于 Sony 改变了他们的奖杯服务器身份验证的工作方式,我正在寻找一种替代解决方案来估算奖杯日期。 UK Playstation Network 网站在未锁定的奖杯下方有一个字符串,该字符串与获得奖杯的时间大致相同。我有以下代码:

private TimeSpan ParseTimeSpan(string datestring)

    TimeSpan ts = new TimeSpan();
    datestring = datestring.Replace("Attained:", ""); // strip Attained:
    string[] parts = datestring.Split(' ');
    int numeric = int.Parse(parts[0]);
    string duration = parts[1];
    switch(duration)
    
        case "minutes":
            ts = new TimeSpan(0, numeric, 0);
            break;
        case "hours":
            ts = new TimeSpan(numeric, 0, 0);
            break;
        case "days":
            ts = new TimeSpan(numeric, 0, 0, 0);
            break;
        case "months":
            ts = new TimeSpan(numeric * 30, 0, 0);
            break;
        case "years":
            ts = new TimeSpan(numeric * 365, 0, 0);
            break;
    
    return ts;

如果我的一个奖杯下面有字符串Attained:17 months ago,它应该是当前月份减去 17 个月。如果我有字符串Attained:3 hours ago,它应该使用当前日期并减去 3 小时来近似获得日期。如果我有字符串 Attained: 5 minutes ago,它应该用当前日期减去 5 分钟来近似获得日期。

我的计划是将此代码作为 Web 服务运行并与桌面客户端一起运行。我不确定我应该返回 TimeSpan 还是直接计算日期?有更好的方法吗?并非所有月份都是 30 天,有些年份超过 365 天(闰年),因此硬编码计算不一定有效。

【问题讨论】:

【参考方案1】:

您不必担心有些月份有 30 天,有些则没有。如果您有时间跨度,您可以直接按该时间跨度递减当前日期。

TimeSpan ts = new TimeSpan(5,0,0);
var earned = DateTime.Now - ts;
Console.Write(earned);

这可以在您的服务内部或外部完成,但如果实际日期是需要的,我会在服务中执行它。

如果您以后需要增加一些灵活性,也可以添加正则表达式。

string input = "Attained:17 months ago";
string pattern = @"Attained:(?<value>[0-9]+) (?<unit>(years|months|days)) ago";
var match = Regex.Match(input, pattern);

if(match.Success)

    int value = Int32.Parse(match.Groups["value"].Value);
    string unit = match.Groups["unit"].Value;
    Console.WriteLine(value);
    Console.WriteLine(unit);

也可以将单元设为枚举

【讨论】:

【参考方案2】:

Noda Time 是一个比 .NET 基类库中提供的类型更灵活的框架,用于处理时间和日期值。其中包括 Period 类型,它表示经过的年、月、日等时间量。表示的实际经过时间是不固定的。正如您所说,有些月或数年比其他时间长,因此如果您不处理固定的时间量(而不是固定的 Duration),则使用 Period 类型。 Period 可以添加到 Noda 时间库中的各种日期/时间类型。

虽然您可以从 DateTime[Offset] 中添加和减去 TimeSpan,但如果您需要处理比小时更长的时间单位,它并不是一个非常有用的类型。考虑使用 Noda Time 进行重要的时间/日期计算。

【讨论】:

以上是关于根据大致时间跨度计算大致日期的主要内容,如果未能解决你的问题,请参考以下文章

ActionScript 3.0 + 计算两个日期之间的时间跨度?

用于根据时间戳计算时间跨度的 SQL 查询

如何通过纯函数计算仅“烧CPU”来最好地“浪费”大致指定的时间?

Java 两个日期间的天数计算

根据 BigQuery 重复记录中的字段计算聚合

Java面向对象大致梳理