将日期/时间转换为时间戳,反之亦然 [英] Convert date/time to time-stamp and vice versa

查看:258
本文介绍了将日期/时间转换为时间戳,反之亦然的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在C两个简单的转换器中实现日期/时间到时间戳,反之亦然,而不依赖于时间库例程,如mktime等。



时间戳以秒为单位,日期/时间结构采用以下格式:




  • unsigned char年份:0到99(代表范围2000到2099)


  • unsigned char month:1到12


  • unsigned char day:1到31


  • unsigned char hour:0到23


  • unsigned char minute:0到59


  • unsigned char second:0到59




我想对dt2ts转换器发表第二个意见(假设输入是合法的):

  unsigned int dt2ts(const dt_t * dt)
{
static unsigned short days [] = {0,31,59,90,120,151,181,212,243,273,304,334};
return(((dt-> year * 365 + dt-> year / 4)+ days [dt-> month-1] + dt-> day)* 24 + dt->小时)* 60 + dt->分钟)* 60 + dt->秒;
}

除此之外,我希望有一些帮助完成ts2dt转换器: / p>

  void ts2dt(unsigned int ts,dt_t * dt)
{
dt-> second = ts %60; ts / = 60;
dt-> minute = ts%60; ts / = 60;
dt-> hour = ts%24; ts / = 24;
dt-> day =
dt-> month =
dt-> year =
}

感谢

解决方案

OP全部准备好处理小时,分,秒。注意:从2000年1月1日到2099年12月31日的天数至少需要一个16位整数。即使 unsigned 是2个字节,以下内容应该可以工作。

  unsigned DivRem无符号股息,无符号除数,无符号*余数){
unsigned Quotient =股息/除数;
*剩余=股息 - 商数*除数;
return Quotient;
}

void Day2000ToYMD(unsigned DaySince2000Jan1,unsigned * Y,unsigned * M,unsigned * D){
unsigned OlympiadDay; //每4年是一个奥运会
* Y = 4 * DivRem(DaySince2000Jan1,365 * 4 + 1,& OlympiadDay);
* D = 1;
if(OlympiadDay> =(31 + 29-1)){//处理2月29日和之后
OlympiadDay--;
if(OlympiadDay ==(31 + 29-1)){
(* D)++;
}
}
unsigned YearDay; //年的日子0到364
* Y + = DivRem(OlympiadDay,365和& YearDay);
static const unsigned short days [] = {0,31,59,90,120,151,181,212,243,273,304,334,365};
* M = 1;
while(days [* M] <= YearDay)(* M)++;
* D + = YearDay - days [* M - 1];
}






答案提供的尝试将年度的概念保持在1月1日至12月31日。由于这个答案不是需要处理大约100和400年的闰年,所以我一直保持着这种风格。一般来说,一旦添加了这2条规则,如果将年初的时间从3月1日开始转移到28/29,则数学变得更加容易。 FWIW,这个是对Julian / Gregorian日历古代发展的更一致的观点。因此* 10月10日 * ober是第8个月,而* 12月 * ember是第10个月。


I am trying to implement in C two simple convertors, date/time to time-stamp and vice versa, without any dependencies on time library routines, such as mktime, etc.

The time-stamp is in seconds, and the date/time structure is in the following format:

  • unsigned char year: 0 to 99 (representing the range 2000 to 2099)

  • unsigned char month: 1 to 12

  • unsigned char day: 1 to 31

  • unsigned char hour: 0 to 23

  • unsigned char minute: 0 to 59

  • unsigned char second: 0 to 59

I would like to have a second opinion on the dt2ts convertor (assuming that the input is legal):

unsigned int dt2ts(const dt_t* dt)
{
    static unsigned short days[] = {0,31,59,90,120,151,181,212,243,273,304,334};
    return ((((dt->year*365+dt->year/4)+days[dt->month-1]+dt->day)*24+dt->hour)*60+dt->minute)*60+dt->second;
}

In addition to that, I would appreciate some help completing the ts2dt convertor:

void ts2dt(unsigned int ts,dt_t* dt)
{
    dt->second = ts%60; ts /= 60;
    dt->minute = ts%60; ts /= 60;
    dt->hour   = ts%24; ts /= 24;
    dt->day    = ?????;
    dt->month  = ?????;
    dt->year   = ?????;
}

Thanks

解决方案

OP is all ready well handling the hours, minutes, seconds. Just a bit of assist on Y,M,D.

Note: The number of days from Jan 1, 2000 to Dec 31, 2099 needs at least a 16 bit integer. Following should work even if unsigned is 2 bytes.

unsigned DivRem(unsigned Dividend, unsigned Divisor, unsigned *Remainder) {
  unsigned Quotient = Dividend/Divisor;
  *Remainder = Dividend - Quotient*Divisor;
  return Quotient;
}

void Day2000ToYMD(unsigned DaySince2000Jan1, unsigned *Y, unsigned *M, unsigned *D) {
  unsigned OlympiadDay;  // Every 4 years is an Olympiad
  *Y = 4*DivRem(DaySince2000Jan1, 365*4+1, &OlympiadDay);
  *D = 1;
  if (OlympiadDay >= (31+29-1)) {  // deal with Feb 29th and after
    OlympiadDay--;
    if (OlympiadDay == (31+29-1)) {
      (*D)++;
    }
  }
  unsigned YearDay;      // Day of the year 0 to 364
  *Y += DivRem(OlympiadDay, 365, &YearDay);
  static const unsigned short days[] = {0,31,59,90,120,151,181,212,243,273,304,334,365};
  *M = 1;
  while (days[*M] <= YearDay) (*M)++;
  *D += YearDay - days[*M - 1];
}


[Edit] The answer provided tries to keep the concept of the year as Jan 1 to Dec 31. As this answer does not need to handle the leap year years about 100 and 400 years, I've kept with this style.

In general, once those 2 rules are added, the math becomes easier to if one shifts the beginning of the year to March 1 and ending on Feb 28/29. FWIW, this is a more consistent view of the ancient development of the Julian/Gregorian calendar. Thus *Oct*ober is then the 8th month and *Dec*ember is the 10th month.

这篇关于将日期/时间转换为时间戳,反之亦然的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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