How can I get a date (day, month, year, time, minute, and second) converted into milliseconds in Java?

Asked

Viewed 10,421 times

7

How can I get a date in milliseconds?

Example: 24, Sat, Jan, 17:39:50 2015

4 answers

8


It depends on how you want to use it has several ways, one of them can be:

import java.util.*;
import java.lang.*;
import java.io.*;
import java.text.*;

class Ideone {
    public static void main (String[] args) throws java.lang.Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        Date date = sdf.parse("2015-01-24 17:39:50.000");
        System.out.println(date.getTime());
    }
}

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

  • One detail is that SimpleDateFormat will use the Timezone default JVM, so depending on what is configured, the value of getTime() can change. I put more details on this in the my answer

  • 1

    @hkotsubo this, cool.

6

The @Maniero response directly answers what was asked. However, I will add some more details on the millisecond question.

Date

The class java.util.Date represents internally the date using the amount of milliseconds passed since 1 January 1970 UTC (known as epoch) in an attribute of the type long. So much so that its only recommended builder gets just the time in ms.

Example:

Date data = new Date(1422279151249l);

Even when we use the empty constructor, which creates a date with the current date and time, actually internally the class Date simply calls the method System.currentTimeMillis() to recover the current milliseconds and forward to the other builder:

public Date() {
    this(System.currentTimeMillis());
}

To regain internal time in milliseconds, simply use the method getTime():

data.getTime();

It is possible to modify the date with the method setTime():

data.setTime(1422279151249l);

But this is not recommended, as it hurts the principle of immutability of the object and in some cases may result in unexpected behaviors.

Converting String for Date

Use the class java.text.SimpleDateFormat. Example:

Date data = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2015-01-24 17:39:50");

Calendar

The class java.util.Calendar is quite different from java.util.Date. It stores information about a date in an internal vector with several positions, including the time zone.

In addition, the class Calendar is abstract, because there are different calendars that implement it, the most common being the GregorianCalendar.

To create an instance of Calendar at the current time and with the default settings of your JVM, just call the method getInstance class:

Calendar cal = Calendar.getInstance();

To regain time in milliseconds since the epoch, just use the method getTimeInMillis():

cal.getTimeInMillis()

To change the time using milliseconds, use the method Setter equivalent:

cal.setTimeInMillis(1422279151249l);

Other than class Date, the class Calendar allows you to easily recover parts of the date. For example, to recover the time of a date:

int hora = cal.get(Calendar.HOUR);

Or to retrieve milliseconds of a date:

int hora = cal.get(Calendar.MILLISECOND);

But note that the value returned has nothing to do with the return of the method getTimeInMillis. While this returns the number of milliseconds since the epoch, that contains the value of milliseconds of the current time, that is, a number between 0 and 999.

To "convert" a Date in Calendar, use the methods getTime() and setTime():

Calendar cal = Calendar.getInstance();
Date data = cal.getTime(); 
cal.setTime(data);

Converting String for Calendar

As the documentation itself warns, the class Calendar no implementations to convert text to date or format date to text.

Therefore, the solution is to use SimpleDateFormat to generate a Date and then pass the information on to Calendar:

Date data = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2015-01-24 17:39:50");
Calendar cal = Calendar.getInstance();
cal.setTime(data);

LocalDateTime (Java 8)

From Java 8 you should represent date and time using java.time.LocalDateTime. This class is immutable, therefore thread-safe, in addition to much more reliable than the previous ones. It also has greater precision, in the nanosecond house.

To get the current date and time, use the method Factory now():

LocalDateTime dateTime = LocalDateTime.now();

To get the milliseconds from the epoch, you can use the method toEpochSecond() and multiply the result by 1000:

long ms = 1000 * dateTime.toEpochSecond(ZoneOffset.UTC);

On the other hand, to recover the amount of milliseconds passed since the last second, use the method get():

long ms = dateTime.get(ChronoField.MILLI_OF_SECOND);

Note that it is very similar to the class Calendar in that respect.

