将java.sql.Timestamp转换为另一个时区的java.sql.Timestamp

时间:2012-06-25 19:48:43

标签: java java.util.date timestamp-with-timezone

我需要操作java.sql.Timestamp。

该功能的输入是: java.sql.Timestamp中的格式化DateTime [可能的日期格式为: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,以及其他一些]

所需输出: 另一个Timezone中的java.sql.Timestamp与输入格式相同的DateTime

所以基本上我需要在java.sql.Timestamp

中更改DateTime的时区

我见过其他帖子,提到使用JODA,但由于一些限制我无法使用它。

我试过了 - 将java.sql.Timestamp转换为java.date.Calendar, - 然后改变时区, - 然后转换为它迄今 - 将日期格式化为相同的格式化日期时间

请参阅以下代码:

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();
}

有谁可以告诉我这里有什么问题,或者有没有其他方法可以在时区上操作java.sql.Timestamp?

感谢。

5 个答案:

答案 0 :(得分:2)

你误解和滥用这些课程。

Timestamp& Date没有时区,但UTC

  

在Timezone上操作java.sql.Timestamp

java.sql.Timestamp始终是UTC中的一个时刻。不涉及其他time zone,仅涉及UTCjava.util.Date同上 - 始终使用UTC,不涉及其他时区。

因此,如上所述,您的问题没有意义。

Timestamp& Date没有“格式”

TimestampDate都没有“格式”。他们使用自己内部定义的方式来跟踪日期时间。它们不是字符串,所以它们没有格式。您可以生成一个String以特定格式表示它们的值,但是这样的String是不同的并且与生成对象分开。

java.time

您正在使用麻烦的旧日期时间类,这些类在几年前被 java.time 类所取代。

TimestampDate都替换为Instant Instant类代表UTC中时间轴上的一个时刻分辨率为nanoseconds(小数部分最多九(9)位)。

您的输入是

String input = "2012-06-20 18:22:42.0" ;

该输入几乎符合标准ISO 8601格式。要完全符合,请使用T替换中间的SPACE。

String input = "2012-06-20 18:22:42.0".replace( " " , "T" ) ;

解析为LocalDateTime因为它没有指示偏离UTC或时区的指示。

LocalDateTime ldt = LocalDateTime.parse( input ) ;

LocalDateTime与输入字符串一样,代表片刻,时间轴上的某个点。如果没有时区的上下文或从UTC偏移,它就没有实际意义。它仅表示大约26-27小时范围内的潜在时刻。

如果您知道预期的时区,请将其应用于获取ZonedDateTime对象。

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;

至于你提到的其他格式,你的问题根本不清楚。搜索DateTimeFormatter类的堆栈溢出,以查看使用 java.time 类生成/解析字符串的许多示例和讨论。但首先,要明确字符串不是日期时间对象的关键概念,日期时间对象不是字符串。

数据库

如果您使用java.sql.Timestamp与数据库交换数据,则不再需要该类。从JDBC 4.2及更高版本开始,您可以直接与数据库交换 java.time 对象。

myPreparedStatement.setObject( … , instant ) ;

...和...

Instant instant = myResultSet.getObject( … , Instant.class ) ;

关于 java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

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

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 1 :(得分:0)

答案 2 :(得分:0)

你不能简单地说:

  1. 以毫秒为单位获取原始时间
  2. 将时区差异转换为毫秒
  3. 加上或减去与原始时间的差异。
  4. 使用新的时间(以毫秒为单位)创建新的时间戳

答案 3 :(得分:0)

将Timestamp视为一个固定的时间点,与您在地球上看时钟的位置断开连接。

如果您想在特定时区显示某个人在日历/时钟上的内容,您可以将日历设置为该时区,然后将您的SimpleDateFormat与该日历相关联。

例如:

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));
}

我的输出是:

2012-06-25 20:27:12.506
2012-06-25 23:27:12.506

答案 4 :(得分:0)

我解决了,我正在提供代码供参考。

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();            
}