How to retrieve oracle Timestamp column in expected timezone in Java? - java

I have a timestamp column in oracle table. While storing time I store it in UTC in this column. For retrieving this time stamp I am using Spring's JdbcTemplate while returns object of type TimeStamp.
I want to get date time string in "dd-MM-YYYY HH:mm:ss" format in current time zone. In order to achieve that I am trying following code:
new LocalDateTime(<retrieved TimeStamp>, <current user DateTimeZone>).toString("yyyy-MM-dd HH:mm:ss")
Both LocalDateTime and DateTimeZone from Joda library.
How ever this isn't working as per expected. Instead of current user's time zone above code gives me date time string in UTC only.
What am I missing?

I think your application is using java.util.Date which has no time zone information, the toString usage applies the JVM’s current default time zone when creating a string.
You can adjust the timezone instant by (Using Joda Library)
ZonedDateTime Tokyo = ZonedDateTime.ofInstant (instant,zoneIdTokyo) ;
Or implement zones
DateTimeZone zone = DateTimeZone.forID("Asia/Tokyo");
You are using
LocalDateTime which is immutable class representing a local date and time (no time zone)
EDIT - You can try this
(I haven't tested it)
DateTime udate = new DateTime("2016-05-01T20:10:04", DateTimeZone.UTC);
System.out.println(udate);
DateTime zone = udate.plusMillis(10000)
.withZone(DateTimeZone.forID("Asia/Kolkata"));
System.out.println(zone);

Add utc calendar when fetching the timestamp from database, so the jdbc driver can use this calendar timezone instead of default system timezone.
//Assign utc calendar
Calendar utc= Calendar.getInstance();
utc.setTimeZone(TimeZone.getTimeZone("UTC"));
Timestamp timestamp = rs.getTimestamp("timestampcolumn", utc);
//Convert to client date time
DateTime dateTime = new DateTime(timestamp.getTime(), DateTimeZone.forID("Asia/Kolkata"));
//Format
DateTimeFormatter formatter = DateTimeFormat.forPattern("dd-MM-YYYY HH:mm:ss");
//Change to client wall clock time
LocalDateTime localDateTime = dateTime.toLocalDateTime();
String formattedlocalDateTime = formatter.print(localDateTime)
Example
String utcTime = "2016-06-17 14:22:02Z";
DateTimeFormatter parser = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ssZ");
DateTime dateTime = parser.parseDateTime(utcTime).withZone(DateTimeZone.forID("Asia/Kolkata"));
DateTimeFormatter formatter = DateTimeFormat.forPattern("dd-MM-YYYY HH:mm:ss");
System.out.println(dateTime);
LocalDateTime localDateTime = dateTime.toLocalDateTime();
String formattedlocalDateTime = formatter.print(localDateTime);
System.out.println(formattedlocalDateTime);

Related

How to convert joda DateTime with timezone to DateTime with same time in UTC?

I have such input date:
DateTime date = new DateTime("2022-10-30T00:00:00.000+11:00");
How can I convert it to UTC while keeping the same time:"2022-10-30 00:00:00.000"?
In other words, I want the date.getMillis(); method to return the midnight of "2022-10-30" in UTC.
For now, if I call date.getMillis();, I get "2020-10-29" in UTC.
I'm not sure you're doing what you think you're doing here.
The date you're creating doesn't have a UTC+11 offset, it's in your JVM's default time zone (demo):
System.out.println(DateTimeZone.getDefault());
DateTime date = new DateTime("2022-10-30T00:00:00.000+11:00");
System.out.println(date);
prints
Etc/UTC
2022-10-29T13:00:00.000Z
so the local date portion of this is 2022-10-29.
If you want to create it with the specified offset, you have to either use DateTime.parse:
DateTime date = DateTime.parse("2022-10-30T00:00:00.000+11:00");
or specify it:
DateTime date = new DateTime("2022-10-30T00:00:00.000+11:00", DateTimeZone.forOffsetHours(11));
Printing either of these results in:
2022-10-30T00:00:00.000+11:00
Now, date.withZoneRetainFields(DateTimeZone.UTC) is:
2022-10-30T00:00:00.000Z
as required.

Best way to Change java.sql.TimeStamp to UTC format in Java

I have tried multiple ways one of them using SimpleDateFromatter and now trying
import java.sql.Timestamp;
public static String getCorrectTimeFormat(Timestamp time) {
return time.toInstant().toString();
}
But the problem is which I realized during writing unit test is, the time gets modified.
Timestamp timeStamp = Timestamp.valueOf("2020-07-22 12:26:51.599");
String res = UserUtil.getCorrectTimeFormat(timeStamp);
assertThat(res).isEqualTo("2020-07-22T12:26:51.599Z");
This never passes as the it auto converts to "2020-07-22T11:26:51.599Z"
It’s best to avoid jqva.sql.Timestamp completely. I’ll show you how.
The result you got is correct, as I think you have already discovered.
Get java.time types from your database
Since JDBC 4.2 we can directly get java.time types from a ResultSet. If your database value is a timestamp with time zone (recommended), for example:
OffsetDateTime odt = rs.getObject(
"your_timestamp_with_time_zone_column", OffsetDateTime.class);
String utcString = odt.withOffsetSameInstant(ZoneOffset.UTC).toString();
If your database value is a timestamp without time zone (not recommended), we can only get a LocalDateTime from it, which doesn’t define a point in time. To convert to Instant we need to rely on knowing which time zone the database uses. For example:
ZoneId datebaseTimeZone = ZoneId.of("Europe/Paris");
LocalDateTime ldt = rs.getObject(
"your_timestamp_column", LocalDateTime.class);
String utcString = ldt.atZone(datebaseTimeZone)
.withZoneSameInstant(ZoneOffset.UTC)
.toString();
If your database uses UTC, which counts as an offset, it’s better to use ZoneOffset than ZoneId:
ZoneOffset datebaseOffset = ZoneOffset.UTC;
LocalDateTime ldt = rs.getObject(
"your_timestamp_column", LocalDateTime.class);
String utcString = ldt.atOffset(datebaseOffset).toString();
Your observed result is correct
java.sql.Timestamp confusingly prints in the default time zone of the JVM, and Timestamp.valueOf() equally confusingly assumes that time zone. So assuming that your time zone is at offset +01:00 at this time of year (such as Great Britain, Ireland, Portugal, Morocco and Tunesia, for example), the conversion from 2020-07-22 12:26:51.599 to 2020-07-22T11:26:51.599Z is correct.
You can use java 8 time ZonedDateTime class :
//1 - default pattern
String timeStamp = "2019-03-27T10:15:30";
ZonedDateTime localTimeObj = ZonedDateTime.parse(time);
//2 - specified pattern
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss a z");
String timeStamp1 = "2019-03-27 10:15:30 AM";
ZonedDateTime localTimeObj1 = ZonedDateTime.parse(timeStamp1, formatter);
//To get LocalDate from ZonedDateTime
LocalDate localDate = localTimeObj1.toLocalDate()
//To get timestamp from zoneddatetime with utc timezone
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneOffset.UTC);
Timestamp timestamp = Timestamp.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());

