convert UTC timestamp to any other zone timestamp - java

I'm using MongoDB to store my data. Mongo stores timestamps in UTC as a default.
We process data in different time zones. I'm struggling to convert UTC timestamp to PDT or IST timestamps.
Trying to construct a method to pass timezone(into which my timestamp is to be converted) and timestamp(UTC). Method to return the timestamp of specified time zone.
public Date getDateBasedOnZone(Date date, "America/Los_Angeles") {
return dateInAmerica/Los_Angeles;
}

You could use something like the following to get the time in a particular zone:
date.toInstant().atZone( ZoneId.of( "America/Los_Angeles" ) )

A java.util.Date object does NOT contain timezone information so it's impossible to convert from one timezone to another in a java.util.Date (it doesn't make sense). It's simply a wrapper around long which is milliseconds since EPOCH.
You only start seeing timezone in java.util.Calendar or when a java.util.Date is converted to String.
There's also Joda-Time which has far better date API's than the core Java libraries.

You can use a dateformat with the required timezone and apply it to the date
public Date convertToZone(Date date, String tz) {
DateFormat TFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
TFormat.setTimeZone(TimeZone.getTimeZone(tz));
return df.parse(currentTFormat.format(date));
}

Related

Convert UTC offset date to different time zone

I would like to convert date with its UTC offset to the different timezone.
Suppose that I get 2021-06-14 06:56:00 (this is local date time) with UTC offset +3 hours and I need to convert this local date time to LosAngeles timezone (UTC -8 hours). In order to implement this, I wrote the following snippet:
public static LocalDateTime toPstTimeZone(LocalDateTime localDateTime, int utcOffset) {
final var pstUtcOffset = ZoneOffset.ofHours(-8);
return localDateTime
.atOffset(ZoneOffset.ofHours(utcOffset))
.withOffsetSameInstant(pstUtcOffset)
.toLocalDateTime();
}
need to check if this is valid approach to do.
Your approach is correct. However, I would suggest if possible to work to begin with, with ZonedDateTime or OffsetDateTime. in this case switching between timezones is much easier. For ZonedDateTime switching to different time zone is just one method: public ZonedDateTime withZoneSameInstant(ZoneId zone)

#JsonFormat converts Date with incorrect timezone

I have a simple POJO with a Date field with initial value coming in:
1985-09-17T01:00:00.000+0400
then this Date value gets mapped to a DTO with the Date field annotated:
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssX")
private Date dateOfBirth;
Then the result is shown:
1985-09-16T21:00:00Z
I have tried setting the timestamp property in #JsonFormat, but that didn't help and the date is still invalid.
How can I correctly convert the date?
The value within a java.util.Date is the number of milliseconds since the Unix epoch, which occurred at midnight January 1st 1970, UTC. As it's a number of milliseconds since a fixed epoch, the value within java.util.Date is the same around the world at any particular instant, regardless of local time zone.
So in your case it's better to use ZonedDateTime class if you use java 8 ZonedDateTime
Both dates represents the same instant:
1985-09-17T01:00:00.000+0400
1985-09-16T21:00:00Z
When you print dates in java it uses the current timezone of the VM, but internally the Date class stores that information in a long representing the time in milliseconds since the epoch.
If you like you can get the a String representation of the date using a custom timezone using the setTimeZone method of DateFormat:
Sets the time zone for the calendar of this DateFormat object.
Here a simple snippet of code:
Date date = ...
DateFormat formatter = ...
TimeZone timeZone = ...
// Set a custom timezone
formatter.setTimeZone(timeZone);
// Get a string representation of the daet with a custom timezone
String formattedDateWithCustomTimezone = formatter.format(date);

Convert java.util.Date to different time zone requested

Depending on a request url, I have to convert a Date to different requested time zone and return date and time as String. I am using java 8 with spring boot and mongo 3.2
So inside the service method, I first set the time zone as below,
TimeZone.setDefault(TimeZone.getTimeZone(TIME_ZONE))
But I notice, it will change the time zone of whole java application. So even the method exit, the time zone would be remain the time zone I set previously.
So instead setDefault method level, I set it specifically in the SimpleDateFormat as below,
(assignment is a Assignmet document class having java.util.Date as a property named assignmentEndDate which map to a mongodb collection. In mongo db assignmentEndDate is store as UTC)
java.text.DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy'T'HH:mm:ss.SSS");
formatter.setTimeZone(TimeZone.getTimeZone(timezone));
Date assignmentEndDate = assignment.getAssignmentEndDate();
formatter.format(assignmentEndDate);
This way it wont change the application level time zone. Is this the correct approach for such scenario?
Take advantage of new date time api included in Java 8.
ZoneId zoneId = ZoneId.of("America/Chicago");
You can start with Instant, a java util date equalivent.
Instant instant = Instant.now();
ZonedDateTime zonedDateTime = instant.atZone(zoneId);
Or
You can also start with
using ZonedDateTime
You can take datetime as LocalDateTime, time zone agnostic class and convert to ZonedDateTime.
LocalDateTime ldt = LocalDateTime.now();
ZonedDateTime zdt = ldt.atZone(zoneId);
You can easliy switch betweeen old date time classes & new time by accessing the helper methods on each of the new/old date time classes.
Change to java util date while saving to mongo database
//From ZonedDateTime to java util date.
Date oldDate = Date.from(zdt.toInstant());
//From Instant to java util date
Date oldDate = Date.from(instant);
//From Date to Instant.
Instant instant = date.toInstant();
All the new date time api have default formatter built into it.
//2007-12-03T10:15:30-06:00[America/Chicago]
String zonedDatetime = zonedDateTime.toString();
For specfic format you can always pass the DateTimeFormatter to the below method.
zonedDateTime.format(formatter)

