两个UNIX时间戳之间的人工可读持续时间 [英] Human-readable duration between two UNIX timestamps

查看:112
本文介绍了两个UNIX时间戳之间的人工可读持续时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图计算两个UNIX时间戳之间的差异(即自1970年以来的秒数)。我想说3年,4个月,6天等,但我不知道如何解释闰年和不同持续时间的月份。这确实是一个解决的问题。?

I'm trying to calculate the difference between two UNIX timestamps (i.e. seconds since 1970). I want to say e.g. "3 years, 4 months, 6 days, etc" but I don't know how to account for leap years and months of different durations. Surely this is a solved problem..?

这与其他问题不同,其他问题要在一个单位中表示一个具有固定/均匀持续时间的大致持续时间小时或7周等)。 1月1日至1月1日的结果为1个月,1月1日至1月1日的结果也为1个月,即使天数不同。

This is different to other questions which want to express an approximate duration in one unit that has a fixed/homogeneous duration (e.g. 3 hours, or 7 weeks, etc.). Results for 1. Jan to 1. Feb would be "1 month" and results for 1. Feb to 1. Mar would also be "1 month" even though the number of days are different.

我想精确地表示完整的持续时间,但是以年/月/日/小时/分钟为单位。

I want to express the complete duration precisely but in years/months/days/hours/minutes. Solutions in C++ would be appreciated!

推荐答案

对于较早的日期,请使用闰年公式开始计算天数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/ )

这篇关于两个UNIX时间戳之间的人工可读持续时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