Java时间戳-如何创建日期为23/09/2007的时间戳?


Answers:


154

通过Timestamp,我相信你的意思java.sql.Timestamp。您会注意到,该类具有一个接受long参数的构造函数。您可以使用以下DateFormat类进行解析:

DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
Date date = dateFormat.parse("23/09/2007");
long time = date.getTime();
new Timestamp(time);

1
正常的ISO日期格式为yyyy-MM-dd,否则很棒!
vidstige 2014年

1
新时间戳(时间);给出这样的错误:没有像这样的构造函数需要较长的值:(
Bhanu Sharma

1
@Bhanu该文档显示这确实需要很长的价值,似乎正常工作:docs.oracle.com/javase/7/docs/api/java/sql/...
Hazok

仅供参考,麻烦的旧日期时间类(如java.util.Datejava.util.Calendarjava.text.SimpleDateFormat现在已成为旧版)被Java 8及更高版本中内置的java.time类取代。请参见Oracle 教程
罗勒·布尔克

121

那这个呢?

java.sql.Timestamp timestamp = java.sql.Timestamp.valueOf("2007-09-23 10:10:10.0");

1
时间戳记时间戳= Timestamp.valueOf(“ 2007-09-23 10:10:10.0”); 显示的是jDK 7中类型Timestamp的valueOf方法未定义
Ashish Ratan

新时间戳(时间);给出错误,即没有像这样的构造函数采用字符串值:(
Bhanu Sharma

@Bhanu构造函数花费Unix时间(以毫秒为单位)。如果要从字符串获取时间戳,请使用静态方法valueOf。
Hazok 2014年

4
这似乎是该问题的最佳答案。
哈佐克2014年

1
最好的答案是不建议使用日期,这是使用它的错误做法。这个答案更好。谢谢
Alberici '16

18

时间戳是什么意思?如果您指的是自Unix时代以来的毫秒数:

GregorianCalendar cal = new GregorianCalendar(2007, 9 - 1, 23);
long millis = cal.getTimeInMillis();

如果要一个实际的java.sql.Timestamp对象:

Timestamp ts = new Timestamp(millis);

2
错误,将无法编译!编译错误:09是八进制数,但9超出八进制数范围。逻辑错误:该月是从0开始的,您将获得2007
user85421 2009年

如果不编译,我不会收到逻辑错误。:)说真的,好收获,卡洛斯。我之前抓过的八进制,但无论如何都粘贴错了。:(
Matthew Flaschen

实际上,时间戳记构造函数是不完整的,您可以使用Timestamp.valueOf()方法
Shiva Komuravelly 2012年

@ShivaKomuravelly并非所有时间戳构造函数都已被弃用,至少不会花费毫秒级的时间,不建议使用以日期为参数的构造函数
否名称

而且有一个常数(而不是月= 9):Calendar.SEPTEMBER
纪尧姆·赫斯塔

11

tl; dr

java.sql.Timestamp.from (
    LocalDate.of ( 2007 , 9 , 23 )
             .atStartOfDay( ZoneId.of ( "America/Montreal" ) )
             .toInstant()
)

java.time

让我们通过使用Java 8和更高版本中内置的java.time框架显示代码来更新此页面。

这些新类的灵感来自由JSR 310定义的Joda-Time,并由ThreeTen-Extra项目扩展。他们取代了与早期Java版本捆绑在一起的臭名昭著的麻烦日期时间类。

在java.time中,InstantUTC时间轴上的时刻是一个时刻。A ZonedDateTime是调整为时区(ZoneId)的Instant 。

时区在这里至关重要。如果September 23, 2007不应用时区,则日期不能转换为时间轴上的某个时刻。考虑到巴黎的新天要比现在仍在“昨天”的蒙特利尔早。

另外,java.sql.Timestamp代表日期和时间。因此,我们必须注入日期中的时间。我们假设您希望将一天的第一时间作为一天中的时间。请注意,00:00:00.0由于夏时制和其他可能的异常,这并不总是时间。

请注意,与旧的java.util.Date类不同,与Joda-Time不同,java.time类型的分辨率为纳秒而不是毫秒。这与java.sql.Timestamp的分辨率匹配。

请注意,java.sql.Timestamp有一个讨厌的习惯,即在通过其toString方法生成字符串表示形式时,将JVM的当前默认时区隐式地应用到其日期时间值。在这里,您可以看到我的America/Los_Angeles时区。相反,使用标准ISO 8601格式的java.time类更为合理。

LocalDate d = LocalDate.of ( 2007 , 9 , 23 ) ;
ZoneId z = ZoneId.of ( "America/Montreal" ) ;
ZonedDateTime zdt = d.atStartOfDay( z ) ;
Instant instant = zdt.toInstant() ;
java.sql.Timestamp ts = java.sql.Timestamp.from ( instant ) ;

转储到控制台。

System.out.println ( "d: " + d + " = zdt: " + zdt + " = instant: " + instant + " = ts: " + ts );

运行时。

d:2007-09-23 = zdt:2007-09-23T00:00-04:00 [美国/蒙特利尔] =即时:2007-09-23T04:00:00Z = ts:2007-09-22 21:00: 00.0

顺便说一句,从JDBC 4.2开始,您可以直接使用java.time类型。不需要java.sql.Timestamp

  • PreparedStatement.setObject
  • ResultSet.getObject

关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代麻烦的老传统日期时间类,如java.util.DateCalendar,和SimpleDateFormat

现在处于维护模式Joda-Time项目建议迁移到java.time类。

要了解更多信息,请参见Oracle教程。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要类。java.sql.*

在哪里获取java.time类?

ThreeTen-额外项目与其他类扩展java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多


3
我不知道如何获得OP或Mod来将您的答案标记为正确答案。公认的答案太过时了。
sttaq

非常好,除了错字。asStartOfDay()应该是atStartOfDay()。
Tullochgorum

@Tullochgorum已修复。谢谢。仅供参考,在Stack Overflow上,如果您愿意,欢迎您自己进行此类编辑。
罗勒·布尔克

5

您还可以执行以下操作:

// untested
Calendar cal = GregorianCalendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 23);// I might have the wrong Calendar constant...
cal.set(Calendar.MONTH, 8);// -1 as month is zero-based
cal.set(Calendar.YEAR, 2009);
Timestamp tstamp = new Timestamp(cal.getTimeInMillis());

2
错误:尝试结果的System.out.println!您将得到类似:“ 2009-10-23 15:26:56.171”月份是从0开始的,所以9是10月!
user85421 2009年

我知道这些常数之一是从零开始的,谢谢。发布更新。
亚历克斯(Alex

1
哦,我确实把“未试” :)
Alex

4

根据API,不赞成使用将接受年,月等的构造函数。相反,您应该使用接受long的构造方法。您可以使用Calendar实现来构造所需的日期,并使用long(例如,使用getTimeInMillis方法)访问时间表示。


1

为了完整起见,还有一个Joda-Time版本2.5及其DateTime类的解决方案:

new Timestamp(new DateTime(2007, 9, 23, 0, 0, DateTimeZone.forID( "America/Montreal" )).getMillis())

1
好的答案,但是您错过了一个关键的片段:时区。如果省略时区,则JVM的当前默认时区将应用于DateTime对象。这意味着您的结果将在不同计算机,主机OS或JVM设置的配置上有所不同。为了获得可预期的结果,请将时区传递给该DateTime构造函数。根据您的意图选择正确的时区名称。例如,DateTimeZone.forID( "America/Montreal" )DateTimeZone.UTC
罗勒·布尔克

该代码可能更简短。无需转换为java.util.Date即可获取和传递毫秒-自epoch。只需询问DateTime对象的毫秒数(自纪元以来)。替换.toDate().getTime().getMillis()
罗勒·布尔克

@BasilBourque视情况而定,您可能要忽略时区以获得可预测的结果。“在您当前的时区”可能是一个完全合理且可预测的结果。为什么要对时区进行硬编码,或者在用户的计算机已设置时区时要求用户手动设置时区?如果我计算机上的应用程序开始输出调整为America / Montreal时区的日期,我当然会感到非常惊讶。
丹·卡特

@dancarter省略可选的时区会导致混乱。遗漏引起了(a)程序员打算依赖隐式默认值,或者(b)程序员没有考虑时区问题(这太普遍了)的不确定性。如果确实要使用JVM的当前默认时区,请通过调用结果并将其作为可选参数传递来明确DateTimeZone.getDefault()地说明。(顺便说一句,同上,对Locale.getDefault(),在可选参数的不确定性同样的问题。)
罗勒布尔克

-1

一个更通用的答案是import java.util.Date,然后当您需要将其设置为timestamp当前日期时,只需将其设置为即可new Date()


因为** Date(“ string”); **已弃用
Ashish Ratan 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.