C#:每天从 TimeSpan 中删除一天的子集时的边缘情况

发布于 2024-09-17 12:28:37 字数 1781 浏览 5 评论 0原文

我正在尝试确定一个时间跨度(例如,注销和登录之间的时间),但需要注意的是,不应计算每天的一部分时间(例如,不要计算晚上 7 点到早上 7 点之间的时间)给定的一天)。从全天中删除该时间很容易,但是检查一天中的部分时间(例如,用户在下午 6 点注销并在当天晚上 8 点重新登录)和其他边缘情况的最佳方法是什么?

ETA:我目前的设置如下所示:

public class HasProductiveHours
{
    //These fields should represent an hour of the day (in 24-hour format)
    // in which production should start or stop.
    public int startProductiveHour;
    public int endProductiveHour;
    //Resource type enum
    public ResourceType resourceType
    //How often this resource is collected, in seconds
    public float harvestTime

    public HasProductiveHours (int startProductiveHour, int endProductiveHour, ResourceType resourceType, int harvestTime)
    {
        // Other creation-time things
        this.startProductiveHour = startProductiveHour;
        this.endProductiveHour = endProductiveHour;
        this.resourceType = resourceType;
        this.harvestTime = harvestTime;
        TimeSimulator.Instance.SimulateElapsedTime (this);
    }
}

此类及其子级的实例每小时左右模拟一些资源的生产(取决于资源)。有一个系统可以模拟自用户上次注销以来经过的时间。

DateTime lastLogoutTime;

public void Logout ()
{
    // Other logout things
    lastLogoutTime = DateTime.Now;
}

