我正在考虑使用TIMESTAMP存储日期+时间,但我读到它有2038年的限制.我没有大量提出我的问题,而是倾向于将其分解成小部分,以便新手用户也能轻松理解.所以我的问题:
提前致谢.
我想我今天写的一些软件将在30年内使用.但我也意识到,很多都是基于UNIX传统,即将时间暴露为自1970年以来的秒数.
#include <stdio.h>
#include <time.h>
#include <limits.h>
void print(time_t rt) {
struct tm * t = gmtime(&rt);
puts(asctime(t));
}
int main() {
print(0);
print(time(0));
print(LONG_MAX);
print(LONG_MAX+1);
}
Run Code Online (Sandbox Code Playgroud)
执行结果:
函数ctime(),gmtime()和localtime()都将一个时间值作为参数,该时间值表示自Epoch(1970年1月1日00:00:00 UTC;参见时间(3))以来的时间(以秒为单位).
我想知道作为程序员在这个领域是否有任何主动做的事情,或者我们是否相信所有软件系统(又称操作系统)将来会如何神奇地升级?
更新看起来确实64位系统是安全的:
import java.util.*;
class TimeTest {
public static void main(String[] args) {
print(0);
print(System.currentTimeMillis());
print(Long.MAX_VALUE);
print(Long.MAX_VALUE + 1);
}
static void print(long l) {
System.out.println(new Date(l));
}
}
Run Code Online (Sandbox Code Playgroud)
但那一年292278994呢?
我刚刚发现,运行日历脚本,PHP中的时间戳限制为2038.这究竟是什么意思?为什么是2038而不是2050或2039?如果时间戳只计算给定日期(1970年)的秒数,为什么限制?
在3238嵌入式Linux(ARMLinux)的C代码中处理时间的正确方法是什么,以确保代码在2038年1月19日03:14:07 UTC之后继续正常工作(当有符号的32位time_t
溢出时)?鉴于time_t
在我必须使用的系统上签名32位,有哪些替代方案?
大量的谷歌搜索没有发现任何实际用途.每个人似乎都认为到那时我们都将使用64位操作系统,但这显然不适用于嵌入式系统.
在我需要使用的系统上,__kernel_time_t
定义为a long
.这可能意味着64位时间没有内核工具.uClibc的版本是0.9.29.
我不敢相信我是唯一有这个问题的人,我不想重新发明轮子.
我想打印或提取年/月/日值.
我不想用time_t
,因为2038年的问题,但我在网上找到的所有例子都使用它来转换time_point
到tm
.
有没有一种简单的方法可以从time_point转换为tm(最好没有boost)?
就像一个实现timesub从libc的将是我的最后一招: http://www.opensource.apple.com/source/Libc/Libc-262/stdtime/localtime.c
编辑:在阅读建议的链接并进行更多研究后,我得出以下结论.
值得注意的是,Boost.Date_Time可以是仅限标头的库.资料来源:http: //www.boost.org/doc/libs/1_53_0/more/getting_started/unix-variants.html#header-only-libraries
2038年的Bug已经遍布网络,但这似乎是一个unix问题.这将如何影响Java Date?
我的理解是,由于PHP使用毫秒表示日期的性质,您无法表示过去2038年的日期.我有一个问题,我想在将来计算日期.数千年之后.
显然我不能使用php日期函数来代表这个日期,因为有限制,但是,我有一些东西在我身边......我想做的就是存储年,月和日.我不关心小时,分钟,秒和毫秒.
我是否正确地认为,如果不包含这些额外信息,我应该能够进一步计算未来,因为我愿意丢弃大量信息.这是目前正在执行此操作的库吗?如果没有,有任何建议如何解决这个问题?
我正在尝试最近的std::chrono
api,我发现在64位Linux体系结构和gcc编译器上time_point
,duration
类和类无法以最大分辨率(纳秒)处理操作系统的最大时间范围.实际上,似乎这些类的存储是一个64位的整数类型,相比于timespec
和timeval
其内部使用两个64位整数,一个用于秒,一个用于纳秒:
#include <iostream>
#include <chrono>
#include <typeinfo>
#include <time.h>
using namespace std;
using namespace std::chrono;
int main()
{
cout << sizeof(time_point<nanoseconds>) << endl; // 8
cout << sizeof(time_point<nanoseconds>::duration) << endl; // 8
cout << sizeof(time_point<nanoseconds>::duration::rep) << endl; // 8
cout << typeid(time_point<nanoseconds>::duration::rep).name() << endl; // l
cout << sizeof(struct timespec) << endl; // 16
cout << sizeof(struct timeval) << endl; // 16
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在64位Windows(MSVC2017)上,情况非常相似:存储类型也是64位整数.在处理稳定(也称为单调)时钟时这不是问题,但存储限制使得不同的API实现不适合存储更大的日期和更宽的时间跨度,从而为类似Y2K的错误创造了基础.这个问题得到了承认吗?是否有更好的实施或API改进的计划?
我需要在Centos 7.4 64位上使用php(5.4)将日期时间信息从本地时间(gtm + 1)转换为UTC
我尝试了以下程序:
function convertToUtc ($date)
{
$dateTime = new DateTime ($date, new DateTimeZone('Europe/Rome'));
$dateTime->setTimezone(new DateTimeZone('UTC'));
return $dateTime->format('Y-m-d') . 'T' . $dateTime->format('H:i:s') . 'Z';
}
Run Code Online (Sandbox Code Playgroud)
这工作到2038年之后,它错误地计算DST总是返回1小时的偏移量:
2037:一切都好
LOCAL TIME -> UTC TIME
2037-03-28 10:12:13 -> 2037-03-28T09:12:13Z the day before dst change
2037-03-29 10:12:13 -> 2037-03-29T08:12:13Z the first DST day
2037-10-24 10:12:13 -> 2037-10-24T08:12:13Z the last DST day
2037-10-25 10:12:13 -> 2037-10-25T09:12:13Z the day after
2038 : ok until dst change
2038-03-27 10:12:13 -> 2038-03-27T09:12:13Z OK
2038-03-28 10:12:13 …
Run Code Online (Sandbox Code Playgroud)