简体   繁体   English

计算 C 中两个日期之间的天数 – 将日期转换为天数

[英]Calculate the number of days between two dates in C – Convert date to days

Recently, I found myself in the need to know the number of days separating two dates for a little program I was writing in C.最近,我发现自己需要知道我在 C 中编写的一个小程序的两个日期之间的天数。

I searched online for a solution but found nothing for C.我在网上搜索了解决方案,但没有找到 C。

How could I do it?我怎么能做到?

There are basically two ways of doing this:基本上有两种方法可以做到这一点:

  1. Use standard tools.使用标准工具。 Use the standard library function mktime to construct a time_t value corresponding to each date.使用标准库 function mktime构造每个日期对应的time_t值。 Then subtract, and convert the difference to units of days.然后减去,并将差值转换为天数单位。
  2. Write your own little ad-hoc code to construct a form of Julian day number .编写您自己的小临时代码来构造一种Julian day number形式。 Again, subtract.再次,减去。 This is at least a little bit complicated, full of fussy little details that are difficult to get right, but it's a great and satisfying exercise.这至少有点复杂,充满了难以正确处理的繁琐小细节,但这是一个很棒且令人满意的练习。 ("Satisfying", at least, if you're a time nurd.) (“令人满意”,至少,如果你是个时间狂人的话。)

Method number 1 looks like this:方法 1 如下所示:

#include <stdio.h>
#include <time.h>
#include <math.h>

int main()
{
    struct tm tm1 = { 0 };
    struct tm tm2 = { 0 };

    /* date 1: 2022-09-25 */
    tm1.tm_year = 2022 - 1900;
    tm1.tm_mon = 9 - 1;
    tm1.tm_mday = 25;
    tm1.tm_hour = tm1.tm_min = tm1.tm_sec = 0;
    tm1.tm_isdst = -1;

    /* date 2: 1990-10-02 */
    tm2.tm_year = 1990 - 1900;
    tm2.tm_mon = 10 - 1;
    tm2.tm_mday = 2;
    tm2.tm_hour = tm2.tm_min = tm2.tm_sec = 0;
    tm2.tm_isdst = -1;

    time_t t1 = mktime(&tm1);
    time_t t2 = mktime(&tm2);

    double dt = difftime(t1, t2);
    int days = round(dt / 86400);

    printf("difference: %d days\n", days);
}

Filling out a struct tm like tm1 and tm2 is a little tricky.填写像tm1tm2这样的struct tm有点棘手。 The tm_year field is counted from 1900, so you have to subtract 1900 when filling it in, as shown. tm_year字段是从1900开始计算的,所以填写的时候要减去1900,如图。 The tm_mon field is 0-based, so you have to subtract 1 from the month number. tm_mon字段是从 0 开始的,因此您必须从月份数中减去 1。 You have to pick a time;你必须选择一个时间; here I've arbitrarily picked 00:00:00 midnight.在这里,我任意选择了午夜 00:00:00。 Finally, in the tm_isdst field you have to specify whether you're inputting a standard or daylight time (0 or 1), or if you don't know or care (-1).最后,在tm_isdst字段中,您必须指定您输入的是标准时间还是夏令时(0 或 1),或者您是否不知道或不关心(-1)。

Then the function mktime returns a time_t value corresponding to the date and time you specified.然后 function mktime返回与您指定的日期和时间相对应的time_t值。 time_t is usually a Unix count of UTC seconds since January 1, 1970, although strictly speaking the C Standard says it can have any implementation-defined encoding, so the safest way to subtract two time_t values is to use the difftime function, which returns a difference guaranteed to be in seconds. time_t is usually a Unix count of UTC seconds since January 1, 1970, although strictly speaking the C Standard says it can have any implementation-defined encoding, so the safest way to subtract two time_t values is to use the difftime function, which returns a差异保证以秒为单位。 As every time nurd knows, there are 86400 seconds in a day, so divide the difference-in-seconds by 86400, and you've got a number of days.每次 nurd 都知道,一天有 86400 秒,所以将秒差除以 86400,就得到了天数。