public void SimulateElapsedTime (HasProductiveHours toSimulate)
{
    DateTime currentTime = DateTime.Now;
    TimeSpan timeSinceLogout = currentTime - lastLogout;
    int unproductiveHours = Math.Abs (toSimulate.startProductionHour - toSimulate.endProductionHour) * timeSinceLogout.Days;
    timeSinceLogout.Subtract (new TimeSpan (unproductiveHours, 0, 0);
    double secondsElapsed = timeSinceLogout.TotalSeconds;
int harvestsElapsed = (int)(secondsElapsed / toSimulate.harvestTime);
PlayerData.Instance.AddResource (toSimulate.resourceType, harvestsElapsed);
}

I'm trying to determine a TimeSpan (eg., time between logout and login), but with the caveat that a part of each day shouldn't be counted (eg., don't count the time between 7PM and 7AM on a given day). Removing that time from full days is easy enough, but what's the best way to check for parts of a day (eg., user logs out at 6PM and logs back in at 8PM the same day) and other edge cases?

ETA: I've currently got a set-up that looks like this:

public class HasProductiveHours
{
    //These fields should represent an hour of the day (in 24-hour format)
    // in which production should start or stop.
    public int startProductiveHour;
    public int endProductiveHour;
    //Resource type enum
    public ResourceType resourceType
    //How often this resource is collected, in seconds
    public float harvestTime

    public HasProductiveHours (int startProductiveHour, int endProductiveHour, ResourceType resourceType, int harvestTime)
    {
        // Other creation-time things
        this.startProductiveHour = startProductiveHour;
        this.endProductiveHour = endProductiveHour;
        this.resourceType = resourceType;
        this.harvestTime = harvestTime;
        TimeSimulator.Instance.SimulateElapsedTime (this);
    }
}

Instances of this class and its children are simulating production of some resource every hour or so (depending on the resource). There's a system in place to simulate elapsed time since the user's last logout.

DateTime lastLogoutTime;

public void Logout ()
{
    // Other logout things
    lastLogoutTime = DateTime.Now;
}

public void SimulateElapsedTime (HasProductiveHours toSimulate)
{
    DateTime currentTime = DateTime.Now;
    TimeSpan timeSinceLogout = currentTime - lastLogout;
    int unproductiveHours = Math.Abs (toSimulate.startProductionHour - toSimulate.endProductionHour) * timeSinceLogout.Days;
    timeSinceLogout.Subtract (new TimeSpan (unproductiveHours, 0, 0);
    double secondsElapsed = timeSinceLogout.TotalSeconds;
int harvestsElapsed = (int)(secondsElapsed / toSimulate.harvestTime);
PlayerData.Instance.AddResource (toSimulate.resourceType, harvestsElapsed);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

那请放手 2024-09-24 12:28:37

只需几个步骤就可以轻松解决此问题:

  1. 检查注销时间 - 看看它是否在上午 7 点到下午 7 点之间(小时方法为您提供自午夜以来的小时数。您想查看它是否 >=7 且 < ;=19)。如果不是,请将时间提前到早上 7 点。应该很容易做到 - 如果时间<7am,将时间更改为7am。如果时间大于晚上 7 点,则将时间更改为第二天早上 7 点

  2. 检查登录时间 - 看看是否在上午 7 点到晚上 7 点之间。如果不是,请将时间推迟到晚上 7 点。应该很容易做到 - 如果时间 > 7pm,则将其设置为晚上 7 点,如果时间 < 7am,则将时间更改为前一天的晚上 7 点

  3. 检查以确保注销时间

    登录时间。如果不是,则整个注销时间均在不计入时间内,因此您的时间跨度应设置为 0。如果您的注销时间 < >登录,只需减去它们即可得到您的时间跨度

这适用于评论中描述的情况:

如果天数现在相同,那么我将采取这些步骤:

  1. 使用注销日期创建一个新的日期时间,并时间 1900。从注销日期中减去新日期 - 这将为您提供直到一天结束的时间跨度

  2. 将注销日期移至第二天早上 7 点。如果现在注销和登录是在同一天,只需从登录中减去注销,这就是当天的时间跨度。如果它们不是同一日期,请重复步骤 1

  3. 将步骤 1 和步骤 2 中生成的时间跨度相加。这给出了您的总时间

例如:我于 1 月 1 日 16:00 注销。我于 1 月 2 日 10:00 登录 我

于 1 月 1 日在跟踪时间内注销的时间为 3 小时(1 月 1 日 19:00 - 1 月 1 日 16:00)

我将注销时间移至 1 月 2 日 07:00 。

注销日期是 2,登录日期是 2,现在我可以将它们相减。

在跟踪时间内,我在 1 月 2 日注销的时间是 3 小时(1 月 2 日 10:00 - 1 月 2 日 07:00)

我现在将它们加在一起,即可在跟踪时间内获得 6 小时的注销时间。

A few steps should easily fix this:

  1. Check the logout time - see if it is between 7am and 7pm (The hour method gives you the number of hours since midnight. You want to see if it is >=7 and <=19). If it is not, move the time forward to 7am. Should be easy enough to do - If the time is <7am, change the time to 7am. If the Time is greater than 7pm, change the time to 7am the next day

  2. Check the login time - see if it is between 7am and 7pm. If it is not, move the time back to 7pm. Should be easy enough to do - If the hour >7pm, set it to 7pm, if the hour is <7am, change the time to 7pm on the previous day

  3. Check to make sure logout time < login time. If not, the entire time logged out was during the none counting hours, so your time span should be set to 0. If your logout time < login, just subtract them to get your timespan

This for the situation described in the comment:

If the day numbers are the now the same these are the steps I would take:

  1. Create a new datetime with the logout outs date, and a time of 1900. Subtract the new date from the logout date - this will give you the timespan until the end of day

  2. Move the logout date to 7am the next day. If the logout and the login are now on the same day, just subtract the logout from the login, this is the timespan for that day. If they are not the same date, repeat step 1

  3. Add the timespans generated in step 1 and step 2 together. This gives your total time

For example: I logout Jan 1, at 16:00. I login Jan 2, at 10:00

The time I was logout on Jan 1 during tracking hours is 3hours (Jan 1, 19:00 - Jan 1, 16:00)

I move the logout time to Jan 2, at 07:00.

The day of logout is 2, and the day of login is 2, now I can subtract them

The time I was logout in Jan 2 during tracking hours is 3hours (Jan 2, 10:00 - Jan 2, 07:00)

I now add them together and get 6hours of logout time during tracking hours.

零度℉ 2024-09-24 12:28:37

@thorkia 有一些很好的建议。

或者,您可以计算时间差,然后总结(从另一个表)所涵盖的总非生产/非时间,并从总数中减去它。

因此,

上午 8 点至上午 6 点 = 总计 2 小时

上午 6 点至上午 7 点 = 1 小时非时间

结果 = 总计 1 小时实时结果

@thorkia has some good suggestions.

Alternatively you can calculate the time difference and then sum up (from another table) the total non-production/non-time that was covered and subtract that from the total.

So

8am-6am = 2 hours total

6am to 7am = 1 hour non-time

result = 1 hour total real-time

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文