简体   繁体   中英

How to represent geological time? (Boost, Date_time?)

I'm trying to process timestep interval data. The data is of two formats:

1) each interval is explicitly set (eg, 1982-12-31, 1988-01-01T00:00:00);

or

2) a start date is set followed by offsets of seconds, minutes, hours, days, months, or years

I've been using a combination of boost::gregorian::date and boost::posix_time::ptime to manage this, and use the facilities to get nicely formatted strings. However, I've now been presented with data that covers 1.9 million years, with each timestep being approximately 10 years. The start date is 0 and the last interval is 7e8. Obviously, I've hit the limits.

Is there a way using Boost to represent such scale? My searching has led to the conclusion 'no' in which case we'll just write our own class.

This is a very interesting question. But reaching the limits of boost in this area requires careful thinking about the risk of going beyond the astronomical limits of today.

Calendars and dates are very relative:

  • Posix time is defined as time elapsed from January 1st, 1970, not counting the leap seconds. boost allows you to choose between the microsecond or the nanosecond resolution at build time.

  • The gregorian calendar is defined since October 15th, 1582. Note that before 1930, some countries used the gregorian calendar and some still the julian one, the transition resulting in some interesting facts , such as the absence of 13 september 1752 in England and America.

  • Before it was the Julian calendar, defined by J.Caesar in 45 BC. Note that while the format, the number of month and length of month is the same than in the gregorian calendar, there are 13 days of difference between both, that take into account accumulated differences over the years.

  • before 45BC, was there the old roman calendar which had 355 days/year.

  • And longer before, until begin of mankind there were certainly all sorts of other calendars. But a days wasn't always 24 hours long. The variations of 1 to 3 microsecond per day of the solar day add up if you go in the millions of years. For instance, 600 millions of years ago, the averge length of the day was only 22 hours.

If you're working on both geological and narrow scales the easiest approach coud be to use a class or a union combining a long long (for geological scale in years BC) and boost::gregorian::date (for years AC, if you can afford the imprecision julian/gregorian). The nice formating would then be relatively easy to organize.

Alternatively you could consider use of chrono with the longest integer type and a ratio indicating that you'r counting the years:

typedef chrono::duration<long long, ratio<31556926, 1>> duration_in_year;
duration_in_year d2(1900000); // 1,9M years
chrono::time_point<chrono::system_clock> t1 = chrono::system_clock::now() - d2;

but nice printout will not be so evident as with boost. And you'll have to define your own clock class (The example above will work with 1,9Mio years but not much more, due to the parameters used to instantiate the system_clock class).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM