我正在使用嵌入式Linux,自1970年1月1日以來系統/控制器時間保持爲毫秒的形式。我正在嘗試使用gmtime,但無法獲得準確的結果。任何將此時間(毫秒)轉換爲實時小時數:分鐘:秒:日:月的示例都會有所幫助。gmtime()函數是否考慮了閏年?
回答
不僅gmtime()
支持閏年,它也佔閏秒,這就是爲什麼它是tm_sec
場的範圍被定義爲0..60]包容性。
根據'C'標準,'gmtime()'不需要考慮閏秒,但它是被允許的。這個特點是沒有說明的。根據POSIX的說法,'gmtime()'不會佔用閏秒,因爲UTC時間1970-01-01T00:00:00時間__不包括它們。隨後,很少(如果有的話)'gmtime()'的實現佔用了閏秒(我知道沒有)。閏年,是的。閏秒,沒有。雖然你對'tm_sec'的範圍是正確的。在這方面,'struct tm'可以代表閏秒,而'time_t'不能。 –
@HowardHinnant「time_t」是否包含Linux和FreeBSD上的閏秒(可能還有其他人)是可配置的。當它包含閏秒時,它們的'gmtime()'可以返回'60'的'tm_sec'值。見http://coliru.stacked-crooked.com/a/622da23fd57dabca – hvd
@hvd:好的演示與'putenv(「TZ =右/ UTC」)',謝謝。 –
您可以使用在Howard Hinnant的chrono-Compatible Low-Level Date Algorithms中得到並詳細解釋的civil_from_days
。此函數自1970年1月1日以來計算天數,並將其轉換爲{y, m, d}
字段。一旦你完成了,你只需要處理從毫秒時間戳中減去天數,以便從午夜開始獲得毫秒數,然後將其分解爲h:M:s.ms
。
下面是完整的代碼:
#include <iostream>
#include <iomanip>
#include <cstdint>
int
main()
{
using namespace std;
int64_t t = 1490285505123; // milliseconds since epoch
int32_t z = (t >= 0 ? t : t - (1000*86400-1))/(1000*86400); // days since epoch
t -= z * (1000LL * 86400); // milliseconds since midnight
z += 719468;
int32_t era = (z >= 0 ? z : z - 146096)/146097;
int32_t doe = z - era * 146097;
int32_t yoe = (doe - doe/1460 + doe/36524 - doe/146096)/365;
int32_t y = yoe + era * 400;
int32_t doy = doe - (365*yoe + yoe/4 - yoe/100);
int32_t m = (5*doy + 2)/153;
int32_t d = doy - (153*m + 2)/5 + 1; // day
m += m < 10 ? 3 : -9; // month
y += m <= 2; // year
int32_t h = t/(1000 * 3600); // hour
t -= h * (1000 * 3600);
int32_t M = t/(1000 * 60); // minute
t -= M * (1000 * 60);
int32_t s = t/1000; // second
int32_t ms = t - s * 1000; // ms
cout.fill('0');
cout << setw(4) << y << '-' << setw(2) << m << '-' << setw(2) << d
<< ' ' << setw(2) << h << ':' << setw(2) << M
<< ':' << setw(2) << s << '.' << setw(3) << ms << '\n';
}
正如我已經用作輸入1490285505123ms
爲例,輸出爲:
2017-03-23 16:11:45.123
這需要閏年考慮在內。它不考慮閏秒。你的嵌入式linux系統/控制器也不太可能,所以嘗試這樣做是不正確的。
上述算法有t
一個非常大的有效範圍:
-5877641-06-23 00:00:00.000 <= t <= 5880010-09-09 23:59:59.999
(+/- 580萬年)
如果你不介意的制約t
到0000-03-01 00:00:00.000
下限那麼你可以簡化era
的計算爲:
int32_t era = z/146097;
如果你可以限制低l的t
到1970-01-01 00:00:00.000
IMIT那麼z
計算可以簡化爲:
int32_t z = t/(1000 * 86400); // days since epoch
最後,如果你願意限制t
到這家擁有400年份範圍:
2000-03-01 00:00:00.000 <= t <= 2400-02-29 23:59:59.999
然後era
可以變得簡單:
int32_t const era = 5;
FWIW,這裏是一個high-level date/time library撬動C++1分之11 4 <chrono>
庫執行完全相同的計算,只是清晰的語法。你的std :: lib將不得不支持<chrono>
來使用這個庫:
#include "date.h"
#include <iostream>
int
main()
{
using namespace date;
using namespace std;
using namespace std::chrono;
cout << sys_time<milliseconds>(1490285505123ms) << '\n';
}
- 1. 計算考慮閏年的java年齡
- 2. Ruby的時間庫是否考慮閏年
- 3. 來自幾年前的JavaScript時間戳,並考慮閏年
- 4. 計算兩個Date或Calendar對象之間的年數,考慮閏年
- 5. java date.before函數是否考慮了時區?
- 6. 檢查年份是否爲閏年
- 7. TimeZoneInfo是否考慮到了DST?
- 8. JS - 計算考慮閏年的兩個日期之間的天數
- 9. 是否使用Javascript承認閏年
- 10. 是否time.h允許閏年C
- 11. 模板參數演繹是否考慮了返回類型?
- 12. python timeit是否考慮設置計數
- 13. 提取特定月份和年份的總小時數,考慮到閏年,使用PHP
- 14. VBA Excel:我是否發現Excel在1900年處理「閏年」的錯誤? (這實際上並不是閏年)
- 15. 這個函數是否考慮過內聯?
- 16. 證明,如果該年是閏年
- 17. 1000年(和其他人)是閏年嗎?
- 18. 檢查今年是JavaScript的閏年
- 19. PHP - 如何檢查一年是否平分(即閏年)?
- 20. Calendar是否迎合了閏秒?
- 21. java.text.SimpleDateFormat閏年
- 22. 閏年方法
- 23. MySql閏年
- 24. 查找閏年
- 25. 閏年計劃
- 26. cf_ct_date_input和閏年
- 27. 閏年Java Q
- 28. 確定閏年
- 29. 閏年編程
- 30. 閏年FreePascal的
它當然應該。你說你得到的不準確結果的一個例子,以及產生它們的[mcve]會有所幫助 - 事實上,如果你想回答你的問題,這是非常重要的。 (你知道'tm_mday'是基於1的,'tm_mon'是基於0的,'tm_year'是基於1900的,對嗎?) –