How can we convert Timestamp datatype in Java to UTC timezone in JPA entity Java?

We are using PO class to represent the sql DB and using Java JPA entity.In that class, we have one column as a field currentTime with Timestamp datatype and #version annotation from JPA.
#Version
private Timestamp currentTime;
whenever the entity gets updated, currentTime is updated with the latest time.
currentTime = new Timestamp(0); //this will create the new timestamp with current time.
but it’s currently taking the time from the server. I want to convert this time to UTC format before saving it to DB.
Anyone can help how can I convert the time to UTC time?
I had a similar problem when I needed to parse the time from server but I needed to convert this time to UTC format before storing this information int MySQL DB. This was my solution:
Instant dateConverted = LocalDateTime
.parse(dateTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH))
.atZone(ZoneId.of("Europe/Bratislava")).toInstant();
long epochTime = dateConverted.toEpochMilli() / 1000L;
Where dateTime is a String variable containing the date and time from server
And I have used DateTimeFormatter to format my time to appropriate format.
At the end I have added the zoneID of my timeZone and converted it to Instant
And at the end I have converted to seconds
Try below code,
currentTime = Timestamp.valueOf(LocalDateTime.ofInstant(Instant.now(), ZoneOffset.UTC));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault());
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String localTime = sdf.format(new Date(your_time_stamp));
Date date = new Date();
try {
date = sdf.parse(localTime);//get local date
} catch (ParseException e) {
e.printStackTrace();
}

