Java 时间戳 - 如何创建日期为 2007 年 9 月 23 日的时间戳?
Posted
技术标签:
【中文标题】Java 时间戳 - 如何创建日期为 2007 年 9 月 23 日的时间戳?【英文标题】:Java Timestamp - How can I create a Timestamp with the date 23/09/2007? 【发布时间】:2010-11-01 18:39:30 【问题描述】:如何创建日期为 23/09/2007 的时间戳?
【问题讨论】:
当心:java.sql.Timestamp
是可怕的日期时间类之一,现在是 legacy,多年前被 JSR 310 中定义的现代 java.time 类所取代。
【参考方案1】:
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);
【讨论】:
正常的 ISO 日期格式是 yyyy-MM-dd,否则很好! 新时间戳(时间);给出错误,没有像这样的构造函数需要很长的值:( @Bhanu 文档显示这确实需要很长的值并且似乎可以正常工作:docs.oracle.com/javase/7/docs/api/java/sql/… 仅供参考,非常麻烦的旧日期时间类,例如java.util.Date
、java.util.Calendar
和 java.text.SimpleDateFormat
现在是 legacy,被 Java 8 中内置的 java.time 类所取代,之后。见Tutorial by Oracle。【参考方案2】:
这个怎么样?
java.sql.Timestamp timestamp = java.sql.Timestamp.valueOf("2007-09-23 10:10:10.0");
【讨论】:
时间戳时间戳 = Timestamp.valueOf("2007-09-23 10:10:10.0");显示在 jDK 7 中未定义类型 Timestamp 的 valueOf 方法 新时间戳(时间);给出错误,没有像这样的构造函数采用字符串值:( @Bhanu 构造函数以毫秒为单位占用 unix 时间。如果要从字符串中获取时间戳,请使用静态方法 valueOf。 这似乎是该问题的最佳答案。 最好的答案是日期,它已被弃用,使用它是不好的做法。这个答案更好。谢谢【参考方案3】:时间戳是什么意思?如果您的意思是自 Unix 纪元以来的毫秒数:
GregorianCalendar cal = new GregorianCalendar(2007, 9 - 1, 23);
long millis = cal.getTimeInMillis();
如果你想要一个实际的 java.sql.Timestamp 对象:
Timestamp ts = new Timestamp(millis);
【讨论】:
错误,无法编译!编译错误:09 是八进制数,但 9 超出八进制范围。逻辑错误:月份从 0 开始,你会得到 OCTOBER 23th of 2007 如果无法编译,我将无法得到逻辑错误。 :) 说真的,很好的收获,卡洛斯。我之前抓到的八进制,但无论如何都粘贴错了。 :( 实际上 Timestamp 构造函数已被贬低,而您可以使用 Timestamp.valueOf() 方法 @ShivaKomuravelly 并非所有时间戳构造函数都已弃用,至少不会花费毫秒时间,不建议使用将日期作为参数的构造函数 还有一个常数(而不是月份 = 9):Calendar.SEPTEMBER
【参考方案4】:
tl;博士
java.sql.Timestamp.from (
LocalDate.of ( 2007 , 9 , 23 )
.atStartOfDay( ZoneId.of ( "America/Montreal" ) )
.toInstant()
)
java.time
让我们通过显示使用 Java 8 及更高版本中内置的 java.time 框架的代码来更新此页面。
这些新类的灵感来自Joda-Time,由JSR 310 定义,并由ThreeTen-Extra 项目扩展。它们取代了与早期版本的 Java 捆绑在一起的臭名昭著的麻烦的旧日期时间类。
在 java.time 中,Instant
是 UTC 时间线上的时刻。 ZonedDateTime
是一个即时调整到时区 (ZoneId
)。
时区在这里很重要。如果不应用时区,日期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
时区。相比之下,java.time 类更健全,使用标准的ISO 8601 格式。
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 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date
、Calendar
和 SimpleDateFormat
。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.*
类。
从哪里获得 java.time 类?
Java SE 8、Java SE 9、Java SE 10、Java SE 11 和更高版本 - 具有捆绑实现的标准 Java API 的一部分。 Java 9 添加了一些小功能和修复。 Java SE 6 和 Java SE 7 大部分 java.time 功能在ThreeTen-Backport 中向后移植到 Java 6 和 7。 Android java.time 类的 android 捆绑包实现的更高版本。 对于早期的 Android (ThreeTenABP 项目适应 ThreeTen-Backport(如上所述)。见How to use ThreeTenABP…。ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval
、YearWeek
、YearQuarter
和more。
【讨论】:
我想知道如何让 OP 或 mods 将您的答案标记为正确答案。接受的答案已经过时了。 非常好,除了一个错字。 asStartOfDay() 应该是 atStartOfDay()。 @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());
【讨论】:
错误:尝试 System.out.println 的结果!你会得到类似:“2009-10-23 15:26:56.171”月份是从 0 开始的,所以 9 是十月! 我知道其中一个常量是从零开始的,谢谢。帖子已更新。 哦,我确实放了“未经测试”:)【参考方案6】:根据API,接受年、月等的构造函数已被弃用。相反,您应该使用接受 long 的构造函数。 您可以使用Calendar 实现来构造您想要的日期并以long 形式访问时间表示,例如使用getTimeInMillis 方法。
【讨论】:
【参考方案7】:为了完整起见,还有Joda-Time 2.5 版及其DateTime
类的解决方案:
new Timestamp(new DateTime(2007, 9, 23, 0, 0, DateTimeZone.forID( "America/Montreal" )).getMillis())
【讨论】:
不错的答案,但您错过了一个关键部分:时区。如果省略时区,JVM 的当前默认时区将应用于DateTime
对象。这意味着您的结果会因不同的计算机或主机操作系统或 JVM 设置的配置而异。要获得可预测的结果,请将时区传递给 DateTime
构造函数。根据您的意图选择proper time zone name。例如,DateTimeZone.forID( "America/Montreal" )
或 DateTimeZone.UTC
。
该代码可能更简洁。无需转换为 java.util.Date 即可获取和传递毫秒-since-epoch。只需询问 DateTime
对象的毫秒数-since-epoch。将.toDate().getTime()
替换为.getMillis()
。
@BasilBourque 根据具体情况,您可能希望省略时区以获得可预测的结果。 “在您当前的时区”可能是一个完全合理且可预测的结果。为什么要硬编码时区,或者在他们的计算机已经设置时区时要求用户手动设置时区?当然,如果我的计算机上的应用程序开始输出调整为美国/蒙特利尔时区的日期,我会感到非常惊讶。
@dancarter 省略可选时区会导致混淆。遗漏引起了(a)程序员是否打算依赖隐式默认值或(b)程序员没有考虑时区问题(这太常见了)的歧义。如果您确实想使用 JVM 的当前默认时区,请明确说明,方法是调用 DateTimeZone.getDefault()
并将结果作为可选参数传递。 (顺便说一句,Locale.getDefault()
也是如此,关于可选参数的歧义也是同样的问题。)【参考方案8】:
更一般的答案是导入java.util.Date
,然后当您需要将timestamp
设置为等于当前日期时,只需将其设置为等于new Date()
。
【讨论】:
因为 ** Date("string"); ** 已弃用以上是关于Java 时间戳 - 如何创建日期为 2007 年 9 月 23 日的时间戳?的主要内容,如果未能解决你的问题,请参考以下文章
如何在android中将日期转换为firebase时间戳格式