-3

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;
}
srikanth
  • 958
  • 16
  • 37
  • 1
    Not by "default" but **ONLY**. UTC Is **always** the only format you should ever be storing any date data in. What you are building on is the wealth of experience by others who came before you. Learn from it. – Neil Lunn Aug 31 '17 at 07:49
  • 1
    A `Date` has no [timezone information](https://codeblog.jonskeet.uk/2017/04/23/all-about-java-util-date), so technically there's no conversion to be made - the timestamp value (aka "the number of milliseconds since `1970-01-01T00:00Z`") will be the same, no matter in what timezone you are. If you want to convert the **values of the fields** (day/month/year/hour/minutes/seconds) to the corresponding values in another timezone, then it'd make sense (but in this case, you should return a `String` representation of those values, not a `Date`). –  Aug 31 '17 at 12:10
  • 1
    If you can (which you can), I recommend you scrap the outdated `Date` class. The modern Java date & time API is much nicer to work with. Especially when it comes to converting across time zones, it provides for much clearer code. You may even be able to get yourself a newer (JDBC 4.2) MongoDB driver that will give you `Instant` objects directly; then you’re already in the sweet spot when you get the timestamp. – Ole V.V. Aug 31 '17 at 12:14
  • Possible duplicate of [Convert Date/Time for given Timezone - java](https://stackoverflow.com/questions/7670355/convert-date-time-for-given-timezone-java). I particularly recommend [Basil Bourque’s answer](https://stackoverflow.com/a/39300461/5772882). – Ole V.V. Aug 31 '17 at 12:28
  • @OleV.V. Thanks for the refernce. – srikanth Sep 01 '17 at 07:06

3 Answers3

5

You could use something like the following to get the time in a particular zone:

date.toInstant().atZone( ZoneId.of( "America/Los_Angeles" ) )
alirabiee
  • 1,286
  • 7
  • 14
  • 2
    Correct, except don’t use `CET`, but exactly what the asker is already using: `America/Los_Angeles` and other zone IDs in *region/city* format. The three and four letter time zone abbreviations are ambiguous and not standardized, and trying to use them has caused lots of trouble for others. – Ole V.V. Aug 31 '17 at 12:06
1

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.

lance-java
  • 25,497
  • 4
  • 59
  • 101
  • 1
    Joda-Time is in maintainance mode and is being replaced by the new APIs, so I don't recommend start a new project with it. Even in [joda's website](http://www.joda.org/joda-time) it says: **"Note that Joda-Time is considered to be a largely “finished” project. No major enhancements are planned. If using Java SE 8, please migrate to java.time (JSR-310)."** - for Java 8 there's the [new java.time API](https://docs.oracle.com/javase/tutorial/datetime), and for Java <= 7, there's the [ThreeTen Backport](http://www.threeten.org/threetenbp), a backport for Java 8's new date/time classes. –  Aug 31 '17 at 12:26
  • Of course if you have a huge legacy code base using Joda-Time and can't (or don't want to) migrate to new API's, then Joda is the best choice (or if you're still stuck in Java 5, as the ThreeTen backport works only in Java 6 and 7). –  Aug 31 '17 at 12:34
0

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));
}
Jujhar Singh
  • 373
  • 5
  • 16
  • Thanks. This helps. – srikanth Aug 31 '17 at 08:46
  • 1
    I am sorry, but while it may appear to give you the correct result, it gives you a wrong one. It converts a `Date` that presumably holds the correct timestamp into a `Date` that holds a different value. As lance-java said in [an answer](https://stackoverflow.com/a/45976391/5772882) and Hugo in a comment, neither of those dates hold any time zone information. – Ole V.V. Aug 31 '17 at 12:10
  • 1
    @OleV.V. Not only that. If you parse and format, you usually end up with the same `Date` - but in this specific case, it's worse because the formatter discards the milliseconds, so the result is the initial `date` with the milliseconds set to zero (not sure if the OP is aware of that). The problem is that `Date.toString()` doesn't print the milliseconds, giving the impression that it worked. –  Aug 31 '17 at 12:35