1990年1月1日からの日数で日付を表す変数があります。それを行う方法を知っている人はいますか?私はMCS8051を使用しているため、スクリプト、標準ライブラリ関数、またはメモリ割り当て(mallocまたはcalloc)を使用できません。また、これは宿題ではありません。どんな助けでもありがたいです。
2 に答える
私はあなたにヒントをあげる:
$ date --date 'jan 1 1990' +%s
631148400
これは 1990 年 1 月 1 日の「エポック日付」です。Unix エポックからの秒数で表されます。これは POSIX システムでのみ有効であることに注意してください。
利用可能な標準ライブラリ関数がないことを明らかにしたので、事前に計算されたエポック時間を開始として使用し、それに追加days * 86400
することをお勧めします。
残念ながら、その演算を処理するのに十分な大きさの整数型はないと思います。以来:
log(633826800, 2) = approx. 29.23951342
Unix エポック自体の値を保持するには、少なくとも 32 ビット型が必要です。
たとえば、32 ビットuint32_t
型の場合、次のことができます。
uint32_t days_to_epoch_date(int days)
{
uint32_t ret = 631148400L; /* value for Jan 1 1990 */
ret += 86400 * days;
return ret;
}
別のエポックまたはスケールを使用する必要がある場合、値は異なりますが、方法は同じままです。まあ、時間測定が線形である限り。
次の例は、新しい情報では正しくありませんが、標準ライブラリを使用できる人が見つけられる場合に備えて残しています。
コードを移植可能にするために、最初にエポック日付を次のように組み立てますstruct tm
。
#include <time.h>
time_t epoch_time_to_time_t(unsigned int days_since_epoch)
{
struct tm t = {0};
t.tm_mday = 1;
t.tm_mon = 0; /* Jan */
t.tm_year = 90; /* since 1900 */
t.tm_isdst = -1;
/* ... */
}
次に、*7.23.2.3 で許可されているように、mktime
関数:
2 […] 構造体の
tm_wday
およびtm_yday
コンポーネントの元の値は無視され、他のコンポーネントの元の値は上記の範囲に制限されません。
…日数を に追加し、struct tm
使用mktime()
して最終的な を取得しtime_t
ます。
time_t epoch_time_to_time_t(unsigned int days_since_epoch)
{
/* ... */
t.tm_mday += days_since_epoch;
return mktime(&t);
}
膨大な量の日付と時刻の計算の詳細とアルゴリズムを集めた本があり、ほぼ間違いなくチェックする価値があります。標準 C (おそらく C89、確かに新しいものではありません) のソース コードでサポートされています。
Standard C Date/Time Library: Programming the World's Calendars and Clocks by Lance Latham、CMP、1998 年、ISBN 978-0879304966。
日付計算をゼロから始める必要がある場合、カレンダーには見逃しやすい特殊なケースがたくさんあるという理由だけで、これは優れたリソースになります。