Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从UNIX时代创建日历的日期不正确(1970年的某个时间)?_Java_Datetime - Fatal编程技术网

Java 从UNIX时代创建日历的日期不正确(1970年的某个时间)?

Java 从UNIX时代创建日历的日期不正确(1970年的某个时间)?,java,datetime,Java,Datetime,我有一个存储unix时间和等效时间戳的表 CREATE TABLE tbl_time ( time_unix BIGINT, time_timestamp TIMESTAMP WITHOUT TIME ZONE ); 数据库使用PostgreSQL。数据库已配置为亚洲/德黑兰时区。 例如: 1333436817, 2012-04-03 11:36:57 当我使用以下命令将unix时间转换为python中的字符串格式时: datetime.datetime.fromtimest

我有一个存储unix时间和等效时间戳的表

CREATE TABLE tbl_time
(
    time_unix BIGINT,
    time_timestamp TIMESTAMP WITHOUT TIME ZONE
);
数据库使用PostgreSQL。数据库已配置为
亚洲/德黑兰
时区。 例如:

1333436817, 2012-04-03 11:36:57
当我使用以下命令将unix时间转换为python中的字符串格式时:

datetime.datetime.fromtimestamp(1333436817)
它给了我:
datetime.datetime(2012,4,3,11,36,57)
,这是正确的,等于数据库。但当我使用java进行此转换时,使用:

Calendar c = Calendar.getInstance(TimeZone.getTimeZone("Asia/Tehran"));
c.setTimeInMillis(1333436817 * 1000);
System.out.println(c.getTime());

它给出了:
Sat Jan 24 06:12:35 IRST 1970
。系统本身在
亚洲/德黑兰
时区下运行。我在Debian 6.0.5上使用PostgreSQL 8.4.11,使用python 3.1和openjdk 6。有人能帮忙吗?

java日期库的设计很糟糕,没有那么好的功能。我无法真正帮助您解决问题,但我可以建议您尝试一下

1333436817*1000的结果对于整数来说太大,因此溢出。在这种情况下,Java不会自动为您升级该类型

试试看:

    c.setTimeInMillis(1333436817 * 1000L);
请注意,
L
迫使您的计算使用长整数。

由tibo编写是正确的。我的其他想法如下

将时间戳与时区一起使用 您提到在Postgres中使用不带时区的数据类型
TIMESTAMP
。该类型仅适用于与任何特定时区无关的日期时间。例如,“2015年12月25日午夜开始的圣诞节”在任何特定时区都意味着不同的时刻。例如,巴黎的圣诞节比蒙特勒尔早。这种数据类型在商业应用程序中很少适用。请参阅此Postgres专家帖子

在Postgres中,另一种类型的带有时区的时间戳表示“关于时区”。与UTC或时区信息的任何偏移以及传入数据都用于调整到UTC。然后,将丢弃伴随的偏移量或时区信息。有些数据库保存这些信息,但不保存Postgres

你的声明:

数据库使用PostgreSQL。数据库已配置亚洲/德黑兰时区

…毫无意义。数据类型
不带时区的时间戳
没有时区(尽管您可以将其视为UTC),并且数据类型
带时区的时间戳
始终处于活动状态。关于存储日期时间值,没有这样的时区配置

您可能的意思是,数据库会话的默认时区设置为德黑兰时区。请参阅命令。但该设置只是粉饰,在生成日期时间值的字符串表示形式时应用。当使用JDBC和java.sql.Timestamp类时,该会话设置是不相关的,因为Postgres没有生成任何字符串。您对时区的关注应该放在Java端(参见下面的代码),而不是Postgres

一般来说,主机服务器操作系统应设置为UTC。但你的应用程序代码永远不应该依赖于此,而应该指定任何期望/预期的时区

java.time 在Java8和更高版本中,新的Java.time包取代了旧的Java.util.Date/.Calendar类。这些新类的灵感来自JSR310定义的Joda时间库,并通过项目进行了扩展

最终,JDBC驱动程序将被更新以直接处理这些新类型。同时使用添加到新旧类中的转换方法

java.sql.Timestamp ts = myResultSet.getTimestamp( 1 ); 
Instant instant = ts.toInstant();
ZoneId zoneId = ZoneId.of( "Asia/Tehran" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
或者根据你从纪元算起的整秒数,构造一个瞬间

long secondsSinceUnixEpoch = 1_333_436_817L ;
Instant instant = Instant.ofEpochSecond( secondsSinceUnixEpoch );
ZoneId zoneId = ZoneId.of( "Asia/Tehran" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

请不要再说了!图书馆并不完美,但我从来没有遇到过问题,我可以做我想做的每一件事。你的回答与这些问题无关。。。