Converting String for LocalDateTime

Use the new class DateTimeFormatter:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

Then it is possible so much to do the parse:

LocalDateTime data = LocalDateTime.from(formatter.parse("2015-01-24 17:39:50"));

How to format the date:

String dataFormatada = data.format(formatter);
  • 1

    thanks for the explanation.

  • 1

    One detail is that SimpleDateFormat uses the Timezone default JVM and depending on this setting, the timestamp value may change. I detail this in my answer

  • 1

    @hkotsubo Good observation, you should always inform Timezone when possible.

3

Just to complement, a point that was not addressed in the other replies.

Timestamp

In accordance with the reply from @utluiz explains, the amount you are asking for (returned by date.getTime()) is the amount of milliseconds since Unix Epoch (which is 1970-01-01T00:00Z - January 1, 1970, midnight, at UTC). This field has many names (Unix Time, Unix Timestamp, etc), but I’ll just call it timestamp to cut short.

One detail about this number is that it is the same all over the world.

For example, if I run now (at this very moment I write), a program that takes the value of System.currentTimeMillis() (a method that returns the timestamp corresponding to the current date and time), the result will be 1529496070462.

This value is the same all over the world. Any computer anywhere on the planet that ran this program at this very moment would have that same result.

The difference is that this same value may correspond to a different date and time, depending on the time zone you are in. Below is a list of the date and time values, in each place of the world, that correspond to this timestamp:

  • São Paulo: June 20, 2018, 09:01:10,462
  • London: June 20, 2018, at 13:01:10.462
  • Auckland (New Zealand): 21 June 2018, at 00:01:10.462

Notice that in São Paulo and London the day is the same, but the time is not. And in Auckland, even the day is different (there is already day 21).

But all these dates and times correspond to same moment (at the same point in the timeline). In other words, the value of the timestamp is the same.

Why am I saying all this?

Because the date you’re using (24, Sáb, Jan, 17:39:50 2015) has no information about the time zone, so it may result in a different timestamp value (the "millisecond value" you want) depending on the time zone you use.

To reply by @Maniero uses SimpleDateFormat, and this class will use the Timezone default of the JVM (the default time zone that is used by Java when you do not specify any). And depending on what you set up, you can get a different value.

Another detail is that, in your String, the day of the week and month are in Portuguese, so it is important to use a java.util.Locale also. If you do not specify the locale, the SimpleDateFormat will use the default JVM, and it can’t always be the language you need. So the code looks like this:

// usar locale pt_BR (português)
SimpleDateFormat sdf = new SimpleDateFormat("dd, EEE, MMM, HH:mm:ss yyyy", new Locale("pt", "BR"));
Date date = sdf.parse("24, Sáb, Jan, 17:39:50 2015");
System.out.println(date.getTime());

The result will be 1422128390000, which is a timestamp that corresponds to January 24, 2015, at 5:39:50 pm in São Paulo. That’s because Timezone default of the JVM I’m using is America/Sao_Paulo (you can see which one is yours using TimeZone.getDefault()).

But if I change Timezone default, the timestamp value will be different. Example:

// mudando o timezone default
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Tokyo"));
SimpleDateFormat sdf = new SimpleDateFormat("dd, EEE, MMM, HH:mm:ss yyyy", new Locale("pt", "BR"));
Date date = sdf.parse("24, Sáb, Jan, 17:39:50 2015");
System.out.println(date.getTime());

I changed the Timezone default for Asia/Tokyo, and now the SimpleDateFormat will use this Timezone to do the Parsing date. The result shall be 1422088790000, corresponding to 24 January 2015 at 17:39:50 in Tokyo.
This same timestamp, in São Paulo, corresponds to 24 January 2015, to 06:39:50 (the difference is not 12 hours because on this day Sao Paulo was in daylight saving time).

