1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
| /***********************************************************
2つの時刻(timespec)の平均を計算
DATE AUTHOR VERSION
2021.02.06 mk-mode.com 1.00 新規作成
Copyright(C) 2020 mk-mode.com All Rights Reserved.
----------------------------------------------------------
引数 : JST_1 JST_2
書式:最大23桁の数字
(先頭から、西暦年(4), 月(2), 日(2), 時(2), 分(2), 秒(2),
1秒未満(9)(小数点以下9桁(ナノ秒)まで))
***********************************************************/
#include <cstdlib> // for EXIT_XXXX
#include <ctime>
#include <iomanip>
#include <iostream>
#include <string>
/*
* @brief Time addition
*
* @param[in] 時刻A (timespec)
* @param[in] 時刻B (timespec)
* @return 時刻 (timespec)
*/
struct timespec time_add(struct timespec ts_a, struct timespec ts_b) {
struct timespec ts;
try {
ts.tv_sec = ts_a.tv_sec + ts_b.tv_sec;
ts.tv_nsec = ts_a.tv_nsec + ts_b.tv_nsec;
if(ts.tv_nsec >= 1e9){
++ts.tv_sec;
ts.tv_nsec -= 1e9;
}
if (ts.tv_nsec < 0) {
--ts.tv_sec;
ts.tv_nsec += 1e9;
}
} catch (...) {
throw;
}
return ts;
}
/*
* @brief Mean of 2 Timespec
*
* @param[in] 時刻A (timespec)
* @param[in] 時刻B (timespec)
* @return 時刻 (timespec)
*/
struct timespec time_mean(struct timespec ts_a, struct timespec ts_b) {
struct timespec ts;
long int a; // 商
long int r; // 剰余
try {
ts = time_add(ts_a, ts_b);
a = ts.tv_sec / 2;
r = ts.tv_sec - a * 2;
ts.tv_sec = a;
ts.tv_nsec += r * 1e9;
ts.tv_nsec /= 2;
if (ts.tv_nsec < 0) {
ts.tv_nsec += 1e9;
--ts.tv_sec;
}
} catch (...) {
throw;
}
return ts;
}
/*
* @brief 日時文字列生成
*
* @param[in] 日時 (timespec)
* @return 日時文字列 (string)
*/
std::string gen_time_str(struct timespec ts) {
struct tm t;
std::stringstream ss;
std::string str_tm;
try {
localtime_r(&ts.tv_sec, &t);
ss << std::setfill('0')
<< std::setw(4) << t.tm_year + 1900 << "-"
<< std::setw(2) << t.tm_mon + 1 << "-"
<< std::setw(2) << t.tm_mday << " "
<< std::setw(2) << t.tm_hour << ":"
<< std::setw(2) << t.tm_min << ":"
<< std::setw(2) << t.tm_sec << "."
<< std::setw(9) << ts.tv_nsec;
return ss.str();
} catch (...) {
throw;
}
}
int main(int argc, char* argv[]) {
unsigned int i;
std::string tm_str;
unsigned int s_tm; // size of time string
unsigned int s_nsec; // size of nsec string
struct tm t;
struct timespec ts[2]; // 時刻 A, B
struct timespec ts_m; // 時刻 A, B の平均
try {
// 日付取得
if (argc < 3) {
std::cout << "[USAGE] ./mean_timespec JST_1 JST_2" << std::endl;
return EXIT_SUCCESS;
}
// コマンドライン引数より取得
for (i = 0; i < 2; ++i) {
tm_str = argv[i + 1];
s_tm = tm_str.size();
if (s_tm > 23) {
std::cout << "[ERROR] Over 23-digits!" << std::endl;
return EXIT_FAILURE;
}
t = {};
std::istringstream is(tm_str);
is >> std::get_time(&t, "%Y%m%d%H%M%S");
ts[i].tv_sec = mktime(&t);
ts[i].tv_nsec = 0;
s_nsec = s_tm - 14;
if (s_tm > 14) {
ts[i].tv_nsec = std::stod(
tm_str.substr(14, s_nsec) + std::string(9 - s_nsec, '0'));
}
}
std::cout << " TIME-A: " << gen_time_str(ts[0]) << std::endl;
std::cout << " TIME-B: " << gen_time_str(ts[1]) << std::endl;
// 2つの時刻の平均を変換
ts_m = time_mean(ts[0], ts[1]);
std::cout << "MEAN(A, B): " << gen_time_str(ts_m) << std::endl;
} catch (...) {
std::cerr << "EXCEPTION!" << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
|