在另一个时区将 java.sql.Timestamp 转换为 java.sql.Timestamp
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11196302/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert java.sql.Timestamp to java.sql.Timestamp in another timezone
提问by sankethm7
I am in need to manipulate on java.sql.Timestamp.
我需要对 java.sql.Timestamp 进行操作。
Input to the function is: Formatted DateTime in java.sql.Timestamp [Possible date formats are: MM/dd/yyyy hh:mm:ss aa, MM/dd/yyyy hh:mm:ss, MM/dd/yyyy hh:mm aa, MM/dd/yyyy HH:mm, MM/dd/yy hh:mm aa, MM/dd/yy HH:mm, MM/dd/yyyy, and some others]
函数的输入是:java.sql.Timestamp 中的格式化日期时间 [可能的日期格式是:MM/dd/yyyy hh:mm:ss aa, MM/dd/yyyy hh:mm:ss, MM/dd/yyyy hh: mm aa、MM/dd/yyyy HH:mm、MM/dd/yy hh:mm aa、MM/dd/yy HH:mm、MM/dd/yyyy 和其他一些]
Required Output: java.sql.Timestamp in another Timezone the same formatted DateTime as input
必需的输出:java.sql.Timestamp 在另一个时区与输入相同格式的 DateTime
So basically I need to change timezone of the DateTime in java.sql.Timestamp
所以基本上我需要在 java.sql.Timestamp 中更改 DateTime 的时区
I have seen other posts, which mention to use JODA, but I can't use it due to some restrictions.
我看过其他帖子,其中提到使用 JODA,但由于某些限制,我无法使用它。
I have tried - to convert java.sql.Timestamp to java.date.Calendar, - then change the timezone, - then convert to it to date - format date to the same formatted datetime
我曾尝试 - 将 java.sql.Timestamp 转换为 java.date.Calendar, - 然后更改时区, - 然后将其转换为日期 - 将日期格式化为相同格式的日期时间
See the code below:
请参阅下面的代码:
Timestamp ts = "2012-06-20 18:22:42.0"; // I get this type of value from another function
Calendar cal = Calendar.getInstance();
cal.setTime(ts);
cal.add(Calendar.HOUR, -8);
String string = cal.getTime().toString(); // return value is in " DAY MMM dd hh:mm:ss PDT yyyy " format i.e. Wed Jun 20 10:22:42 PDT 2012
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss"); // This could be any format required
Date date;
try {
date = formatter.parse(string); // I am getting exception here on parsing
} catch (ParseException e1) {
e1.printStackTrace();
}
Can anyone tell me what is wrong here, or is there any other way to manipulate on Timezone for java.sql.Timestamp ?
谁能告诉我这里出了什么问题,或者有没有其他方法可以操作 java.sql.Timestamp 的 Timezone ?
Thanks.
谢谢。
回答by Basil Bourque
You are misunderstanding and abusing these classes.
您正在误解和滥用这些课程。
Timestamp
& Date
have no time zone but UTC
Timestamp
&Date
没有时区,但 UTC
manipulate on Timezone for java.sql.Timestamp
操作 java.sql.Timestamp 的时区
A java.sql.Timestamp
is always a moment in UTC. No other time zoneis involved, only UTC. Ditto for java.util.Date
– always in UTC, no other time zone involved.
Ajava.sql.Timestamp
始终是UTC 中的一个时刻。不涉及其他时区,仅涉及UTC。同上java.util.Date
– 始终使用 UTC,不涉及其他时区。
So your Question, as quoted above, does not make sense.
因此,如上所述,您的问题没有意义。
Timestamp
& Date
have no “format”
Timestamp
&Date
没有“格式化”
Neither Timestamp
nor Date
have a “format”. They use their own internally defined way to track the date-time. They are not strings, so they have no format. You can generate a String to represent their value in a particular format, but such a String is distinct and separate from the generating object.
既没有Timestamp
也Date
没有“格式”。他们使用自己内部定义的方式来跟踪日期时间。它们不是字符串,因此它们没有格式。您可以生成一个字符串来以特定格式表示它们的值,但这样的字符串与生成对象不同且独立。
java.time
时间
You are using troublesome old date-time classes that wore supplanted years ago by the java.timeclasses.
您正在使用麻烦的旧日期时间类,这些类在多年前被java.time类取代。
Both Timestamp
and Date
are replaced by Instant
.The Instant
class represents a moment on the timeline in UTCwith a resolution of nanoseconds(up to nine (9) digits of a decimal fraction).
这两个Timestamp
和Date
被取代Instant
。该Instant
级表示时间轴上的时刻UTC,分辨率为纳秒(最多小数的9个位数)。
Your input is
您的输入是
String input = "2012-06-20 18:22:42.0" ;
That input is nearly compliant with standard ISO 8601 format. To comply fully, replace the SPACE in the middle with a T
.
该输入几乎符合标准 ISO 8601 格式。要完全符合,请将中间的 SPACE 替换为T
.
String input = "2012-06-20 18:22:42.0".replace( " " , "T" ) ;
Parse as a LocalDateTime
because it lacks an indicator of offset-from-UTC or time zone.
解析为 a,LocalDateTime
因为它缺少从 UTC 或时区偏移的指标。
LocalDateTime ldt = LocalDateTime.parse( input ) ;
A LocalDateTime
, like your input string, does notrepresent a moment, is nota point on the timeline. Without the context of a time zone or offset-from-UTC, it has no real meaning. It represents only potentialmoments along a range of about 26-27 hours.
一LocalDateTime
,喜欢你的输入字符串,并不能代表一个时刻,是不是在时间轴上的一个点。如果没有时区的上下文或与 UTC 的偏移量,它就没有真正的意义。它仅代表大约 26-27 小时范围内的潜在时刻。
If you know the intended time zone, apply it to get a ZonedDateTime
object.
如果您知道预期的时区,请应用它来获取ZonedDateTime
对象。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;
As for the other formats you mentioned, your Question is not at all clear. Search Stack Overflow for DateTimeFormatter
class to see many examples and discussions of generating/parsing strings with the java.timeclasses. But first, get clear on the crucial concept that strings are not the date-time objects, and the date-time objects are not strings.
至于你提到的其他格式,你的问题根本不清楚。搜索 Stack OverflowDateTimeFormatter
以查看有关使用java.time类生成/解析字符串的许多示例和讨论。但首先,要弄清楚字符串不是日期时间对象,日期时间对象也不是字符串这一关键概念。
Database
数据库
If you were using java.sql.Timestamp
to exchange data with a database, no need for that class anymore. As of JDBC 4.2 and later, you can directly exchange java.timeobjects with your database.
如果您正在使用java.sql.Timestamp
与数据库交换数据,则不再需要该类。从 JDBC 4.2 及更高版本开始,您可以直接与数据库交换java.time对象。
myPreparedStatement.setObject( … , instant ) ;
…and…
…和…
Instant instant = myResultSet.getObject( … , Instant.class ) ;
About java.time
关于java.time
The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
该java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date
, Calendar
, & SimpleDateFormat
。
The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310。
You may exchange java.timeobjects directly with your database. Use a JDBC drivercompliant with JDBC 4.2or later. No need for strings, no need for java.sql.*
classes.
您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*
Where to obtain the java.time classes?
从哪里获得 java.time 类?
- Java SE 8, Java SE 9, and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6and Java SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- Later versions of Android bundle implementations of the java.time classes.
- For earlier Android (<26), the ThreeTenABPproject adapts ThreeTen-Backport(mentioned above). See How to use ThreeTenABP….
- Java SE 8、Java SE 9及更高版本
- 内置。
- 具有捆绑实现的标准 Java API 的一部分。
- Java 9 添加了一些小功能和修复。
- Java SE 6和Java SE 7
- 多的java.time功能后移植到Java 6和7在ThreeTen-反向移植。
- 安卓
- 更高版本的 Android 捆绑实现 java.time 类。
- 对于早期的 Android(<26),ThreeTenABP项目采用了ThreeTen-Backport(上面提到过)。请参阅如何使用ThreeTenABP ...。
The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如Interval
,YearWeek
,YearQuarter
,和更多。
回答by Sebastian
you miss one argumment in formatter.parse http://docs.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html#parse(java.lang.String,%20java.text.ParsePosition)
你错过了 formatter.parse http://docs.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html#parse(java.lang.String,%20java.text.ParsePosition )
回答by Conor Sherman
Couldn't you simply:
你不能简单地:
- Get original time in milliseconds
- Convert timezone difference to milliseconds
- Add or subtract the difference from the original time.
- Create a new timestamp using the new time in milliseconds
- 以毫秒为单位获取原始时间
- 将时区差异转换为毫秒
- 添加或减去原始时间的差异。
- 使用以毫秒为单位的新时间创建新的时间戳
回答by phatfingers
Think of Timestamp as being a fixed point in time, disconnected from where on earth you happen to be looking at a clock.
将时间戳视为一个固定的时间点,与地球上您碰巧正在看时钟的地方断开连接。
If you want to display what's on the calendar/clock for a person at that instant in a particular time zone, you can set a calendar to that time zone and then associate your SimpleDateFormat to that calendar.
如果您想在特定时区的某个时刻为某个人显示日历/时钟上的内容,您可以将日历设置为该时区,然后将您的 SimpleDateFormat 关联到该日历。
For example:
例如:
public void testFormat() throws Exception {
Calendar pacific = Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles"));
Calendar atlantic = Calendar.getInstance(TimeZone.getTimeZone("America/New_York"));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Timestamp ts = new Timestamp(System.currentTimeMillis());
sdf.setCalendar(pacific);
System.out.println(sdf.format(ts));
sdf.setCalendar(atlantic);
System.out.println(sdf.format(ts));
}
My output was:
我的输出是:
2012-06-25 20:27:12.506
2012-06-25 23:27:12.506
回答by sankethm7
I got it solved, I am putting code for reference.
我已经解决了,我把代码供参考。
Timestamp ts = "2012-06-20 18:22:42.0"; // input date in Timestamp format
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Calendar cal = Calendar.getInstance();
cal.setTime(ts)
cal.add(Calendar.HOUR,-7); // Time different between UTC and PDT is -7 hours
String convertedCal = dateFormat.format(cal.getTime()); // This String is converted datetime
/* Now convert String formatted DateTime to Timestamp*/
SimpleDateFormat formatFrom = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
try {
Date date = formatFrom.parse(convertedCal);
Timestamp finalTS = new Timestamp(date.getTime()); // Final value in Timestamp: 2012-06-20 11:22:42.0
} catch (Exception e) {
e.printStackTrace();
}