Joda DateTime automatically change timezone when parsing string

I have string of a date in "iso8601" format and when I parse it using Joda "DateTime", the time zone of date changes automatically.
DateTime dateTime = new DateTime( "2017-05-22T08:10:00.000+0300" ) ;
System.out.println(dateTime);
and its output is:
2017-05-22T09:40:00.000+04:30
As you see time zone of first string is +3:00 and the time zone after parsing is +04:30. How can I parse first string without changing time zone? (so the time zone remains +03:00 even after parsing)
This constructor use default timezone of user. You need to set timezone manually with DateTime(Object object, DateTimeZone zone) construnctor.
Or, parse this string with usage of withOffsetParsed() like this:
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'hh:mm:ss.SSSZ");
DateTime dateTime = formatter.withOffsetParsed().parseDateTime("2017-05-22T08:10:00.000+0300");
You have to setup time zone manually something like this:
String str = "2017-05-22T08:10:00.000+0300" ;
DateTime dateTime = new DateTime() ;
System.out.println(dateTime);
String tzName = str.substring(text.length() - 5);
DateTimeZone tz = DateTimeZoneDateTimeZone forID(str.substring(3) + ":" + str.substring(text.length() - 2))
System.out.println(dateTime.withZone(tz));
You can use the inbuilt functionalities of JDK 8 date-time API to solve this easily. The following code prints 2017-05-22T08:10+03:00.
DateTimeFormatter df = DateTimeFormatter.ISO_OFFSET_DATE_TIME ;
OffsetDateTime date1 = OffsetDateTime.parse("2017-05-22T08:10:00.000+03:00", df);
System.out.println(date1); //prints 2017-05-22T08:10+03:00

Java 8 Convert given time and time zone to UTC time

I have a time with string type like: "2015-01-05 17:00" and ZoneId is "Australia/Sydney".
How can I convert this time information to the corresponding to UTC time using Java 8 datetime API?
Also need to considering DST stuff.
You are looking for ZonedDateTime class in Java8 - a complete date-time with time-zone and resolved offset from UTC/Greenwich. In terms of design, this class should be viewed primarily as the combination of a LocalDateTime and a ZoneId. The ZoneOffset is a vital, but secondary, piece of information, used to ensure that the class represents an instant, especially during a daylight savings overlap.
For example:
ZoneId australia = ZoneId.of("Australia/Sydney");
String str = "2015-01-05 17:00";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime localtDateAndTime = LocalDateTime.parse(str, formatter);
ZonedDateTime dateAndTimeInSydney = ZonedDateTime.of(localtDateAndTime, australia );
System.out.println("Current date and time in a particular timezone : " + dateAndTimeInSydney);
ZonedDateTime utcDate = dateAndTimeInSydney.withZoneSameInstant(ZoneOffset.UTC);
System.out.println("Current date and time in UTC : " + utcDate);
An alternative to the existing answer is to setup the formatter with the appropriate time zone:
String input = "2015-01-05 17:00";
ZoneId zone = ZoneId.of("Australia/Sydney");
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").withZone(zone);
ZonedDateTime utc = ZonedDateTime.parse(input, fmt).withZoneSameInstant(UTC);
Since you want to interact with a database, you may need a java.sql.Timestamp, in which case you don't need to explicitly convert to a UTC time but can use an Instant instead:
ZonedDateTime zdt = ZonedDateTime.parse(input, fmt);
Timestamp sqlTs = Timestamp.from(zdt.toInstant());
**// Refactored Logic**
ZoneId australia = ZoneId.of("Australia/Sydney");
ZoneId utcZoneID= ZoneId.of("Etc/UTC");
String ausTime = "2015-01-05 17:00";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
//converting in datetime of java8
LocalDateTime ausDateAndTime = LocalDateTime.parse(ausTime, formatter);
// DateTime With Zone
ZonedDateTime utcDateAndTime = ausDateAndTime.atZone(utcZoneID);
// output - 2015-01-05T17:00Z[Etc/UTC]
// With Formating DateTime
String utcDateTime = utcDateAndTime.format(formatter);
// output - 2015-01-05 17:00

Categories

Resources