This all looks pretty straightforward, although there are a couple of subtleties to beware of.这一切看起来都很简单,尽管有一些微妙之处需要提防。 If you look carefully at the difftime differences you get, you will find that they are often not an exact multiple of 86400, if the two dates you specified happen to span a daylight saving time changeover.如果您仔细查看您得到的difftime差异,您会发现它们通常不是86400 的精确倍数,如果您指定的两个日期恰好跨越夏令时转换。 (If so, you had at least one day that was either 23 or 25 hours long.) That's why it's vital to round the result of dividing by 86400, as shown in the example code. (如果是这样,您至少有一天是 23 或 25 小时。)这就是为什么将除以 86400 的结果四舍五入至关重要的原因,如示例代码中所示。 Usually it's also a very good idea to fill in tm_hour as 12, not 0, since using noon (ie in the middle of day, not right at the midnight day changeover) can also help to avoid various anomalies.通常将tm_hour填写为 12 而不是 0 也是一个很好的主意,因为使用中午(即在中午,而不是在午夜一天转换)也有助于避免各种异常。

So that's method 1. Here's the beginning of method 2. We're going to write a function makejd that computes a modified " Julian day " number.这就是方法 1。这是方法 2 的开始。我们将编写一个 function makejd来计算修改后的“儒略日”数字。 In general, a Julian day number is one that increases from day to day, without regard to month and day boundaries.一般来说,儒略日数是一天一天增加的,不考虑月份和日期的界限。 For example, this makejd function is going to compute day number 154400 for today, September 25, 2022. September 1 was day number 154376, and the day before that, August 31, was day number 154375. For reasons we'll get to, these day numbers go all the way back to the year 1600, where January 1 was day number 1.例如,这个makejd function 将计算今天 2022 年 9 月 25 日的第 154400 天。9 月 1 日是第 154376 天,而前一天,8 月 31 日是第 154375 天。出于以下原因,我们将了解,这些天数 go 一直追溯到 1600 年,其中 1 月 1 日是第 1 天。

(In the real world, different Julian day numbering schemes use different base days. The official Julian Day numbers go back to 4713 BC; there's also an official "Modified Julian Day" or MJD number that's based on 1858.) (在现实世界中,不同的儒略日编号方案使用不同的基日。官方的儒略日编号 go 可追溯到公元前 4713 年;还有一个基于 1858 年的官方“修改儒略日”或 MJD 编号。)

Anyway, here's makejd :无论如何,这里是makejd

#define BASEYEAR 1600      /* must be a multiple of 400 */

long int makejd(int year, int month, int day)
{
    long int jdnum = 0;
    jdnum += (year - BASEYEAR) * 365L;
    jdnum += (year - BASEYEAR) / 4;
    jdnum -= (year - BASEYEAR) / 100;
    jdnum += (year - BASEYEAR) / 400;
    jdnum += monthcount(month - 1, year);
    jdnum += day;
    return jdnum;
}

I love this function, because the problem that it solves sounds very complicated at first, but the function itself looks halfway reasonable, and once you understand how it works it's downright simple.我喜欢这个 function,因为它解决的问题一开始听起来很复杂,但 function 本身看起来很合理,一旦你了解它是如何工作的,它就非常简单。

Basically, to count up the total number of days, since that base date in the far past, up to the date we care about, we have three pieces to worry about:基本上,要计算总天数,自从那个基准日期在很久以前,到我们关心的日期为止,我们需要担心三个方面:

  1. We'll have 365 days for every full year.我们每一年都有 365 天。
  2. Then we'll have some number of days corresponding to full months that have gone by from the start of the year, to the month we're in.然后我们将有一些天数对应于从年初到我们所在月份的整个月份。
  3. Finally, we have some number of days into the month we're in.最后,我们所在的月份还有几天。

