我需要存储来自多个不同日历的日期和持续时间。特别是,我需要存储以下日期:
我还需要存储持续时间,我已经将其定义为两个时间戳(日期和时间)之间的差异。这意味着需要能够存储“零”日期-这样我就可以存储持续时间,比方说,三个半小时;或10分钟。
我有所需计算的details。Firebird的时间戳基于从公元100年1月1日开始的日期函数,因此不能以我需要的方式记录持续时间。此外,该数据类型(与大多数时间戳函数一样)用于记录自基准日期以来的天数;它不适于记录日历日期。
有没有人建议:
编辑:
@Warren P在他的回复中提供了一些优秀的工作。我显然没有足够清楚地解释我寻求的是什么,因为他的工作集中在计算以及如何进行计算。所有有价值和有用的东西,但不是我想要表达的问题。
我确实有在不同的日期表示之间转换所需的所有计算的详细信息,并且我对如何实现它们有一个相当好的想法(使用Warren建议的元素)。但是,我的要求是存储满足上面列出的各种条件的日期。示例:要存储的日期-‘3月13日查尔斯二世’。我正在尝试确定一个适当的结构来存储这些日期。
编辑:
我已经修改了我提出的方案。我已经列出了每个表上的属性,并通过示例定义了表和属性,如实体框的第三部分所示。我已经在我的定义中通过示例使用了这个question和answer中给出的示例,并修改了我的问题中的示例以对应。虽然我已经通过描述别人的例子证明了我的模式,但这个模式可能仍然过于复杂;过度分析;遗漏了一些明显的简化,并且可能被证明是非常难以实现的(实际上,它可能是完全错误的)。任何意见或建议都将非常受欢迎。
发布于 2011-03-25 09:27:55
如果您正在编写自己的类(我假设您打算这样做),我将创建一个包含TDateTime和其他字段的类,并且我将基于为Python编写的非常优秀的mxDateTime扩展中的功能,它是非常容易阅读的、开源的C代码,您可以使用它来提取您将需要的公历逻辑。
在一定的范围内,TDateTime总是正确的。它的纪元值(0)是1899年12月30日午夜。从那里,您可以计算其他儒略日数字。它支持负值,因此它将支持超过400年。我相信,在上一次公历改革的时候,你将不得不开始进行更正。如果你从1582年10月15日星期五开始,算出它的儒略日数字,以及在那之前和之后的改革,你应该能够做你需要的一切。请注意,在1899年之前,一天中的时间是“倒退”的,但这纯粹是人脑的问题,计算机将是准确的,并将为您计算分钟和秒数,达到双精度浮点数学的极限。坚持使用TDateTime作为您的基础。
我发现了一些非常旧的BorlandPascal/TurboPascal代码,它们处理非常广泛的日期here。
如果您需要处理阿拉伯语、犹太和其他日历,我再次建议您参考Python,因为它是一个很好的工作示例来源。不仅仅是mxdatetime扩展,还有像this这样的东西。
对于数据库持久性,如果您需要的最大分辨率是1秒,那么您可能希望以julian天数作为日期存储的基础,并将您的时间作为从午夜开始的类似C的秒数。
下面是我将开始的代码片段,并对其进行代码补全:
TCalendarDisplaySubtype = ( cdsGregorian,cdsHebrew,cdsArabic,cdsAztec,
cdsValveSoftwareCompany, cdsWhoTheHeckKnows );
TDateInformation = class
private
FBaseDateTime:TDateTime;
FYear,FMonth,FDay:Integer; // if -1 then not calculated yet.
FCalendarDisplaySubtype:TCalendarDisplaySubtype;
public
function SetByDateInCE(Y,M,D,h,m,s:Integer):Boolean;
function GetAsDateInCE(var Y,M,D,h,m,s:Integer):Boolean;
function DisplayStr:String;
function SetByDateInJewishCalendar( ... );
property BaseDateTime:TDateTime read FDateTime write FDateTime;
property JulianDayNumber:Integer read GetJulianDayNumber write SetJulianDayNumber;
property CalendarDisplaySubType:TCalendarDisplaySubtype;
end;
我认为没有理由同时存储儒略日数字和TDateTime,只需使用Trunc(FBaseDateTime)值减去/添加的常量,并在GetJulianDayNumber的SetJulianDayNumber函数中返回该常量。您可以在字段中一次性计算给定日历的年、月、日,并将其存储,从而使显示为字符串的功能变得更简单、更快。
更新:看起来你比我更擅长ER建模,所以如果你发布了这张图,我会支持它,就是这样。就我而言,我将存储三个字段:一个符合现代日历标准的日期时间字段,一个包含任何形式的原始学术日期的文本字段(自由格式),以及一些其他字段,它们是子类型查找表外键,以帮助我按日期和子类型组织和搜索日期。对我来说就是这样。
发布于 2011-03-25 22:36:19
这只是一个部分答案,但却是一个重要的部分。
由于您将在非常广泛的范围内存储日期,其中日历发生了很多事情,因此您需要适应这些更改。
围绕TZ-database的时区数据库TZ-database和Delphi TZDB wrapper将会有很大帮助。
它有一个数据库,里面有关于时区历史行为的规则。
我知道它们是基于当前的日历方案,您需要首先转换为UTC。
您需要为您想要支持的其他日历方案设计类似的方案。
编辑:
我使用的方案是这样的:
中的日历类型
--jeroen
https://stackoverflow.com/questions/5427459
复制相似问题