2013-07-13 80 views
0

我試過尋找一種算法,可以實現這一點,但沒有拿出任何結果。如何將一年中的一天(1-365)轉換爲它的等效日期(即2013年1月5日)C++

我有構造函數Date2013(int dd)。

在這個成員函數我創建了它與個月陣列(一月,二月,等等)

然後,我創建了一個聲明,如果發生在DD,DD是否1天-31之間落在,然後1月份的產量,如果在32-59之間,那麼產出2月份。

我在遇到麻煩的是,然後把他們輸入的數字,dd,並將其轉換爲當月的適當日期。即(今年的第34天是2月2日)。

有沒有人知道任何算法或知道我可以做到這一點?

(我剛開始學習我的C++所以在任何代碼的解釋或意見,將是非常有用的,這樣我能理解你的思維過程和語法)

+0

轉換'YEAR-01-01 00:00:00'到時代。加'(天 - 1)* 3600 * 24'秒,然後轉換回日期。 – syam

+0

我會確定一年的第一天的時間戳,然後添加'(day-1)* 24 * 60 * 60'並將新的時間戳轉換爲日期。這會給你一個你想要的格式的日期。 – gpalex

+0

你到目前爲止嘗試過什麼 - 我問的原因是要了解你正在採取哪種方法,以便我們能給你「正確的」答案。使用C的 –

回答

5

最輕便&可靠的方法是使用ANSI C的mktime &本地時間功能,這將是C或者C++

更新工作:

回答有關如何實現自己的算法,而不是使用標準C庫米問題ktime函數,一個好的起點是查看已知的代碼,例如the glibc mktime source code。你會需要相關的花絮包括:

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:

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++類實現一個轉換年&構造dayOfYear到相應的月份& dayOfMonth可能看起來像這樣:

#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; 
}; 

希望我不會因爲顯示可能完成這項工作的示例代碼而投票贊成。隨意實現它,然而你想要的當然。這只是一個示例方法。


如果你寧願使用現有mktime功能(推薦),這應該最有可能出現在你的編程在任何平臺上的標準C庫,我原來的答覆內容如下...

當使用mktime你需要確保設置tm_mon = 0和tm_mday到一年(see mktime documentation for a better explanation)的日子,但簡而言之mktime忽略tm_wday和tm_yday只有轉化tm_mday,它本質上解釋爲如果您還設置了tm_mon = 0;

下面是說明了這一點,這將在C或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; 
} 

編譯&樣品運行:

$ 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:

$ ./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 
+0

+1尼斯解決方案。甚至不需要增強。 – 2013-07-13 21:48:53

+0

@ H2CO3有趣的是,因爲這幾乎是我在評論中所說的 - 除非我懶得拿出一個完整的答案。 ;)(+1也是,順便說一下) – syam

+1

雖然我同意這是一個很好的解決方案,但我不相信它會教會初學者如何編寫代碼 - 我懷疑OP是在尋找使用小陣列/矢量實際解決問題的方法每月的天數並計算它 - 給予初學者的地位,這樣做可以在循環,數組等方面做更多的練習,而不是填充結構和調用庫函數。 –

1

所以,對於這個計算的基本原理是哈有一個「每月天數」的列表,基本上。

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

如果我們再有一個名爲days變量,它是一年中的天數和month指示我們結束這一個月:

開始與「月= 1;」,只需檢查如果days小於days_in_month[month],如果不是從天減去days_in_month[month],並繼續下去,直到你要麼到達月= 12,仍然有更多的天,天比days_in_month[month] [這意味着它明年更多,重新來過與month=1,並移動到下一個year - 但我認爲你的任務被限制在1-3 65天,所以只報告一個錯誤現在罰款]。

當天數不超過days_in_month[month]多,你有天到該月的數量。

請注意,我有意爲而不是寫了如何做到這一點的代碼,但描述瞭如何做到這一點。因爲我是至少有幾次寫這類代碼的人,而你是那個試圖學習的人。你不會通過複製和粘貼來學習。

編輯:是的,我已經完全忽略了飛躍年。對於2013年,它不是一個閏年,所以我們不關心...;)

相關問題