169

I have milliseconds in certain log file generated in server, I also know the locale from where the log file was generated, my problem is to convert milliseconds to date in specified format. The processing of that log is happening on server located in different time zone. While converting to "SimpleDateFormat" program is taking date of the machine as such formatted date do not represent correct time of the server. Is there any way to handle this elegantly ?

long yourmilliseconds = 1322018752992l;
        //1322018752992-Nov 22, 2011 9:25:52 PM 

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS",Locale.US);

GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("US/Central"));
calendar.setTimeInMillis(yourmilliseconds);

System.out.println("GregorianCalendar -"+sdf.format(calendar.getTime()));

DateTime jodaTime = new DateTime(yourmilliseconds, 
                    DateTimeZone.forTimeZone(TimeZone.getTimeZone("US/Central")));
DateTimeFormatter parser1 = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss,SSS");

System.out.println("jodaTime "+parser1.print(jodaTime));

Output:

Gregorian Calendar -2011-11-23 08:55:52,992
jodaTime 2011-11-22 21:25:52,992
nbro
  • 15,395
  • 32
  • 113
  • 196
Amit
  • 2,080
  • 3
  • 19
  • 24
  • 1
    Don't confuse Locale with time zone. Totally separate. Locale determines human language for name of months and days, and cultural norms such as order of parts like month, day, etc. A time zone is offset-from-UTC plus rules for handling anomalies such as Daylight Saving Time. – Basil Bourque Apr 10 '16 at 22:33
  • Was the problem that the number of milliseconds was a count not from 1970-01-01T00:00:00Z but from some other moment? – Basil Bourque Apr 10 '16 at 22:36
  • FYI, both the terrible old date-time classes (`GregorianCalendar`, `SimpleDateFormat`, etc.) and the excellent Joda-Time library are now supplanted by the modern *java.time* classes. – Basil Bourque Oct 16 '18 at 00:23

13 Answers13

283

You may use java.util.Date class and then use SimpleDateFormat to format the Date.

Date date=new Date(millis);

We can use java.time package (tutorial) - DateTime APIs introduced in the Java SE 8.

var instance = java.time.Instant.ofEpochMilli(millis);
var localDateTime = java.time.LocalDateTime
                        .ofInstant(instance, java.time.ZoneId.of("Asia/Kolkata"));
var zonedDateTime = java.time.ZonedDateTime
                            .ofInstant(instance,java.time.ZoneId.of("Asia/Kolkata"));

// Format the date

var formatter = java.time.format.DateTimeFormatter.ofPattern("u-M-d hh:mm:ss a O");
var string = zonedDateTime.format(formatter);
KV Prajapati
  • 93,659
  • 19
  • 148
  • 186
  • 2
    Nope. Not all methods of `java.util.Date` are depreciated. ( There is improved Date & Time APIs In JDK8's `java.time`) – KV Prajapati Sep 15 '15 at 01:42
  • 1
    @RafaelZeffa , the '''Date(long date)''' constructor is not deprecated – gokan Nov 21 '15 at 12:12
  • The Date object is provided for backward compatibility. Better use Calendar as suggested above. – Ton Snoei Jan 17 '18 at 09:15
  • 3
    FYI, the terribly troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Oct 16 '18 at 00:24
136
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timeStamp);

int mYear = calendar.get(Calendar.YEAR);
int mMonth = calendar.get(Calendar.MONTH);
int mDay = calendar.get(Calendar.DAY_OF_MONTH);
nbro
  • 15,395
  • 32
  • 113
  • 196
Faisal Ashraf
  • 1,456
  • 1
  • 12
  • 11
  • I had to set Calendar as final to make it work. `final Calendar calendar = Calendar.getInstance();` – Victor Augusto Nov 18 '14 at 20:23
  • 5
    Calendar objects are generally considered quite large, so should be avoided when possible. A Date object is going to be better assuming it has the functionality you need. "Date date=new Date(millis);" provided in the other answer by user AVD is going to be the best route :) – Dick Lucas Jul 17 '15 at 18:15
  • 1
    Somehow, for `1515436200000l`, I am getting `calendar.get(Calendar.MONTH))` as `0`! – Sajib Acharya Jan 06 '18 at 14:22
  • 1
    FYI, the terribly troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Oct 16 '18 at 00:24
  • 2
    @SajibAcharya Note that the instances for Calendar.MONTH start at 0; you need to add one to get the "real" month as we know it. Example: 0 = January, 1 = February, 2 = March, etc. – shagberg Dec 07 '18 at 21:21
