【问题标题】:Compare datetimes, see if one hour has passed比较日期时间,看看是否已经过了一小时
【发布时间】:2020-02-07 17:48:33
【问题描述】:

我正在尝试查看自创建令牌对象以来是否已经过去了一个小时。 我在创建它时使用 datetime.utcnow。

我尝试过 datetime.compare,并直接比较两个日期时间,但无论我做什么都会得到相同的结果..(不是我想要的)

如果创建后一小时过去了,令牌应该被“消耗”,因此它不再有效。

令牌对象

    public int ID { get; set; }

    public int UserId { get; set; }

    public string Token { get; set; }

    public System.DateTime Time_stamp { get; set; }

    public Nullable<bool> Consumed { get; set; }

我的验证方法

public bool IsValidToken(string token)
{
        var tokenEntity = this.GetAll().Where(x => x.Consumed == false && x.Token == token).FirstOrDefault();

            if (tokenEntity != null)
            {
                var tokenDate = tokenEntity.Time_stamp;

                var machineDate = DateTime.UtcNow;


                var result = DateTime.Compare(tokenDate, machineDate.AddHours(1));

                if (result > 0)
                {
                    tokenEntity.Consumed = true;
                    this.Update(tokenEntity);
                    return false;
                }
                else
                {
                    return true;
                }
            }
            return false;
        }

【问题讨论】:

  • 为什么要与 utcnow + 1hour 进行比较?您真的不想知道machineDate - tokenDate 是否大于1 小时吗?喜欢if ((machineDate - tokenDate).TotalHours &gt; 1)?
  • 问题是您在比较日期时将机器日期加一小时。过去或当前的任何日期都将返回 var result = DateTime.Compare(tokenDate, machineDate.AddHours(-1));。
  • 为我辩护...这里是星期五...所以我怀疑我的大脑准备好迎接周末...

标签: c# datetime compare


【解决方案1】:

您可以减去两个DateTime 而不是DateTime.Compare(),得到DateTime 的总小时数。

类似的,

var result = (DateTime.UtcNow - tokenEntity.Time_stamp).TotalHours;
if(result > 1)
{
   //Do your business logic for expiring token
}
else
   //Your business logic

Try it online

【讨论】:

  • 在我可以尝试这个解决方案之前需要恢复一个数据库.. 但几乎 100% 肯定这是它... 将在测试后将其标记为答案。
  • @andrelange91,慢慢来。我还添加了支持我的答案的在线小提琴。
  • 另外,如果您只想知道两个DateTime 值是否相隔1 小时,但不关心哪个小于另一个,您可以使用Duration()求差值绝对值的方法。否则,差异可能是负数(在不应该的情况下,result &gt; 1 测试会失败)。例如:(DateTime.UtcNow - tokenEntity.Time_stamp).Duration().TotalHours;
  • @RufusL,是的,你是对的。使用Duration() 会给我们绝对值。仅当 Time_stampUtcNow 大 1 小时时,结果才会存储负值。现在对 OP 的问题是 Time_stamp 是否包含大于 DateTime.UtcNow.AddHours(+1) 的值?
  • @PrasadTelkikar 我不得不在最后添加 Duration() ,但现在它可以工作了。感谢您的帮助
【解决方案2】:

“我正在尝试查看自创建令牌对象以来是否已过去 [超过] 一个小时”

问题似乎是您增加一个小时到当前时间,而不是减去一个小时。您可以通过将-1 传递给AddHours 方法来减去一个小时。

还有一个问题是调用Compare时参数顺序不正确,因为如果第一个参数大于第二个参数,Compare方法将返回1。由于我们想知道“一小时前”的值是否大于令牌创建时间,所以我们应该在调用Compare时首先传递该值:

var result = DateTime.Compare(machineDate.AddHours(-1), tokenDate);

另一个(首选)选项是简单地使用&gt; 运算符,并以类似于您用英语编写代码的方式编写代码。另一种说法“我正在尝试查看自创建令牌对象以来是否已经过去了[超过]一个小时”是:

“当前时间是否大于令牌创建时间加一小时的总和”

可以写成:

if (machineDate > tokenDate.AddHours(1))

【讨论】:

  • 最后一种检查令牌过期时间的方法既优雅又清晰。
【解决方案3】:
// Add -1 hour to simulate timespan being one hour in past
DateTime d1 = DateTime.Now.AddHours(-1);
DateTime d2 = DateTime.Now;
TimeSpan diff = d2 - d1;
bool diffIsGreaterThan1Hour = diff.TotalHours > 1;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多