arduino日付関数

arduino日付関数

・UNIX環境で使われる1970/1/1 00:00:00からの秒数と日時の相互変換関数
・日付関数の呼び出しは少ないので速度は犠牲、わかり易さ優先


2014-07-18

arduinoスケッチ
0001  //----------------------------------------------------------------
0002 // 日時 <-> 1970/1/1 00:00:00からの秒数(UNIXの日付) 相互変換
0003 //----------------------------------------------------------------
0004 #define SECONDS_IN_DAY 86400 // 24 * 60 * 60
0005 #define SECONDS_IN_HOUR 3600 // 60 * 60
0006
0007 typedef struct {
0008 int year;
0009 byte month;
0010 byte day;
0011 byte hour;
0012 byte min;
0013 byte sec;
0014 } date_time;
0015
0016 date_time tm;
0017 void unix_time_to_date( unsigned long unix_datetime, date_time *tm );
0018
0019 //----------------------------------------------------------------
0020 // 西暦0年1月1日からの日数を返す
0021 //----------------------------------------------------------------
0022 unsigned long calc_0_days(int year, byte month, byte day) {
0023 unsigned long days;
0024 int daysinmonth_ruiseki[12] = {0,31,59,90,120,151,181,212,243,273,304,334};
0025
0026 year--; // 当年は含まず
0027 days = (unsigned long)year * 365;
0028 days += year / 4; // 閏年の日数を足しこむ
0029 days -= year/100; // 閏年で無い日数を差し引く
0030 days += year/400; // 差し引きすぎた日数を足しこむ
0031 days += (unsigned long)daysinmonth_ruiseki[month-1];
0032 if( is_leapyear( year ) && 3 <= month ) {
0033 day++;
0034 }
0035 days += (unsigned long)day;
0036
0037 return days;
0038 }
0039
0040 //----------------------------------------------------------------
0041 // 西暦1970年1月1日からの日数を返す
0042 //----------------------------------------------------------------
0043 unsigned long calc_unix_days(int year, byte month, byte day) {
0044 unsigned long days;
0045
0046 return calc_0_days(year, month, day) - calc_0_days(1970, 1, 1);
0047 }
0048
0049 //----------------------------------------------------------------
0050 // 西暦1970年1月1日 00:00:00 からの秒数を返す
0051 //----------------------------------------------------------------
0052 unsigned long calc_unix_seconds(int year, byte month, byte day, byte hour, byte minutes, byte second) {
0053 unsigned long days;
0054 unsigned long seconds;
0055
0056 days = calc_unix_days(year, month, day);
0057 seconds = days * SECONDS_IN_DAY;
0058 seconds += (unsigned long)hour * SECONDS_IN_HOUR;
0059 seconds += (unsigned long)minutes * 60;
0060 seconds += (unsigned long)second;
0061 seconds += -9 * SECONDS_IN_HOUR; // JPN(GMT+9) 日本時間
0062
0063 return seconds;
0064 }
0065
0066 //----------------------------------------------------------------
0067 // 閏年か否かを返す
0068 //----------------------------------------------------------------
0069 boolean is_leapyear( int year )
0070 {
0071 if( (year % 400) == 0 || ((year % 4) == 0 && (year % 100) != 0)) {
0072 return true;
0073 } else {
0074 return false;
0075 }
0076 }
0077
0078 //----------------------------------------------------------------
0079 // Unixの日付を日時に変換 ループ処理しているので2msec程度かかる
0080 //----------------------------------------------------------------
0081 void unix_time_to_date( unsigned long unix_datetime, date_time *tm )
0082 {
0083 tm->year = 1970;
0084 tm->month = 1;
0085 tm->day = 1;
0086 tm->hour = 0;
0087 tm->min = 0;
0088 tm->sec = 0;
0089
0090 unsigned long yearindate;
0091 unsigned long seconds_year;
0092 unsigned long seconds_month;
0093 byte daysinmonth[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
0094
0095 unix_datetime += 9 * SECONDS_IN_HOUR;
0096 while( unix_datetime > 0 ) {
0097 if( is_leapyear(tm->year) ) {
0098 yearindate = 366;
0099 daysinmonth[1] = 29;
0100 } else {
0101 yearindate = 365;
0102 daysinmonth[1] = 28;
0103 }
0104 seconds_year = yearindate * SECONDS_IN_DAY;
0105 seconds_month = daysinmonth[tm->month - 1] * SECONDS_IN_DAY;
0106 if( unix_datetime >= seconds_year ) {
0107 tm->year++;
0108 unix_datetime -= seconds_year;
0109 } else if( unix_datetime >= seconds_month ) {
0110 tm->month++;
0111 unix_datetime -= seconds_month;
0112 } else if( unix_datetime >= SECONDS_IN_DAY ) {
0113 tm->day++;
0114 unix_datetime -= SECONDS_IN_DAY;
0115 } else if( unix_datetime >= SECONDS_IN_HOUR ) {
0116 tm->hour++;
0117 unix_datetime -= SECONDS_IN_HOUR;
0118 } else if( unix_datetime >= 60 ) {
0119 tm->min++;
0120 unix_datetime -= 60;
0121 } else {
0122 tm->sec = (byte)unix_datetime;
0123 unix_datetime= 0;
0124 }
0125 }
0126 }
0127
0128 //---------------------------------------------------------------------------
0129 // arduino setup
0130 //---------------------------------------------------------------------------
0131 void setup() {
0132 unsigned long days;
0133 unsigned long unix_seconds;
0134 long a,b;
0135
0136 Serial.begin(9600);
0137
0138 unix_seconds = calc_unix_seconds( 2014,7,18,1,2,3 );
0139 Serial.println(unix_seconds);
0140 unix_time_to_date( unix_seconds, &tm );
0141
0142 Serial.println(tm.year);
0143 Serial.println(tm.month);
0144 Serial.println(tm.day);
0145 Serial.println(tm.hour);
0146 Serial.println(tm.min);
0147 Serial.println(tm.sec);
0148 }
0149
0150 //---------------------------------------------------------------------------
0151 // arduino loop
0152 //---------------------------------------------------------------------------
0153 void loop() {
0154 // nothing to do
0155 }
0156
0157 //--------- E N D -----------------------------------------------------------
行番号
解説
解説は無し 本文中のコメントを参照
サンプルスケッチ現物
ファイル ファイルタイプ 添付ファイルの解説
test_time.zip arduino スケッチ現物 ライブラリーは使用していないし、この関数はライブラリーでもない