26

tl;dr

Instant.ofEpochMilli( 1_322_018_752_992L )     // Parse count of milliseconds-since-start-of-1970-UTC into an `Instant`.
       .atZone( ZoneId.of( "Africa/Tunis" ) )  // Assign a time zone to the `Instant` to produce a `ZonedDateTime` object.

Details

The other answers use outmoded or incorrect classes.

Avoid the old date-time classes such as java.util.Date/.Calendar. They have proven to be poorly designed, confusing, and troublesome.

java.time

The java.time framework comes built into Java 8 and later. Much of the functionality is backported to Java 6 & 7 and further adapted to Android. Made by the some of the same folks as had made Joda-Time.

An Instant is a moment on the timeline in UTC with a resolution of nanoseconds. Its epoch is first moment of 1970 in UTC.

Assuming your input data is a count of milliseconds from 1970-01-01T00:00:00Z (not clear in the Question), then we can easily instantiate an Instant.

Instant instant = Instant.ofEpochMilli( 1_322_018_752_992L );

instant.toString(): 2011-11-23T03:25:52.992Z

The Z in that standard ISO 8601 formatted string is short for Zulu and means UTC.

Apply a time zone using a proper time zone name, to get a ZonedDateTime.

ZoneId zoneId = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( zoneId );

See this code run live at IdeOne.com.

Asia/Kolkata time zone ?

I am guessing your are had an India time zone affecting your code. We see here that adjusting into Asia/Kolkata time zone renders the same time-of-day as you report, 08:55 which is five and a half hours ahead of our UTC value 03:25.

2011-11-23T08:55:52.992+05:30[Asia/Kolkata]

Default zone

You can apply the current default time zone of the JVM. Beware that the default can change at any moment during runtime. Any code in any thread of any app within the JVM can change the current default. If important, ask the user for their desired/expected time zone.

ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

With a JDBC driver complying with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings or java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
14

The easiest way to do this is to use the Joda DateTime class and specify both the timestamp in milliseconds and the DateTimeZone you want.

I strongly recommend avoiding the built-in Java Date and Calendar classes; they're terrible.

Cameron Skinner
  • 51,692
  • 2
  • 65
  • 86
  • GorgianCalender didn't work... for whatever reason it took system default time zone. Joda worked perfectly. – Amit Nov 23 '11 at 05:04
  • Let me know looking at the sample code if we can do some thing different with Gregorian – Amit Nov 23 '11 at 05:16
  • 1
    FYI, the [*Joda-Time*](http://www.joda.org/joda-time/) project is now in [maintenance mode](https://en.wikipedia.org/wiki/Maintenance_mode), advising migration to the [*java.time*](http://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Oct 16 '18 at 00:24
13

My Solution

public class CalendarUtils {

    public static String dateFormat = "dd-MM-yyyy hh:mm";
    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);

    public static String ConvertMilliSecondsToFormattedDate(String milliSeconds){
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(Long.parseLong(milliSeconds));
        return simpleDateFormat.format(calendar.getTime());
    }
}
Siddarth Kanted
  • 5,738
  • 1
  • 29
  • 20
13

If the millis value is number of millis since Jan 1, 1970 GMT, as is standard for the JVM, then that is independent of time zone. If you want to format it with a specific time zone, you can simply convert it to a GregorianCalendar object and set the timezone. After that there are numerous ways to format it.

