gpt4 book ai didi

c# - 如何在 C# 项目中使用 gas days?

转载 作者:行者123 更新时间:2023-12-05 08:45:38 29 4
gpt4 key购买 nike

天然气日定义为 24 小时的时间范围,从世界标准时间 5:00 开始,到欧洲标准时间次日世界标准时间 5:00 结束。在欧洲夏令时期间,它从 4:00 UTC 开始到次日 4:00 UTC 结束(请参阅 WikipediaACER 了解英文说明)。

我需要在应用程序中使用 gas days 以执行以下操作:

  1. 获取任何给定 UTC 时间戳的当前加油日。示例:“2022-03-22 05:00:00”(UTC)应变为“2022-03-22 00:00:00”(加油日)。
  2. 从特定的加油日添加和/或减去时间跨度(天、小时等)以获得新的时间戳,该时间戳也将 DST 考虑在内。例如,这意味着如果我从时间戳“2022-03-29 04:00:00”(UTC)(等于加油日“2022-03-29”)中减去 7 天,我想得到时间戳“2022-03-22 05:00:00"(UTC)。

这对我来说感觉好像“gas day”应该作为类似于时区的东西可用,然后我可以在我的应用程序中使用它,但尝试使用 DateTimeDateTimeOffset 让我完全不知道我应该做什么来完成这项工作。

任何人都可以指出我必须做些什么才能让我进行上面解释的计算的正确方向吗?是否有一个图书馆可以使这更容易做到?例如,我已经研究过 NodaTime ,但我在它的文档中找不到任何能让我更轻松地解决此任务的内容。

最佳答案

我将使用稍微更精确的定义:“Gas Days”(或更确切地说是“Gas Time”,因为这里有时间部分)基于德国本地时区,但偏移了 6 小时,因此德国的 06:00在 Gas Time 中是 00:00。

正如您在自己的实验中发现的那样,自定义时区方法并不那么容易实现,因为所有转换都是根据德国本地的日期和时间发生的,即使气体转移将值插入不同的日期。 (使用 NodaTime 可能可行,但使用 TimeZoneInfo 则不行。)

考虑到这一点,您需要在德国时间进行所有转换和操作,然后将它们转移到 Gas Time。一些扩展方法在这里很有用。解释性注释内联代码。

public static class GasTimeExtensions
{
private static readonly TimeZoneInfo GermanyTimeZone =
TimeZoneInfo.FindSystemTimeZoneById("Europe/Berlin");
// (use "W. Europe Standard Time" for .NET < 6 on Windows)

private static readonly TimeSpan GasTimeOffset = TimeSpan.FromHours(6);

/// <summary>
/// Adjusts the provided <paramref name="dateTimeOffset"/> to Gas Time.
/// </summary>
/// <param name="dateTimeOffset">The value to adjust.</param>
/// <returns>The adjusted value.</returns>
public static DateTimeOffset AsGasTime(this DateTimeOffset dateTimeOffset)
{
// Convert to Germany's local time.
var germanyTime = TimeZoneInfo.ConvertTime(dateTimeOffset, GermanyTimeZone);

// Shift for Gas Time.
return germanyTime.ToOffset(germanyTime.Offset - GasTimeOffset);
}

/// <summary>
/// Adjusts the provided <paramref name="dateTime"/> to Gas Time.
/// </summary>
/// <param name="dateTime">The value to adjust.</param>
/// <returns>The adjusted value.</returns>
public static DateTime AsGasTime(this DateTime dateTime)
{
// Always go through a DateTimeOffset to ensure conversions and adjustments are applied.
return dateTime.ToGasDateTimeOffset().DateTime;
}

/// <summary>
/// Adjusts the provided <paramref name="dateTime"/> to Gas Time,
/// and returns the result as a <see cref="DateTimeOffset"/>.
/// </summary>
/// <param name="dateTime">The value to adjust.</param>
/// <returns>The adjusted value as a <see cref="DateTimeOffset"/>.</returns>
public static DateTimeOffset ToGasDateTimeOffset(this DateTime dateTime)
{
if (dateTime.Kind != DateTimeKind.Unspecified)
{
// UTC and Local kinds will get their correct offset in the DTO constructor.
return new DateTimeOffset(dateTime).AsGasTime();
}

// Treat the incoming value as already in gas time - we just need the offset applied.
// However, we also need to account for values that might be during DST transitions.
var germanyDateTime = dateTime + GasTimeOffset;
if (GermanyTimeZone.IsInvalidTime(germanyDateTime))
{
// In the DST spring-forward gap, advance the clock forward.
// This should only happen if the data was bad to begin with.
germanyDateTime = germanyDateTime.AddHours(1);
}

// In the DST fall-back overlap, choose the offset of the *first* occurence,
// which is the same as the offset before the transition.
// Otherwise, we're not in a transition, just get the offset.
var germanyOffset = GermanyTimeZone.GetUtcOffset(
GermanyTimeZone.IsAmbiguousTime(germanyDateTime)
? germanyDateTime.AddHours(-1)
: germanyDateTime);

// Construct the Germany DTO, shift to gas time, and return.
var germanyDateTimeOffset = new DateTimeOffset(germanyDateTime, germanyOffset);
return germanyDateTimeOffset.ToOffset(germanyOffset - GasTimeOffset);
}

/// <summary>
/// Add a number of calendar days to the provided <paramref name="dateTimeOffset"/>, with respect to Gas Time.
/// </summary>
/// <remarks>
/// A day in Gas Time is not necessarily 24 hours, because some days may contain a German DST transition.
/// </remarks>
/// <param name="dateTimeOffset">The value to add to.</param>
/// <param name="daysToAdd">The number of calendar days to add.</param>
/// <returns>The result of the operation, as a <see cref="DateTimeOffset"/> in Gas Time.</returns>
public static DateTimeOffset AddGasDays(this DateTimeOffset dateTimeOffset, int daysToAdd)
{
// Add calendar days (with respect to gas time) - not necessarily 24 hours.
return dateTimeOffset.AsGasTime().DateTime.AddDays(daysToAdd).ToGasDateTimeOffset();
}

/// <summary>
/// Add a number of calendar days to the provided <paramref name="dateTime"/>, with respect to Gas Time.
/// </summary>
/// <remarks>
/// A day in Gas Time is not necessarily 24 hours, because some days may contain a German DST transition.
/// </remarks>
/// <param name="dateTime">The value to add to.</param>
/// <param name="daysToAdd">The number of calendar days to add.</param>
/// <returns>The result of the operation, as a <see cref="DateTime"/> in Gas Time.</returns>
public static DateTime AddGasDays(this DateTime dateTime, int daysToAdd)
{
// Add calendar days (with respect to gas time) - not necessarily 24 hours.
return dateTime.AsGasTime().AddDays(daysToAdd).AsGasTime();
}
}

