从通用或本地DateTime添加/减去的最佳实践 [英] Best practice for adding/subtracting from universal or local DateTime

查看:61
本文介绍了从通用或本地DateTime添加/减去的最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to add a wrapper around DateTime to include the time zone information. Here's what I have so far:

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.

由于夏时制的问题,我在增加/减少时间上感到很挣扎.根据以下说明,最佳做法是加/减世界时:

I am struggling with with adding/subtracting time due to problems with daylight saving time. According to the following it is best practice to add/subtract the universal time:

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

我的问题是,如果我说:

The problem I have is that if I say:

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();

这将返回2003年10月26日23:00:00.如您所见,当地时间已经损失了一个小时(由于夏令时结束),所以如果我要显示该时间,它将表示与添加了一天的日期是同一天.但是,如果我要说的话:

This will return 26/10/2003 23:00:00. As you can see the local time has lost an hour (due to daylight saving time ending) so if I was to display this, it would say it's the same day as the day it's just added a day to. However if i was to say:

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

我会回来2003年10月27日00:00:00并保留时间.在我看来,这是正确的,但与增加通用时间相抵触的最佳做法是相反的.

I would get back 27/10/2003 00:00:00 and the time is preserved. This looks correct to me but it goes against the best practice to add to the universal time.

如果有人可以帮助您澄清执行此操作的正确方法,我将不胜感激.请注意,我已经看过Noda Time了,目前要将它转换成太多的工作,我也希望对这个问题有更好的理解.

I'd appreciate it if someone could help clarify what's the correct way to do this. Please note that I have looked at Noda Time and it's currently going to take too much work to convert to it, also I'd like a better understanding of the problem.

推荐答案

这两种方法都是正确的(或不正确的),具体取决于您需要执行的操作.

Both ways are correct (or incorrect) depending upon what you need to do.

我喜欢将它们视为不同类型的计算:

I like to think of these as different types of computations:

  1. 按时间顺序计算.

日历计算.

按时间顺序的计算涉及相对于物理时间有规律的单位的时间算术.例如,秒,纳秒,小时或天的加法.

A chronological computation involves time arithmetic in units that are regular with respect to physical time. For example the addition of seconds, nanoseconds, hours or days.

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

A calendrical computation involves time arithmetic in units that humans find convenient, but which don't always have the same length of physical time. For example the addition of months or years (each of which have a varying number of days).

当您要添加不一定具有固定秒数的粗略单位,而您仍希望在日期中保留更精细的字段单位(例如天,小时,分钟和秒钟.

A calendrical computation is convenient when you want to add a coarse unit that does not necessarily have a fixed number of seconds in it, and yet you still want to preserve the finer field units in the date, such as days, hours, minutes and seconds.

在本地时间计算中,您要添加一天,并假定您要进行日历计算,则可以保留本地一天中的时间,尽管事实上本地日历中的1天并不总是24小时.请注意,本地时间的算术有可能导致本地时间具有与UTC的两个映射,甚至与UTC的映射.因此,您应该对代码进行构造,以使您知道这种情况永远不会发生,或者能够检测到它何时发生并以对您的应用程序正确的任何方式做出反应(例如,消除歧义性歧义).

In your local time computation, you add a day, and presuming a calendrical computation is what you intended, you preserve the local time of day, despite the fact that 1 day is not always 24 hours in the local calendar. Be aware that arithmetic in local time has the potential to result in a local time that has two mappings to UTC, or even zero mappings to UTC. So your code should be constructed such that you know this can never happen, or be able to detect when it does and react in whatever way is correct for your application (e.g. disambiguate an ambiguous mapping).

在UTC时间计算(按时间顺序进行的计算)中,您总是 添加86400秒,而本地日历可以做出反应,但是这可能是由于UTC偏移量的变化(与夏令时有关或其他原因).UTC偏移量更改可能长达24小时,因此添加按时间顺序排列的日期甚至可能不会使该月的本地日历天增加一倍.按时间顺序计算的结果始终具有唯一的UTC <->本地映射(假设输入具有唯一的映射).

In your UTC time computation (a chronological computation), you always add 86400 seconds, and the local calendar can react however it may due to UTC offset changes (daylight saving related or otherwise). UTC offset changes can be as large as 24h, and so adding a chronological day may not even bump the local calendar day of the month by one. Chronological computations always have a result which has a unique UTC <-> local mapping (assuming the input has a unique mapping).

两种计算都很有用.两者都是通常需要的.知道您需要的内容,并知道如何使用API​​计算所需的内容.

Both computations are useful. Both are commonly needed. Know which you need, and know how to use the API to compute whichever you need.

这篇关于从通用或本地DateTime添加/减去的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