(And then of course there are some leap year corrections, which I'll explain in a minute.) (当然还有一些闰年修正,我会在一分钟内解释。)

For example, if the base year was 2020 and we were worried about today's date (September 25, 2022), we'd have two years times 365 = 730 days, plus 243 (which is the sum of the lengths of the months January through August), plus 25, for a total of 998. (That'd be for a hypothetical base year of 2020. As mentioned, we're actually going to use 1600 as our base year.)例如,如果基准年是 2020 年并且我们担心今天的日期(2022 年 9 月 25 日),我们将有两年乘以 365 = 730 天,再加上 243(这是 1 月到8 月)加上 25,总共 998。(这是假设的 2020 年基准年。如前所述,我们实际上将使用 1600 作为基准年。)

So the makejd function simply performs those three calculations, plus the various leap year corrections.因此makejd function 只需执行这三个计算以及各种闰年校正。 The first line,第一行,

jdnum += (year - BASEYEAR) * 365L;

literally does step 1 above, computing the difference between the year we care about, and the base year, times 365. Step 2 is the line从字面上看上面的第1步,计算我们关心的年份和基准年之间的差异,乘以365。第2步是线

jdnum += monthcount(month - 1, year);

which uses a separate function to compute the total number of days in the months 1 through N, where N (that is, month - 1 ) is the month before the one we care about.它使用单独的 function 来计算从 1 到 N 月份的总天数,其中 N (即month - 1 )是我们关心的月份的前一个月。 Finally, step 3 is the very simple最后,第3步非常简单

jdnum += day;

where day is the day we care about. day是我们关心的日子。

And then we come to the leap year corrections.然后我们来到闰年修正。 Every 4 years is a leap year, so the line每 4 年是闰年,所以这条线

jdnum += (year - BASEYEAR) / 4;

takes the number of full years we care about, divided by 4, and that's a few more days we need to add in. (In other words, we have to add in one day for every four years that elapsed since our base year.)将我们关心的整年数除以 4,这就是我们需要添加的更多天数。(换句话说,我们必须为自基准年以来经过的每四年添加一天。)

But the rule is not quite that every fourth year is a leap year.但规则并不完全是每四年是闰年。 The actual rule for the Gregorian calendar we use is that every four years there's a leap year, except that every 100 years there's not a leap year (that is, 1900 was not a leap year), except that every 400 years there is a leap year, after all (that is, 2000 was a leap year).我们使用的公历的实际规则是每四年有一个闰年,除了每 100 年没有闰年(也就是说,1900 年不是闰年),除了每 400 年一个闰年毕竟是年(也就是说,2000 年是闰年)。 So those two lines所以这两行

jdnum -= (year - BASEYEAR) / 100;
jdnum += (year - BASEYEAR) / 400;

take care of subtracting out the every-100-years non leap years, and adding back in the every-400-years leap years.注意减去每 100 年的非闰年,并在每 400 年的闰年中加回。

Note that those simple expressions work if the base year is an exact multiple of 400. If we'd used some other base year (like 1850 or 1900 or 1970), there would have been a certain number of awkward ±1 fudge factors.请注意,如果基准年是 400 的精确倍数,则这些简单的表达式有效。如果我们使用其他基准年(如 1850 年或 1900 年或 1970 年),则会有一定数量的尴尬 ±1 虚假因素。

Now we can go back to the monthcount function.现在我们可以将 go 返回到月monthcount If we cared about the date "September 25", it's monthcount 's job to count up all the days in the full months January through August.如果我们关心日期“9 月 25 日”,那么monthcount的工作就是计算 1 月到 8 月整个月份的所有天数。 (Stated another way, monthcount computes the partial Julian day number of "September 0", setting us up to be able to add in the exact day we care about, like 25.) monthcount is simple and straightforward: (换句话说, monthcount计算“September 0”的部分儒略日数,使我们能够添加我们关心的确切日期,例如 25。) monthcount简单明了:

                     /* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */
int monthlengths[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

/* return total days from January up to the end of the given month */
int monthcount(int month, int year)
{
    int r = 0;
    for(int i = 1; i <= month; i++)
        r += monthlengths[i];
    if(isleap(year) && month >= 2)
        r++;
    return r;
}

This function uses a pre-initialized array monthlengths[] containing the lengths of each month.这个 function 使用包含每个月长度的预初始化数组monthlengths[] ("Thirty days hath September...") Since C arrays are 0-based, but we always think of January as being month number 1, to keep things simple this array "throws away" (wastes) cell 0, so that monthlengths[1] is 31 for January. (“30 天有九月......”)因为 C arrays 是从 0 开始的,但我们总是认为一月是第 1 个月,为了简单起见,这个数组“扔掉”(浪费)单元格 0,所以monthlengths[1]一月是 31。

This function is also a second place we have to worry about leap years.这个 function 也是我们不得不担心闰年的第二个地方。 In leap years, of course, February has 29 days.当然,在闰年,二月有 29 天。 So if this is a leap year, and if we're being asked to compute the count of days in months through February or beyond, we have to add in one more day.因此,如果这是闰年,并且如果我们被要求计算到 2 月或以后的月份天数,我们必须再增加一天。 (That's why the monthcount function needs to have the year number passed in also.) (这就是为什么月份计数monthcount也需要传入年份。)

The only remaining detail is that little isleap function that monthcount uses as part of its decision of whether to add in February 29. It's simply:唯一剩下的细节是, isleap在 2 月 29 日决定是否添加时使用的小岛monthcount 。它很简单:

int isleap(int year)
{
    return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}

, using the formulation from question 20.32 of the C FAQ list . ,使用C 常见问题解答列表问题 20.32中的公式。

...And that's it. ......就是这样。 Hopefully now the workings of the makejd function are clear, even if you choose not to use anything like it.希望现在makejd function 的工作原理很清楚,即使您选择不使用类似的东西。

And, speaking of that choice, it's worth asking: which way should you use, method 1 or method 2?而且,说到那个选择,值得一问:你应该使用哪种方式,方法 1 还是方法 2?

Most of the time, of course, it's better to use prewritten code if you can, rather than "rolling your own" or reinventing the wheel.当然,大多数时候,如果可以的话,最好使用预先编写的代码,而不是“自己动手”或重新发明轮子。 And when it comes to code for dealing with dates and times, that advice ("use somebody else's prewritten code") is doubly or even triply valid, because dates and times are notoriously complex, and it's ridiculously easy (almost guaranteed) to get at lest one of the obscure details wrong, resulting in subtle bugs.当涉及到处理日期和时间的代码时,这个建议(“使用别人的预先编写的代码”)是双重甚至三重有效的,因为日期和时间是出了名的复杂,而且它非常容易(几乎可以保证)得到以免其中一个晦涩的细节出错,导致细微的错误。

So I will almost always use method 1. In fact, it's usually worth going out of your way to figure out how to use the standard date/time functions, even to solve a problem that they're not an immediately obvious fit for.所以我几乎总是使用方法 1。事实上,通常值得你去弄清楚如何使用标准的日期/时间函数,甚至解决一个它们不是立即明显适合的问题。 (See, for example, this answer , where I contrive to use mktime to answer the question, "On what day of the week does a given month begin?".) (例如,参见这个答案,我设法使用mktime来回答这个问题,“给定月份从一周中的哪一天开始?”。)

Once in a while, though, you may find yourself in a situation where the standard functions aren't suitable, and in that case, knowing how to "roll your own" can be extremely useful.但是,有时您可能会发现自己处于标准函数不适合的情况,在这种情况下,知道如何“自己动手”可能非常有用。 Just be careful, and test your code thoroughly, for lots of different dates and times!请小心,并针对许多不同的日期和时间彻底测试您的代码! (Situations where you might need to roll your own are when you're working with far-past or far-future dates that type time_t might not be able to handle, or when you're working in an embedded environment where you don't have a full C library available.) (您可能需要自己滚动的情况是,当您处理类型time_t可能无法处理的遥远过去或遥远未来的日期时,或者当您在嵌入式环境中工作时,您不能有一个完整的 C 库可用。)

