如何将一年中的某天(1-365)转换为其等效日期(即2013年1月5日)C ++ [英] How can I convert the day of the year (1-365) to its equivalent date (ie. January 5th, 2013) C++

查看:113
本文介绍了如何将一年中的某天(1-365)转换为其等效日期(即2013年1月5日)C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图寻找一种可以实现此目标但没有得出任何结果的算法。

I've tried searching for an algorithm that could achieve this but haven't come up with any results.

我有构造函数Date2013(int dd)。

I have the constructor Date2013(int dd).

在此成员函数中,我创建了一个包含月份的数组(一月,二月等)

In this member function I created an array with the months in it (January, February, Etc)

然后,我创建了一个带dd的if语句,如果dd介于第1天-31之间,则输出1月,如果dd介于32-59之间,则输出2月。

Then I created an if statement that takes in dd, if dd falls in between day 1 -31, then output January, if it falls between 32 - 59, then output February.

我遇到的麻烦是,然后取他们输入的数字dd,并将其转换为月份中的适当日期。即(一年的第34天是2月2日)。

What I'm having trouble doing is, then taking the number they input, dd, and converting that to the appropriate day in the month. ie(The 34th day of the year is February 2nd).

有人知道任何算法还是我可以实现这一目标的方法?

Does anyone know of any algorithms or know of a way I could achieve this?

(我刚开始学习C ++,因此在任何代码中进行解释或注释都将非常有帮助,这样我就可以了解您的思维过程和语法)

(I'm just beginning to learn my C++ so an explanation or comments in any code would be really helpful so that I can understand your thought process and syntax)

推荐答案

最便携的&可靠的方法是使用ANSI C mktime& localtime函数,可与C或C ++一起使用

The most portable & reliable approach is to use the ANSI C mktime & localtime functions, which will work with either C or C++

更新:

要回答有关如何实现自己的算法而不是使用标准C库mktime函数的问题,一个好的出发点是查看已知有效的代码,例如 glibc mktime源代码。您需要的相关花絮包括:

To answer the question about how to implement your own algorithm rather than using standard C library mktime function, a good starting point would be to look at known-working code such as the glibc mktime source code. The relevant tidbits you would need include:

来自 glibc 2.17(HEAD)mktime.c 在141行附近:

#define TM_YEAR_BASE 1900

/* Return 1 if YEAR + TM_YEAR_BASE is a leap year.  */
static inline int
leapyear (int year)
{
  /* Don't add YEAR to TM_YEAR_BASE, as that might overflow.
     Also, work even if YEAR is negative.  */
  return
    ((year & 3) == 0
     && (year % 100 != 0
         || ((year / 100) & 3) == (- (TM_YEAR_BASE / 100) & 3)));
}

来自 glibc 2.17(HEAD)mktime.c 从第160行开始:

From glibc 2.17 (HEAD) mktime.c starting at line 160:

const unsigned short int __mon_yday[2][13] =
{
    /* Normal years.  */
    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
    /* Leap years.  */
    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
};

示例C ++类实现了可转换year& dayofYear到相应的月份& dayOfMonth可能类似于:

A sample C++ class implementing a constructor that converts year & dayOfYear to corresponding month & dayOfMonth might look something like:

#include <iostream>
using namespace std;

#define MONTHS_IN_YEAR 12

class MyDateClass {
public:
MyDateClass(int year, int dayOfYear) {
    int yearOffset = dayOfYear - TM_YEAR_BASE;
    int leapYearIndex = leapyear(year) ? 1 : 0;
    int daysInYear = leapYearIndex ? 366 : 365;

    this->year = year;
    this->dayOfYear = dayOfYear;

    if (dayOfYear >= 1 && dayOfYear <= daysInYear) {
        for (int mon = 0; mon < MONTHS_IN_YEAR; mon++) {
           if (dayOfYear <= __mon_yday[leapYearIndex][mon+1]) {
               month = mon + 1;
               dayOfMonth = dayOfYear - __mon_yday[leapYearIndex][mon];
               break;
           }
        }
    } else {
        cerr << "day of year must be between 1 and " << daysInYear << endl;
        month = 0;
        dayOfMonth = 0;
    }
}

// Get month 1=January, 12=December       
inline int getMonth() { return month; }

// Get day of month
inline int getDayOfMonth() { return dayOfMonth; }

// Get year
inline int getYear() { return year; }

// Get day of yar
inline int getDayOfYear() { return dayOfYear; }

private:
   int month;
   int dayOfMonth;
   int year;
   int dayOfYear;
};

希望我不会因为显示示例代码而感到沮丧。当然可以随意实施它。这只是一种示例方法。

Hopefully I won't get down-voted for showing sample code that might do the job. Feel free to implement it however you want of course. This is just one example approach.

如果您想使用现有的mktime功能(推荐),可以使用应该最有可能出现在您正在编程的任何平台上的标准C库中,我的原始答案内容如下...

使用mktime时,您需要请确保将tm_mon = 0和tm_mday设置为一年中的某一天(有关详细信息,请参阅mktime文档解释),但简而言之,mktime忽略了tm_wday和tm_yday,仅翻译了tm_mday,如果您还设置了tm_mon = 0,则本质上将其解释为一年中的某天;

When using mktime you need to be sure to set tm_mon=0 and tm_mday to the day of the year (see mktime documentation for a better explanation), but in a nutshell mktime ignores tm_wday and tm_yday and only translates tm_mday, which it essentially interprets as the day of the year if you also set tm_mon = 0;

以下是一些说明该点的有效示例代码,它们将在C或C ++中工作:

Here is some working sample code that illustrates the point, which will work in C or C++:

#include <stdio.h>      /* printf, scanf */
#include <time.h>       /* time_t, struct tm, time, mktime */
#include <strings.h>    /* bzero */

int main () {
   time_t loctime;
   struct tm timeinfo, *loctimeinfo;
   int year, day;

   /* prompt user for year and day-of-the-year */
   printf ("Enter year: "); scanf ("%d",&year);
   printf ("Enter day of the year: "); scanf ("%d",&day);

   /* initialize timeinfo and modify it to the user's choice */
   bzero(&timeinfo, sizeof(struct tm));
   timeinfo.tm_isdst = -1;  /* Allow mktime to determine DST setting. */
   timeinfo.tm_mon   = 0;
   timeinfo.tm_mday = day;
   timeinfo.tm_year = year - 1900;

   loctime = mktime (&timeinfo);
   loctimeinfo = localtime(&loctime);

   printf ("The date for that day of the year is %s.\n", asctime(loctimeinfo));

   return 0;
}

编译&示例运行:

Compile & sample runs:

$ g++ -o t2 t2.c
$ ./t2
Enter year: 2013
Enter day of the year: 1
The date for that day of the year is Tue Jan  1 00:00:00 2013

$ ./t2
Enter year: 2013
Enter day of the year: 365
The date for that day of the year is Tue Dec 31 00:00:00 2013

即使在2012年这样的leap年都可以使用:

Even works for leap years like 2012:

$ ./t2
Enter year: 2012
Enter day of the year: 366
The date for that day of the year is Mon Dec 31 00:00:00 2012

这篇关于如何将一年中的某天(1-365)转换为其等效日期(即2013年1月5日)C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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