That is, depending on the Timezone configured, the SimpleDateFormat can return a different value. And rely on the configuration default not always a good idea, since any point of your system can call TimeZone.setDefault (even other applications running on the same JVM), and this will affect all code running on this JVM. Or the infrateam can update the server and change the Timezone (on purpose or unintentionally), and not warn you about it. Anyway, it’s not something you have a lot of control over.

Therefore, an alternative is to set a Timezone on its own SimpleDateFormat, and so you do not depend on the Timezone default. Example:

// mudando o timezone default
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Tokyo"));
SimpleDateFormat sdf = new SimpleDateFormat("dd, EEE, MMM, HH:mm:ss yyyy", new Locale("pt", "BR"));
// setar um timezone no SimpleDateFormat, para não depender do default
sdf.setTimeZone(TimeZone.getTimeZone("America/Sao_Paulo"));
Date date = sdf.parse("24, Sáb, Jan, 17:39:50 2015");
System.out.println(date.getTime());

How I set up Timezone America/Sao_Paulo in the SimpleDateFormat, he will use this Timezone to make the Parsing, ignoring the Timezone default. So the result is 1422128390000 (January 24, 2015 at 5:39:50 pm in São Paulo).

If you know that date and time corresponds to a specific Timezone, use it on SimpleDateFormat, rather than depending on the configuration default of the JVM (which can change without you noticing).

If instead of a specific Timezone, you want to use UTC, you can do TimeZone.getTimeZone("UTC").

Java 8

From Java 8 there is the API java.time. In this API, the conversion is similar: you need to know which Timezone to use to convert the date and time to the timestamp.

First we get a java.time.LocalDateTime (a class that has date and time). For this, we use a java.time.format.DateTimeFormatter to do the Parsing. Here, we also need to use a java.util.Locale, because the day of the week and month are in Portuguese, and it is better to use a specific locale than depending on the configuration default jvm.

Another detail is that some location information has changed in Java 8, then the month with capital letter did not work in my test (JDK 1.8.0_144). So I also wear one java.time.format.DateTimeFormatterBuilder, that makes it possible to create a DateTimeFormatter case insensitive:

DateTimeFormatter parser = new DateTimeFormatterBuilder()
    // ignorar maiúsculas
    .parseCaseInsensitive()
    // pattern para data e hora
    .appendPattern("dd, EEE, MMM, HH:mm:ss uuuu")
    // usar locale pt_BR, pois o dia da semana e mês estão em português
    .toFormatter(new Locale("pt", "BR"));
LocalDateTime dateTime = LocalDateTime.parse("24, Sáb, Jan, 17:39:50 2015", parser);

The class LocalDateTime has only the date and time, without any notion of time zones. To convert it to a Timezone, I need to use a java.time.ZoneId, and then I use the result to get the value of timestamp:

long timestamp = dateTime
    // converte para um timezone
    .atZone(ZoneId.of("America/Sao_Paulo"))
    // obtém o timestamp em milissegundos
    .toInstant().toEpochMilli();

How I chose Timezone America/Sao_Paulo, the value of the timestamp will be 1422128390000 (as it corresponds to January 24, 2015, at 5:39:50 pm in São Paulo).

If you want another Timezone, just change the name passed to ZoneId.of. Always prefer the names on standard of the IANA (in the "Continent/Region" format, as America/Sao_Paulo, Europe/London, etc). You can use the method ZoneId.getAvailableZoneIds(), which returns all valid names.

If you choose to use Timezone default jvm, use ZoneId.systemDefault(). Remembering all the cares already mentioned above, about the fact of Timezone default can be changed without you noticing.

And to use UTC, use the constant ZoneOffset.UTC.

Use java.time in versions prior to Java 8

For JDK 6 and 7, there is the Threeten Backport, which is a backport of java.time. This backport contains the same Java 8 classes (with the same names, methods and operation).

The difference is, instead of being in the package java.time, are in the package org.threeten.bp. But the way to use will be the same as explained above.

I recommend using these options (java.time for JDK >= 8 and Threeten Backport for JDK 6 and 7), as it is a much higher API than Date, Calendar and SimpleDateFormat (who possess many problems and questionable design decisions - reasons for creating a new date API).