BillRobertson42
  • 12,602
  • 4
  • 40
  • 57
  • 1
    This is the sample code with GregorianCalendar and Joda, I am getting correct output with Joda but not with Gregorian GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("US/Central")); calendar.setTimeInMillis(yourmilliseconds); DateTime jodaTime = new DateTime(yourmilliseconds,DateTimeZone.forTimeZone(TimeZone.getTimeZone("US/Central"))); DateTimeFormatter parser1 = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss,SSS"); – Amit Nov 23 '11 at 05:10
  • Setting the time zone in the calendar object did not work, but setting it in the date formatter object did? – BillRobertson42 Nov 23 '11 at 13:27
  • What is DateTime and DateTimeFormatter?? – SweetWisher ツ Nov 15 '13 at 06:41
7

Easiest way:

private String millisToDate(long millis){

    return DateFormat.getDateInstance(DateFormat.SHORT).format(millis);
    //You can use DateFormat.LONG instead of SHORT

}
Joaquin Iurchuk
  • 5,499
  • 2
  • 48
  • 64
7

I do it like this:

static String formatDate(long dateInMillis) {
    Date date = new Date(dateInMillis);
    return DateFormat.getDateInstance().format(date);
}

You can also use getDateInstance(int style) with following parameters:

DateFormat.SHORT

DateFormat.MEDIUM

DateFormat.LONG

DateFormat.FULL

DateFormat.DEFAULT

Yogesh Umesh Vaity
  • 41,009
  • 21
  • 145
  • 105
5

The SimpleDateFormat class has a method called SetTimeZone(TimeZone) that is inherited from the DateFormat class. http://docs.oracle.com/javase/6/docs/api/java/text/DateFormat.html

Jessica Brown
  • 8,222
  • 7
  • 46
  • 82
3

You can try java.time api;

        Instant date = Instant.ofEpochMilli(1549362600000l);
        LocalDateTime utc = LocalDateTime.ofInstant(date, ZoneOffset.UTC);
Narendar Reddy M
  • 1,499
  • 1
  • 11
  • 18
2

Below is my solution to get date from miliseconds to date format. You have to use Joda Library to get this code run.

import java.util.GregorianCalendar;
import java.util.TimeZone;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class time {

    public static void main(String args[]){

        String str = "1431601084000";
        long geTime= Long.parseLong(str);
        GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("US/Central"));
        calendar.setTimeInMillis(geTime);
        DateTime jodaTime = new DateTime(geTime, 
               DateTimeZone.forTimeZone(TimeZone.getTimeZone("US/Central")));
        DateTimeFormatter parser1 = DateTimeFormat.forPattern("yyyy-MM-dd");
        System.out.println("Get Time : "+parser1.print(jodaTime));

   }
}
Archit
  • 57
  • 2
  • 8
1
 public static String getFormatTimeWithTZ(Date currentTime) {
    SimpleDateFormat timeZoneDate = new SimpleDateFormat("EEE, dd-MM-yyyy  hh:mm a", Locale.getDefault());
    return timeZoneDate.format(currentTime);
}

Output is

Mon,01-03-2021 07:37 PM

and

public static String getFormatTimeWithTZ(Date currentTime) {
    SimpleDateFormat timeZoneDate = new SimpleDateFormat("EEE, dd-MM-yyyy  HH:mm ", Locale.getDefault());
    return timeZoneDate.format(currentTime);
}

output is

Mon,01-03-2021 19:37

if you do not want the Days Then Remove EEE,
if you do not want the Date Then Remove dd-MM-yyyy
If you want Time in Hour, Minutes, Second, Millisecond then Use HH:mm:ss.SSS

and Call this method where you want

getFormatTimeWithTZ(Mydate)

where

Date Mydate = new Date(System.currentTimeMillis());
0
public static LocalDateTime timestampToLocalDateTime(Long timestamp) {
    return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), TimeZone.getDefault().toZoneId());
}
Typsou
  • 9
  • 1
  • 1
    Duplicate of existing answer? https://stackoverflow.com/a/54666195/5990117 – Petr Aleksandrov Nov 13 '20 at 15:36
  • 1
    I recommend you don’t use `TimeZone`. That class is poorly designed and long outdated, and using it here involves an unnecessary conversion. Just do `LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault())`. – Ole V.V. Nov 13 '20 at 20:04