C++:将儒略日期转换为公历日期
我需要编写一个函数,将儒略日期(年、年、日、分)转换为标准形式(年、月、日、日、分)并将其表示为字符串。我想一定有人已经编写了一个库或组件,可以完成从一年中的某一天到月份和每月的某一天的转换。我查看了几个著名的日期时间库:
- ctime -具体来说,使用 tm 结构和 mktime(tm *timeptr) ,因为这通常会将 tm 结构的值设置到适当的位置,除了“timeptr 的成员 tm_wday 和 tm_yday 的原始值被忽略。 ..”这没有帮助。
- Boost::DateTime - 构造公历
date(greg_year, greg_month, greg_day)
这没有帮助。但是,它们确实有一个 date_from_tm(tm datetm) ,但“字段: tm_wday 、 tm_yday 、 tm_hour 、 tm_min 、 tm_sec 和 tm_isdst 被忽略。”再次,没有帮助。 - COleDateTime - 此项目包含 COM那么为什么不呢? COleDateTime 构造函数
COleDateTime( int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec )
没有帮助。而且我没有看到任何其他转换函数可以与之配合。
正如您所看到的,这些都需要月份和月份的日期,这正是我首先要避免的。我一定是错过了一些东西,或者没有找到正确的地方(尽我所能,并不完美。)
任何人都可以帮忙吗?我宁愿避免自己编写,因为几乎总会有一些我错过的问题。
I need to write a function that converts a Julian dates (Year, Day of Year, Hour of Day and Minutes) into a standard form (Year, Month, Day of Month, Hour of Day and Minutes) and express it as a string. I figure there's got to be someone who's already written a library or component which can do the conversion from Day Of Year to Month and Day of Month. I've looked at several well-known datetime libraries:
- ctime - Specifically using a tm struct and
mktime(tm *timeptr)
as this generally sets the values of the tm struct to the appropriate places except that "The original values of the members tm_wday and tm_yday of timeptr are ignored..." which doesn't help. - Boost::DateTime - Gregorian is constructed
date(greg_year, greg_month, greg_day)
which doesn't help. However, they do have adate_from_tm(tm datetm)
but "The fields: tm_wday , tm_yday , tm_hour, tm_min, tm_sec, and tm_isdst are ignored." Again, no help. - COleDateTime - This project contains COM so why not? The COleDateTime constructor
COleDateTime( int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec )
doesn't help. And I don't see any other conversion functions to go with it.
As you can see, these all need Month and Day of Month which is exactly what I'm trying to avoid in the first place. I must be either missing something or haven't looked in the right places (not perfect, as much as I try.)
Anyone can help? I'd prefer to avoid writing my own as there's almost always bound to be some gotcha I miss.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我偶然发现了这个老问题,并认为我可以添加一些新信息。我由 Thomas Pornin 撰写的现有答案是一个很好的答案,我已经投票了。然而,我将其视为改善它的挑战。如果我们能以两倍的速度得出相同的答案怎么办?也许更快?
为了测试这项工作,我将 Thomas 的答案包装在一个函数中:
我改进它的尝试基于:
上面的文章没有直接解决这种情况。然而,它确实详细描述了涉及日期操作的算法,甚至包括“一年中的某一天”概念,尽管该概念与此问题中指定的概念不同:
在这个问题中,“一年中的某一天”是 1基于 1 月 1 日的计数为一年的开始(1 月 1 == 第 1 天)。 chrono 兼容的低级日期算法 在算法中具有类似的“一年中的某一天”概念
civil_from_days
但现在已经是 3 月 1 日过去的日子了(3 月 1 日 ==第 0 天)。我的想法是,我可以从
civil_from_days
中挑选一些零碎的东西创建一个新的ymd_from_ydoy
,它不需要迭代 12 个月即可找到所需的结果。这就是我的想法:仍然有分支机构,但数量较少。为了测试此替代方案的正确性和性能,我编写了以下内容:
此测试中有三个循环:
事实证明,这两种算法都非常快……在我正在测试的 iMac Core i5 上只需几纳秒。因此引入皮秒来获得纳秒分数的一阶估计。
我想指出两件事:
std::chrono
让与皮秒的互操作变得如此简单,这有多酷?对我来说,这个测试打印出(大约):
表明
ymd_from_ydoy2
比ymd_from_ydoy1
快大约 3.3 倍。希望这有帮助。从这个答案中可以得到的重要信息:
在测量非常快的函数时可以非常灵活。比非常快快三倍仍然是一个不错的胜利。I stumbled across this old question, and thought I might be able to add some new information to it. The single existing answer as I write this by Thomas Pornin is a good answer, and I've upvoted it. However I've taken it as a challenge to better it. What if we could produce the same answer twice as fast? Maybe even faster?
To test this effort, I've wrapped Thomas' answer up in a function:
And my attempt to better it is based off of:
The above article does not address this situation directly. However it does go into detailed descriptions of the algorithms involved with date manipulations, and even includes a "day of year" concept, though that concept is different than what is specified in this question:
In this question "day of year" is a 1-based count with Jan 01 being the start of the year (Jan 1 == day 1). chrono-compatible Low-Level Date Algorithms has a similar "day of year" concept in the algorithm
civil_from_days
but it is days past Mar 01 (Mar 1 == day 0).My thought is that I could pick bits and pieces from
civil_from_days
and create a newymd_from_ydoy
which did not need to iterate over the 12 months to find the desired result. Here is what I came up with:There are still branches, but fewer of them. To test both the correctness and performance of this alternative I wrote the following:
There are three loops in this test:
It turns out that both algorithms are wicked fast ... a handful of nanoseconds on the iMac Core i5 I'm testing on. And thus the introduction of picoseconds to get a first-order estimate of fractional nanoseconds.
I'd like to point out two things:
std::chrono
makes it so easy to interoperate with picoseconds?For me this test prints out (approximately):
Indicating that
ymd_from_ydoy2
is approximately 3.3 times faster thanymd_from_ydoy1
.Hope this helps. Important things to get from this answer:
<chrono>
can be very flexible in measuring very fast functions. Three times faster than very fast is still a good win.从一年中的一天计算出月份和月份中的日期似乎很容易。这应该可以做到:
请注意,这计算一月份从零开始的月份,但假设天数(一年中的某一天或一个月中的某一天)从一开始。如果一年中的日期计数无效(超出年底),则生成的
月
值为 12(“12 月之后的月份”)。“儒略历”是一个混乱的根源,因为它也代表与公历相差几十天的“儒略历”以及闰年的计算。在这里,我只是假设您只想在给定的公历年份的上下文中将“一年中的某一天”计数转换为“月份和月份中的某一天”。
It seems easy to compute the month and day of month from the day of year. This should do it:
Note that this computes the month starting with zero for January, but assumes that day counts (either day of year or day of month) start at one. If the day of year count is invalid (beyond the end of the year) then the resulting
month
value is 12 (the "month after December")."Julian" is a source of confusion, since it also stands for the "Julian calendar" which differs from the Gregorian calendar by a few dozen days, and the computation of leap years. Here I just assumed that you just wanted to convert a "day of year" count into a "month and day of month" within the context of a given, Gregorian year.