In Java, Can the Date type just hold MM-dd-yyyy or just hh:mm:ss?

I am converting epoch format time to the normal format, but when I convert it to date I get, MM-dd-yyyy hh:mm:ss.
If I want to single out just the date or the time I have to use SimpleDateFormat. But this returns a String. I was wondering if there was a way to make this string a Date type.
The type java.util.Date is actually a timestamp, it is not much more than a wrapper for a number of milliseconds since 01-01-1970, 00:00:00 UTC. (The class name Date is unfortunately badly chosen).
It is not very well suited for holding just a date or just a time value.
If you are using Java 8, use the new date and time API (package java.time); use for example LocalDate if you need to store a year/month/day, or a LocalTime if you need to store just a time-of-day (hours, minutes, seconds, milliseconds).
If you are using Java 7 or older, consider using the equivalent classes in the Joda Time library.
You can format the date as MM-dd-yyyy HH:mm:ss not (MM-dd-yyyy hh:mm:ss)
https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
DateFormat dateformat= new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");
Date date = dateformat.parse("01-25-1988 23:54:59");
System.out.println(date);
System.out.println(dateformat.format(date));

Convert LocalTime (Java 8) to Date

I'm trying to convert a java.time.LocalTime object to java.util.Date but can't find any suitable method. What's the correct way to do this?
Is there any reason why java doesn't seem to ship with a built-in direct conversion method?
To possible duplicates:
How to convert joda time - Doesn't work for me, probably I'm missing some "joda" libraries?
How to convert Date to LocalTime? - This adresses conversion the other way around.
LocalTime actually can't be converted to a Date, because it only contains the time part of DateTime. Like 11:00. But no day is known. You have to supply it manually:
LocalTime lt = ...;
Instant instant = lt.atDate(LocalDate.of(A_YEAR, A_MONTH, A_DAY)).
atZone(ZoneId.systemDefault()).toInstant();
Date time = Date.from(instant);
Here's a blog post which explains all the conversions between the new and the old API.
There's no simple built-in conversion method, because these APIs approach the idea of date and time in completely different way.
LocalTime lt = ...;
Instant instant = lt.atDate(LocalDate.of(A_YEAR, A_MONTH, A_DAY)).
atZone(ZoneId.systemDefault()).toInstant();
Date time = Date.from(instant);
From :
http://blog.progs.be/542/date-to-java-time
I added the data (hour, minute, second) one by one (from localtime to date):
reta.setHours(vol.getRetard().getHour());
reta.setMinutes(vol.getRetard().getMinute());
reta.setSeconds(vol.getRetard().getSecond());
Note :
reta: Date veriabble ;
vol.getRetard (): localtime variable
As others have said, it’s a problematic question in that a LocalTime and a Date really represent quite different and almost unrelated concepts. A LocalTime is a time of day without time zone, such as 19:45 (or 7:45 PM). A Date is a point on the time line; if it happens to coincide with 19:45 on some date in some time zone, it will not in other time zones.
I believe that the conventional way of misusing (indeed) a Date for an hour of day is setting it to that time of day on January 1, 1970 in the default time zone of the JVM. This practice carries all of the liabilities already mentioned. In particular the JVM default time zone setting can be changed at any time from another part of your program or any other program running in the same JVM. This means that a completely unrelated program may suddenly cause your Date to indicate a different time of day than the one you had initialized it to.
There’s nothing better we can do, so here goes:
LocalTime time = LocalTime.of(11, 0);
Instant timeOnEpochDayInDefaultTimeZone = LocalDate.EPOCH
.atTime(time)
.atZone(ZoneId.systemDefault())
.toInstant();
Date oldfashionedDateObject = Date.from(timeOnEpochDayInDefaultTimeZone);
System.out.println(oldfashionedDateObject);
In my time zone output from this snippet is:
Thu Jan 01 11:00:00 CET 1970
Here is another approach:
We can add a LocalDate to the LocalTime in order to make it a LocalDateTime and then convert it to Date using the valueOf method of java.sql.Timestamp like this:
LocalTime localTime = LocalTime.now();
Date date = java.sql.Timestamp.valueOf(localTime.atDate(LocalDate.now()));
As #Dariusz said, we cannot convert LocalTime to Date directly as it contains only time part but Date must contain all the value along with the timeZone.
In order to get the date part, we can use LocalDate.now(). It will give us LocalDate object with today's date.
Now, we have both LocalDate and LocalTime, we can now use the LocalDateTime.of(date: LocalDate, time: LocalTime) or localTime.atDate(date: LocalDate) to get the LocalDateTime object.
And now we can convert the LocalDateTime to Date using below kotlin extension function.
fun LocalDateTime.toDate(): Date {
return Date.from(this.atZone(ZoneId.systemDefault()).toInstant())
}

Categories