Joda-Time

In your own website, Joda-Time recommends using the java.time:

Note that Joda-Time is considered to be a largely "finished" project. No major Nhancements are Planned. If using Java SE 8, Please migrate to java.time (JSR-310).

Free translation: "Note that Joda-Time is considered a 'shut down' project. No improvements planned. If you are using Java SE 8, please migrate to java.time (JSR-310)."

Anyway, it’s an alternative for anyone who’s still tied to JDK 5 and wants to wear something better than Date and Calendar (see here a more detailed discussion, then you can decide better whether to use it or not). The operation is similar to the java.time: do Parsing, convert to a Timezone and get the timestamp.

Some classes have the same class names as the java.time, but they stay in the package org.joda.time, and beyond that, they’re not exactly the same.

DateTimeFormatter parser = DateTimeFormat.forPattern("dd, EEE, MMM, HH:mm:ss yyyy")
    // usar locale pt_BR, pois o dia da semana e mês estão em português
    .withLocale(new Locale("pt", "BR"));
LocalDateTime dateTime = parser.parseLocalDateTime("24, Sáb, Jan, 17:39:50 2015");
long timestamp = dateTime
    // converter para um timezone
    .toDateTime(DateTimeZone.forID("America/Sao_Paulo"))
    // obter o timestamp
    .getMillis();
  • 1

    About java-8 there is also a wiki on the website about it: https://answall.com/questions/177129/como-migrar-de-date-e-calendar-para-a-nova-api-de-datas-no-java-8

  • @Yes, I saw it. I just wanted to give a solution using the java.time API, since the other answers don’t do the Parsing of String that is in question (and I took the opportunity to put more details also).

  • 1

    Yes, it was just complementary (and to be referenced in the sidelist) my comment, your answer goes far beyond just talking about java-8 :)

1

Only want the millisecond? Use java.sql.Timestamp:

import java.sql.Timestamp;

public class DateTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        System.out.println(new Timestamp(System.currentTimeMillis()));
    }
}

If you want EVERYTHING, you can use Joda and you can do this in three lines:

(http://joda-time.sourceforge.net/)

DateTime jodaTime = new DateTime();

DateTimeFormatter formatter = DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss.SSS");
System.out.println("jodaTime = " + formatter.print(jodaTime));

You also have direct access to individual date fields without using a calendar.

System.out.println("year = " + jodaTime.getYear());
System.out.println("month = " + jodaTime.getMonthOfYear());
System.out.println("day = " + jodaTime.getDayOfMonth());
System.out.println("hour = " + jodaTime.getHourOfDay());
System.out.println("minute = " + jodaTime.getMinuteOfHour());
System.out.println("second = " + jodaTime.getSecondOfMinute());
System.out.println("millis = " + jodaTime.getMillisOfSecond());

Exit :)

jodaTime = 2010-04-16 18:09:26.060

year = 2010
month = 4
day = 16
hour = 18
minute = 9
second = 26
millis = 60 **O QUE VOCÊ PEDIU NO COMENTÁRIO**

Or use java.util.Calendar.

Calendar now = Calendar.getInstance();
int year = now.get(Calendar.YEAR);
int month = now.get(Calendar.MONTH); // Note: zero based!
int day = now.get(Calendar.DAY_OF_MONTH);
int hour = now.get(Calendar.HOUR_OF_DAY);
int minute = now.get(Calendar.MINUTE);
int second = now.get(Calendar.SECOND);
int millis = now.get(Calendar.MILLISECOND);

System.out.printf("%d-%02d-%02d %02d:%02d:%02d.%03d", year, month + 1, day, hour, minute, second, millis);

Source: https://stackoverflow.com/questions/2654025/how-to-get-year-month-day-hours-minutes-seconds-and-milliseconds-of-the-cur

  • Even though my question was not answered, these passages served to build my answer. Thank you ;)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.