一些用法示例:

  • 转换特定的时间戳

    var test = DateTimeOffset.Parse("2022-03-22T05:00:00Z").AsGasTime();
    Console.WriteLine($"{test:yyyy-MM-ddTHH:mm:sszzz} in Gas Time is
    {test.UtcDateTime:yyyy-MM-ddTHH:mm:ssZ} UTC.");

    输出:

    2022-03-22T00:00:00-05:00 in Gas Time is 2022-03-22T05:00:00Z UTC.
  • 获取当前gas时间戳

    var now = DateTimeOffset.UtcNow.AsGasTime();
    Console.WriteLine($"It is now {now:yyyy-MM-ddTHH:mm:sszzz} in Gas Time ({now.UtcDateTime:yyyy-MM-ddTHH:mm:ssZ} UTC).");

    输出:

    It is now 2022-05-10T14:31:56-04:00 in Gas Time (2022-05-10T18:31:56Z UTC).
  • 添加绝对时间(小时、分钟、秒等)

    var start = DateTimeOffset.Parse("2022-03-26T05:00:00Z").AsGasTime();
    var end = start.AddHours(24 * 7).AsGasTime(); // add and correct any offset change
    Console.WriteLine($"Starting at {start:yyyy-MM-ddTHH:mm:sszzz} Gas Time ({start.UtcDateTime:yyyy-MM-ddTHH:mm:ssZ} UTC),");
    Console.WriteLine($"7 x 24hr intervals later is {end:yyyy-MM-ddTHH:mm:sszzz} Gas Time ({end.UtcDateTime:yyyy-MM-ddTHH:mm:ssZ} UTC).");

    输出:

    Starting at 2022-03-26T00:00:00-05:00 Gas Time (2022-03-26T05:00:00Z UTC),
    7 x 24hr intervals later is 2022-04-02T01:00:00-04:00 Gas Time (2022-04-02T05:00:00Z UTC).
  • 添加或减去日历天数(由于 DST 转换,严格来说不是 24 小时天数)

    var start = DateTimeOffset.Parse("2022-03-26T05:00:00Z").AsGasTime();
    var end = start.AddGasDays(7); // add and correct any offset change
    Console.WriteLine($"Starting at {start:yyyy-MM-ddTHH:mm:sszzz} Gas Time ({start.UtcDateTime:yyyy-MM-ddTHH:mm:ssZ} UTC),");
    Console.WriteLine($"7 calendar days later is {end:yyyy-MM-ddTHH:mm:sszzz} Gas Time ({end.UtcDateTime:yyyy-MM-ddTHH:mm:ssZ} UTC).");

    输出:

    Starting at 2022-03-26T00:00:00-05:00 Gas Time (2022-03-26T05:00:00Z UTC),
    7 calendar days later is 2022-04-02T00:00:00-04:00 Gas Time (2022-04-02T04:00:00Z UTC).

请注意,在最后两个示例中,我选择了与您不同的日期,以演示跨 DST 转换。

关于c# - 如何在 C# 项目中使用 gas days?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72113804/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com