gpt4 book ai didi

C# 将特定时区的 1 天添加到 DateTimeOffset

转载 作者:太空宇宙 更新时间:2023-11-03 20:58:55 26 4
gpt4 key购买 nike

我有一个 DateTimeOffset 实例,考虑到夏令时规则(所以它可能会导致 Offset 改变)。如果没有第 3 方库,我该怎么做?

可验证的例子:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace UnitTestProject
{
[TestClass]
public class TimeZoneTests
{
[TestMethod]
public void DateTimeOffsetAddDays_DaylightSaving_OffsetChange()
{
var timeZoneId = "W. Europe Standard Time";
var utcTimestamp = new DateTimeOffset(2017, 10, 28, 22, 0, 0, TimeZoneInfo.Utc.BaseUtcOffset);
var weuropeStandardTimeTimestamp = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(utcTimestamp, timeZoneId);
Assert.AreEqual(new DateTime(2017, 10, 29), weuropeStandardTimeTimestamp.DateTime);
Assert.AreEqual(TimeSpan.FromHours(2), weuropeStandardTimeTimestamp.Offset);

var weuropeStandardTimeTimestampNextDay = AddDaysInTimeZone(weuropeStandardTimeTimestamp, 1, timeZoneId);

Assert.AreEqual(new DateTime(2017, 10, 30), weuropeStandardTimeTimestampNextDay);
Assert.AreEqual(TimeSpan.FromHours(1), weuropeStandardTimeTimestamp.Offset);
}

private DateTimeOffset AddDaysInTimeZone(DateTimeOffset timestamp, int days, string timeZoneId)
{
// this line has to be fixed:
return timestamp.AddDays(days);
}
}
}

AddDaysInTimeZone 方法应替换为正确的实现。

PS 如果它导致无效/不明确/跳过的日期,那么可以抛出异常。

最佳答案

TimeZoneInfo 使这个合理简单 - 只需将一天添加到值的 DateTime 部分,检查结果是否被跳过或有歧义,如果不是,请向区域询问 UTC 偏移量。这是一个显示所有不同可能性的完整示例:

using System;
using System.Globalization;

using static System.FormattableString;

class Program
{
static void Main()
{
// Stay in winter
Test("2017-01-22T15:00:00+01:00");
// Skipped time during transition
Test("2017-03-25T02:30:00+01:00");
// Offset change to summer
Test("2017-03-25T15:00:00+01:00");
// Stay in summer
Test("2017-06-22T15:00:00+02:00");
// Ambiguous time during transition
Test("2017-10-28T02:30:00+02:00");
// Offset change back to winter
Test("2017-10-28T15:00:00+02:00");
// Stay in winter
Test("2017-12-22T15:00:00+01:00");
}

static void Test(string startText)
{
var zone = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");
var start = DateTimeOffset.ParseExact(
startText, "yyyy-MM-dd'T'HH:mm:ssK", CultureInfo.InvariantCulture);
try
{
var end = AddOneDay(start, zone);
Console.WriteLine(Invariant($"{startText} => {end:yyyy-MM-dd'T'HH:mm:ssK}"));
}
catch (Exception e)
{
Console.WriteLine($"{startText} => {e.Message}");
}
}

static DateTimeOffset AddOneDay(DateTimeOffset start, TimeZoneInfo zone)
{
var newLocal = start.DateTime.AddDays(1);
// TODO: Use a better exception type :)
if (zone.IsAmbiguousTime(newLocal))
{
throw new Exception("Ambiguous");
}
if (zone.IsInvalidTime(newLocal))
{
throw new Exception("Skipped");
}
return new DateTimeOffset(newLocal, zone.GetUtcOffset(newLocal));
}

}

关于C# 将特定时区的 1 天添加到 DateTimeOffset,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47710262/

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