c# – 从通用或本地DateTime添加/减去的最佳实践

我正在尝试在DateTime周围添加一个包装器以包含时区信息.这是我到目前为止所拥有的:

public struct DateTimeWithZone {
    private readonly DateTime _utcDateTime;
    private readonly TimeZoneInfo _timeZone;

    public DateTimeWithZone(DateTime dateTime, TimeZoneInfo timeZone) {
        _utcDateTime = TimeZoneInfo.ConvertTimeToUtc(DateTime.SpecifyKind(dateTime, DateTimeKind.Unspecified), timeZone);
        _timeZone = timeZone;
    }

    public DateTime UniversalTime { get { return _utcDateTime; } }

    public TimeZoneInfo TimeZone { get { return _timeZone; } }

    public DateTime LocalTime { get { return TimeZoneInfo.ConvertTimeFromUtc(_utcDateTime, _timeZone); } }

    public DateTimeWithZone AddDays(int numDays) {
        return new DateTimeWithZone(TimeZoneInfo.ConvertTimeFromUtc(UniversalTime.AddDays(numDays), _timeZone), _timeZone);
    }

    public DateTimeWithZone AddDaysToLocal(int numDays) {
        return new DateTimeWithZone(LocalTime.AddDays(numDays), _timeZone);
    }
}

这是根据先前问题中提供的@Jon Skeet的答案改编的.

由于夏令时问题,我正在努力增加/减少时间.根据以下内容,最佳做法是添加/减去通用时间:

https://msdn.microsoft.com/en-us/library/ms973825.aspx#datetime_topic3b

我遇到的问题是,如果我说:

var timeZone = TimeZoneInfo.FindSystemTimeZoneById("Romance Standard Time");            
var date = new DateTimeWithZone(new DateTime(2003, 10, 26, 00, 00, 00), timeZone);
date.AddDays(1).LocalTime.ToString();

这将返回26/10/2003 23:00:00.正如你所看到的那样,当地时间已经减少了一个小时(由于夏令时结束),所以如果我要显示它,它会说它与它刚刚添加一天的那天相同.但是,如果我要说:

date.AddDaysToLocal(1).LocalTime.ToString();

我会回来27/10/2003 00:00:00并保留时间.这看起来对我来说是正确的,但它违背了加入世界时的最佳做法.

如果有人能帮助澄清正确的方法,我会很感激.请注意,我已经看过Noda Time,它目前需要做太多工作才能转换成它,我也想更好地理解这个问题.

两种方式都是正确的(或不正确的)取决于您需要做什么.

我喜欢将这些视为不同类型的计算:

>按时间顺序计算.
>日历计算.

按时间顺序计算涉及以物理时间为常规单位的时间算术.例如,添加秒,纳秒,小时或天.

日历计算涉及人类发现方便的单位时间算术,但并不总是具有相同的物理时间长度.例如,添加数月或数年(每个都有不同的天数).

当您想要添加一个不一定具有固定秒数的粗单位时,日历计算很方便,但您仍希望在日期中保留更精细的字段单位,例如天,小时,分钟和秒.

在您的本地时间计算中,您添加一天,并假设日历计算是您的意图,您保留当地时间,尽管在本地日历中1天并非总是24小时.请注意,本地时间的算术可能会导致本地时间与UTC有两次映射,甚至是映射到UTC的零映射.因此,您的代码应该构建为使您知道这种情况永远不会发生,或者能够检测它何时发生并以适合您的应用程序的任何方式做出反应(例如消除模糊映射的歧义).

在您的UTC时间计算(按时间顺序计算)中,您总是添加86400秒,然后本地日历可能会做出反应,但这可能是由于UTC偏移更改(夏令时相关或其他). UTC偏移量变化可能大到24小时,因此添加按时间顺序排列的日期可能甚至不会使当月日历日突然加1.按时间顺序计算的结果总是具有唯一的UTC< - >.局部映射(假设输入具有唯一的映射).

两种计算都很有用.两者都是常见的.知道您需要哪些,并知道如何使用API​​来计算您需要的任何内容.

相关文章
相关标签/搜索