The other way to choose might be to just look at which code is shorter or simpler.另一种选择方法可能是只看哪些代码更短或更简单。 Method 1 is a bit more cumbersome than I'd like, mostly because filling in all the fields of a struct tm one by one is a plain nuisance.方法 1 比我想要的要麻烦一些,主要是因为一个一个地填写struct tm的所有字段是一件很麻烦的事情。 Method 2 is a bit longer, although not actually all that much longer.方法 2 有点长,尽管实际上并没有那么长。 (It looks quite a bit longer here, but that's just because I've surrounded it with so much longwinded explanation.) (这里看起来有点长,但那只是因为我用了很多冗长的解释来包围它。)


Footnote: I said "I love this function", and I do, but I confess it's got one blemish, a violation of the DRY principle.脚注:我说过“我喜欢这个功能”,我确实喜欢,但我承认它有一个缺陷,违反了DRY原则。 The Gregorian leap year rules are embedded twice, once in the lines公历闰年规则被嵌入两次,一次在行中

jdnum += (year - BASEYEAR) / 4;
jdnum -= (year - BASEYEAR) / 100;
jdnum += (year - BASEYEAR) / 400;

in makejd , and then a second time, completely separately, in the isleap function.makejd中,然后第二次完全分开,在isleap中。 If we ever change calendars, someone will have to remember to change the rules in both places.如果我们更改日历,则必须有人记得更改两个地方的规则。 (I'm not joking, DRY is a splendid principle, and I do like to follow it when I can. and this is definitely a violation, But exploring the possibility of applying the principle here will have to be a topic for another day, as I've already written about 3× as much here as I intended to. and it's time to go get the furnace ready for the winter.) (我不是在开玩笑,DRY 是一个很棒的原则,我愿意尽可能地遵循它。这绝对是违规的,但是在这里探索应用该原则的可能性将不得不成为另一天的话题,因为我已经在这里写了我打算写的 3 倍。现在是时候让 go 为冬天准备好炉子了。)

I have created a function which converts a date to the number of days that have passed since 01/01/0001 until the input date:我创建了一个 function ,它将日期转换为自 01/01/0001 到输入日期以来经过的天数:

// Define a date data type.
struct date {
    int day, month, year;
};

/*
 * Function's limits (included):
     * bottom: 01/01/0001
     * top: 31/12/9999

 * Input: date data type.
 * Output: (int) number of days from 01/01/0001 to that date.
 */

unsigned long int convertDateToDays(struct date date){
    unsigned long int totalDays;
    int numLeap = 0;
    int monthsAddFromYearStart[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
    int i;

    // First, calculate the number of leap year since year one (not including date's year).
    for(i = 1; i < date.year; i++)
        if((i % 4 == 0 && i % 100 != 0) || (i % 4 == 0 && i % 400 == 0))
            numLeap++;

    // If it is a leap year, as of March there has been an extra day.
    if((date.year % 4 == 0 && date.year % 100 != 0) || (date.year % 4 == 0 && date.year % 400 == 0))
        for(i = 2; i < 12; i++)
            monthsAddFromYearStart[i]++;

    // (Year - 1) * 356 + a day per leap year + days totaling the previous months + days of this month
    totalDays = (date.year - 1) * 365 + numLeap + monthsAddFromYearStart[date.month - 1] + date.day;

    return totalDays;
}

This way you can convert two dates to days and then compare them very easily.通过这种方式,您可以将两个日期转换为天数,然后非常轻松地进行比较。 Here is an example:这是一个例子:

struct date startDate = {28, 02, 0465};
struct date endDate = {30, 06, 2020};
unsigned long int dateDifference, dateDifferenceLastDateIncluded;

dateDifference = convertDateToDays(endDate) - convertDateToDays(startDate);
dateDifferenceLastDateIncluded = convertDateToDays(endDate) - convertDateToDays(startDate) + 1;

printf("Difference in days: %lu.\n", dateDifference);
printf("Difference in days, last date included: %lu.", dateDifferenceLastDateIncluded);

/*
 * Output:
Difference in days: 625053.
Difference in days, last date included: 625054.
 */

Just define a date struct including day, month and year, and pass it to the convertDateToDays() function as a parameter.只需定义一个包含日、月和年的日期结构,并将其作为参数传递给 convertDateToDays() function。 Notice that the function returns an unsigned long int.请注意,function 返回一个 unsigned long int。 That's because the day count in extreme cases is huge (ie 31/12/9999).这是因为极端情况下的天数非常大(即 9999 年 12 月 31 日)。

You can convert now two dates to days and calculate the difference between them.您现在可以将两个日期转换为天数并计算它们之间的差异。 If you want to include the last date in the operation just add one day, as the example shows.如果您想在操作中包含最后日期,只需添加一天,如示例所示。

Hope this was helpful!希望这有帮助!

To solve this using standard funciotns:要使用标准功能解决此问题:

<time.h> offers struct tm , mktime() and difftime() . <time.h>提供struct tmmktime()difftime()

#include <limits.h>
#include <math.h>
#include <time.h>

// y1/m1/d1 - y0/m0/d0 in days
// Return LONG_MIN on error 
long days_diff(int y1,int m1,int d1,int y0,int m0,int d0) {
  // Important: Note other struct tm members are zero filled.
  // This includes .tm_isdst to avoid daylight savings time issues.
  struct tm date0 = { .tm_year = y0 - 1900, .tm_mon = m0 - 1, .tm_mday = d0 }; 
  struct tm date1 = { .tm_year = y1 - 1900, .tm_mon = m1 - 1, .tm_mday = d1 }; 
  time_t t0 = mktime(&date0);
  time_t t1 = mktime(&date1);
  if (t0 == -1 || t1 == -1) {
    return LONG_MIN;
  }
  double diff = difftime(t1, t0); // Difference in seconds
  const double secs_per_day = 24.0*60*60;
  return lround(diff/secs_per_day);  // Form the difference in `long` days.
}
  
  

To convert year, month, day Gregorian calendar to a day number , consider using the Modified Julian Day as the epoch.要将年、月、日公历转换为天数,请考虑使用修改后的儒略日作为纪元。 It is a well defined count of days from midnight, unlike the Julian date which starts at noon.它是从午夜开始的明确定义的天数,与从中午开始的儒略日期不同。
MJD 0.0 is November 17, 1858 midnight - local time. MJD 0.0 是当地时间 1858 年 11 月 17 日午夜。

Chances are good you can find well tested code that performs that named calculation.很有可能您可以找到执行该命名计算的经过良好测试的代码。

Unless code has been tested, be wary of its correctness.除非代码已经过测试,否则请注意其正确性。 Time functions have many corners cases that trip up seemingly good code.时间函数有许多角落情况,这些情况会使看似不错的代码出错。

Armed with that, simple subtract two day numbers to get the difference between dates.有了这个,简单地减去两天的数字来得到日期之间的差异。


Below is from an attempt from years ago.以下是多年前的一次尝试。

  • Handles all int values of year, month, day without overflow by using int2x math - a type with twice the bits of int .使用int2x math 处理年、月、日的所有int值而不会溢出 - 一种具有两倍int位的类型。 Note int may only be 16-bit.注意int可能只有 16 位。

  • A key features is simplification that shifts dates before March 1, to months of the prior year, making March the 1st month ( Oct ober the 8th month, Dec ember the 10th month, ...).一个关键特性是简化,将 3 月 1 日之前的日期转移到前一年的几个月,使 3 月成为第 1 个月( 10 月8 个月, 12 月10 个月,...)。 This harkens back to the Romans adding a leap day in the last month of the year - February.这可以追溯到罗马人在一年的最后一个月 - 二月添加闰日。

Note that the Gregorian calendar started in October 1582 and was only used by the majority of the planet sometimes in the early 1900s.请注意,公历始于 1582 年 10 月,仅在 1900 年代初期才被地球上的大部分地区使用。 For earlier dates, we could assume the Proleptic Gregorian calendar .对于较早的日期,我们可以假设Proleptic Gregorian calendar


#include <limits.h>
#include <stddef.h>
#include <stdint.h>

#if LONG_MAX/2/INT_MAX - 2 == INT_MAX
typedef long int2x;
#define PRId2x "ld"

#elif LLONG_MAX/2/INT_MAX - 2 == INT_MAX
typedef long long int2x;
#define PRId2x "lld"

#elif INTMAX_MAX/2/INT_MAX - 2 == INT_MAX
typedef intmax_t int2x;
#define PRId2x "jd"

#else
#error int2x not available

#endif


static const short DaysMarch1ToBeginingOfMonth[12] = { //
    0, 31, 61, 92, 122, 153, 184, 214, 245, 275, 306, 337};
#ifndef INT32_C
#define INT32_C(x) ((int_least32_t)1*(x))
#endif
#define DaysPer400Years   (INT32_C(365)*400 + 97)
#define DaysPer100Years   (INT32_C(365)*100 + 24)
#define DaysPer4Years     (365*4    +  1)
#define DaysPer1Year      365
#define MonthsPerYear     12
#define MonthsPer400Years (12*400)
#define MonthMarch        3
#define mjdOffset         0xA5BE1
#define mjd1900Jan1       15020
// November 17, 1858

// Example: 2015 December 31 -->  ymd_to_mjd(2015, 12, 31)
int2x ymd_to_mjd(int year, int month, int day) {

  int2x year2x = year;
  year2x += month / MonthsPerYear;
  month %= MonthsPerYear;
  // Adjust for month/year to Mar ... Feb
  while (month < MonthMarch) {
    month += MonthsPerYear;
    year2x--;
  }

  int2x d = (year2x / 400) * DaysPer400Years;
  int y400 = (int) (year2x % 400);
  d += (y400 / 100) * DaysPer100Years;
  int y100 = y400 % 100;
  d += (y100 / 4) * DaysPer4Years;
  int y4 = y100 % 4;
  d += y4 * DaysPer1Year;
  d += DaysMarch1ToBeginingOfMonth[month - MonthMarch];
  d += day;
  // November 17, 1858 == MJD 0
  d--;
  d -= mjdOffset;
  return d;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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