1

I have date 2015-12-25 23:59:59 in the form of epoch milliseconds 1451087999000, And I want the date part only i.e. 2015/12/25, how do I do that efficiently might be with the JODA time library which is nowdays standard for dealing with Date time in java.

I have this code which works in most the case but when time is like 23:59:59 it gives me the next date (as in my case it gives 2015-12-26 with input of 2015-12-25 23:59:59)-

String dateInMilliSeconds = "1451087999000";
String dateInYYYYMMDDFormat = DateHelper.convertDateFormat(new Date(Long.valueOf(dateInMilliSeconds)),DateHelper.yyyy_MM_dd);

DateHelper.convertDateFormat() -

public static final String yyyy_MM_dd = "yyyy-MM-dd";
public static String convertDateFormat( Date date, String outputFormat )
{
    String returnDate = "";
    if( null != date )
    {
        SimpleDateFormat formatter = new SimpleDateFormat(outputFormat);
        returnDate = formatter.format(date);
    }
    return returnDate;
}
thedevd
  • 683
  • 11
  • 26
  • 1
    It's been a long time since I've used Java but this sounds like a typical timezone offset problem to me. E.g.: epoch is defined at UTC, while you display your output time in your (server's) local timezone. Or something similar to that. – Geert-Jan Sep 19 '17 at 09:47
  • 2
    From the timestamp, you can build a `java.util.Date`. From this point, you can convert it to a `LocalDate` but you will have to specify a timezone as `2015-12-25 23:59:59` can aswell be `2015-12-26 00:59:59` in another timezone. – Arnaud Denoyelle Sep 19 '17 at 09:49
  • 1
    Use `Long.parseLong` rather than `Long.valueOf`. Also, Joda time is old; use classes from the java.time package (in Java 8 or 9) instead. – DodgyCodeException Sep 19 '17 at 09:54
  • I can't help you with Jodatime, just want to mention that even on the Jodatime homepage it states "Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.". If you are ok with java.time I can provide a solution, however there is one already anyway :) – findusl Sep 19 '17 at 09:58
  • [This answer: Convert Epoch seconds to date and time format in Java](https://stackoverflow.com/a/38547492/5772882) will get you most of the way. – Ole V.V. Sep 19 '17 at 10:02

3 Answers3

4

You can use localDate from java 8

LocalDate date = Instant.ofEpochMilli(dateInMilliSeconds).atZone(ZoneId.of(timeZone)).toLocalDate();
Count
  • 1,395
  • 2
  • 19
  • 40
  • This also worked. It is good to use passed timezone instead of using systemDefault like- String timeZone = "Etc/Greenwich" and then .atZone(ZoneId.of(timeZone)). – thedevd Sep 19 '17 at 10:25
  • 2
    I applaud using Java 8 (or the ThreeTen Backport with Java 6 and 7, the code is the same). Running your code line on my computer I get `2015-12-26`,the day after the desired day. This is because your code uses my JVM’s time zone, Europe/Copenhagen. Better to use UTC. – Ole V.V. Sep 19 '17 at 10:29
  • Thanks @OleV.V. Added zone . – Count Sep 19 '17 at 10:47
3

I should like to make two points:

  1. Time zone is crucial.
  2. Skip the outdated classes Date and SimpleDateFormat.

My suggestion is:

    String dateInMilliSeconds = "1451087999000";
    LocalDate date = Instant.ofEpochMilli(Long.parseLong(dateInMilliSeconds))
            .atOffset(ZoneOffset.UTC)
            .toLocalDate();
    System.out.println(date);

This prints

2015-12-25

Please note that you get your desired output format for free: LocalDate.toString() produces it. If you want to be able to produce different output formats, use a DateTimeFormatter.

Time zone

Your millisecond value isn’t just equal to 2015-12-25 23:59:59. It is equal to this date and time in UTC, so you need to make sure that your conversion uses this time zone offset. When I run your code from the question on my computer, I incorrectly get 2015-12-26 because my computer is in the Europe/Copenhagen time zone.

JSR-310 AKA java.time

Joda-Time was the widely acknowledged better alternative to the original date and time API from Java 1 that many considered poor and troublesome. The Joda-Time project is now finished because the modern Java date and time API known as JSR-310 or java.time came out three and a half years ago, so they recommend we use this instead. So my code does.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
1

The timestamp 1451087999000 is 2015-12-25 23:59:59 in UTC. In your code, you're not specifying the timezone when you format it with a SimpleDateFormat, so it's formatted in your local timezone.

With Joda Time:

String dateInMilliSeconds = "1451087999000";

LocalDate date = new LocalDate(Long.parseLong(dateInMilliSeconds), DateTimeZone.UTC);

DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");

String result = formatter.print(date);
Jesper
  • 202,709
  • 46
  • 318
  • 350
  • 1
    I guess we can get the output directly using date.toString() method instead of using DateTimeFormatter since I am sure that date is already formatted in yyyy-MM-dd, right?, By the way thanks this solved my problem. – thedevd Sep 19 '17 at 10:12
  • Yes, @thedevd, the way I read [the API documentation](http://www.joda.org/joda-time/apidocs/org/joda/time/LocalDate.html#toString--), you are correct, you can. – Ole V.V. Sep 19 '17 at 12:32