且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

两个UNIX时间戳之间的人工可读持续时间

更新时间:2022-12-18 09:29:02

对于较早的日期,请使用闰年公式开始计算天数Unix开始日期,1970年1月1日到您的第一个时间戳

For the older date, use the Leap Year formula to start counting the number of days from Unix start date, Jan1st 1970, to your first timestamp

(对于闰秒,dunno如果你需要获得精确,希望会超出范围?

(For leap seconds, dunno if you need to get that precise, hopefully will be out-of-scope?)

通过约束日期到1600AD之后计算的闰年,
格雷戈里亚历法的算法:
http://en.wikipedia.org/wiki/Leap_year

Leap year calculated by constraining date to after 1600AD and the algorithm for the Gregorian Calendar from: http://en.wikipedia.org/wiki/Leap_year of

if year modulo 400 is 0
then is_leap_year
else if year modulo 100 is 0
then not_leap_year
else if year modulo 4 is 0
is_leap_year
else
not_leap_year

如果一年是闰年,那么2月有29天,

If a year is a Leap Year, then there are 29days in Feb, else 28days

现在您知道第一个变量的月份,day_of_month,年。

Now you know the month, day_of_month, year for the 1st variable

天到第二个时间戳,使用闰年公式,直到到达第二个时间戳。

Next, another set of counts of days to the 2nd timestamp, using the Leap Year formula till you get to the 2nd timestamp.

typedef struct {
  int year;
  int month;
  int dayOfMonth;
} date_struct;

static int days_in_month[2][13] = {
  {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
  {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
};

int isLeapYear(int year) {
  int value;
  value = year;

  //if year modulo 400 is 0
  //   then is_leap_year
  value = year % 400;
  if(value == 0) return 1;

  //else if year modulo 100 is 0
  //   then not_leap_year
  value = year % 100;
  if(value == 0) return 0;

  //else if year modulo 4 is 0
  //   then is_leap_year
  value = year % 4;
  if(value == 0) return 1;

  //else
  //   not_leap_year
  return 0;
}

date_struct addOneDay(date_struct ds, int isLeapYear){
  int daysInMonth;

  ds.dayOfMonth++;

  //If the month is February test for leap year and adjust daysInMonth
  if(ds.month == 2) {
    daysInMonth = days_in_month[isLeapYear][ds.month];
  } else {
    daysInMonth = days_in_month[0][ds.month];
  }

  if(ds.dayOfMonth > daysInMonth) {
    ds.month++;
    ds.dayOfMonth = 1;
    if(ds.month > 12) {
      ds.year += 1;
      ds.month = 1;
    }
  }
  return ds;
}

long daysBetween(date_struct date1, date_struct date2){
  long result = 0l;
  date_struct minDate = min(date1, date2);
  date_struct maxDate = max(date1, date2);

  date_struct countingDate;
  countingDate.year = minDate.year;
  countingDate.month = minDate.month;
  countingDate.dayOfMonth = minDate.dayOfMonth;

  int leapYear = isLeapYear(countingDate.year);
  int countingYear = countingDate.year;

  while(isLeftDateSmaller(countingDate,maxDate)) {
    countingDate = addOneDay(countingDate,leapYear);
    //if the year changes while counting, check to see if
    //it is a new year
    if(countingYear != countingDate.year) {
      countingYear = countingDate.year;
      leapYear = isLeapYear(countingDate.year);
    }

    result++;
  }

  return result;
}

(我写了一个开源程序,在C / C ++中,它的源代码,我上面提到的一些,可能会帮助给你灵感的自己的解决方案,或者也许你可以适应一些它, http://mrflash818.geophile.net/software/timediff/

(I wrote an open source program that gives the difference between two calendar dates, in C/C++. Its source code, some that I posed above, might help give you inspiration for your own solution, or maybe you can adapt some of it, too http://mrflash818.geophile.net/software/timediff/ )