Java example

How to get the current date and time in Java

8 min read Updated Sep 2026 Runs in an isolated runtime
Quick answer

Call LocalDateTime.now() from java.time (Java 8+). To turn it into text like 2026-09-25 14:05:09.123, format it: LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")). For a moment you store, log or send to another machine, use Instant.now(), which is always UTC.

Java has two date APIs. The old one, java.util.Date, Calendar and SimpleDateFormat, is mutable, counts months from 0 and isn't thread-safe. Java 8 replaced it with java.time, modelled on the Joda-Time library, where each class says exactly what it holds: LocalDate is a date, LocalDateTime is a date and a wall-clock time with no zone, ZonedDateTime adds a time zone, and Instant is a point on the UTC timeline. Every one of them has a static now().

Two things to know before you run anything. now() reads the clock in the JVM's default time zone, and on this page's sandbox that zone is GMT, the same as UTC, just like most production servers. And the current time is different on every run, so the snippets print checks for the live values and use a frozen Clock wherever they show a concrete date. Each example runs on this page: hit Run, then edit the code and run it again.

1LocalDateTime.now() and friendsRecommended

LocalDateTime.now() gives you today's date and the current time together. LocalDate.now() and LocalTime.now() give you one half each. All three are immutable value objects with a getter for every field: getYear(), getMonthValue() (1 to 12, unlike Calendar), getDayOfMonth(), getHour() and so on, plus getMonth() and getDayOfWeek(), which return enums.

Main.java

Output

Every line is the same on every run: LocalDateTime, year >= 2026: true, today matches yyyy-MM-dd: true, three more true checks and Month, DayOfWeek. Swap the checks for System.out.println(now) to see the real value. It looks like 2026-09-25T15:02:32.968022814: ISO 8601 with a T between the date and the time, and on this JVM the clock reads down to the nanosecond. That default toString() is fine for logs, but for anything a person reads you format it, which is the next section.

2Format it with DateTimeFormatter

DateTimeFormatter.ofPattern(...) turns a pattern of letters into a formatter, and now.format(formatter) produces the string. The pattern for the classic timestamp is yyyy-MM-dd HH:mm:ss.SSS: year, month, day, 24-hour hour, minute, second and milliseconds. The snippet builds its LocalDateTime from a Clock.fixed(...) so the output never moves. now(clock) is the same call your code makes, with the clock passed in, which is also how you freeze time in tests.

Main.java

Output

Prints 2026-09-25 14:05:09.123, 25/09/2026 and 20260925_140509 (handy for file names), then Friday, September 25, 2026 at 2:05 PM and vendredi 25 septembre 2026: text inside single quotes is copied literally, and the locale decides the month and day names. ofPattern without a locale uses the JVM's default, so pass one whenever the pattern has names or a in it. The two ISO formatters give 2026-09-25T14:05:09.123 and 2026-09-25, and the last line confirms the live clock formats to the same shape. Unlike SimpleDateFormat, a DateTimeFormatter is immutable and thread-safe, so keep it in a static final field and share it.

3Pattern letters that bite: YYYY, mm, DD, hh

Pattern letters are case-sensitive, and most of the wrong-case versions are valid letters that mean something else. So a typo doesn't throw, it prints a plausible wrong date, often only on some days of the year. This snippet runs each common mistake on 28 December 2026, 21:07:03.045, a date picked to make them show up.

Main.java

Output

The correct pattern gives 2026-12-28 21:07:03.045. YYYY is the week-based year, and under US week rules 28 December 2026 is already in week 1 of 2027, so it prints 2027-12-28: a year off, from a pattern that is right on all but a few days a year. yyyy-mm-dd puts the minutes where the month should be (2026-07-28), and DD is the day of the year (2026-12-362). hh is the 12-hour clock, so 21:07 becomes 09:07:03 unless you add a for 09:07:03 PM. One S is tenths of a second, truncated, so .045 prints as 21:07:03.0: milliseconds are SSS. Finally, toString() drops seconds and fractions that are zero, printing 2026-09-25T14:05 where ISO_LOCAL_DATE_TIME prints 2026-09-25T14:05:00. Never rely on toString() for a fixed-width format.

4Time zones, Instant and epoch millis

A LocalDateTime has no zone, so it can't tell you which moment it is. When the zone matters, ask for it: ZonedDateTime.now(ZoneId.of("America/New_York")) gives the current wall-clock time in New York, daylight saving included. When you only need the moment itself, Instant.now() is the modern form of System.currentTimeMillis(): both count from 1 January 1970 UTC, and toEpochMilli() and Instant.ofEpochMilli() convert between them.

Main.java

Output

The live lines print default zone: GMT, Tokyo offset: +09:00 (Japan has no daylight saving, so that is stable) and two true checks. The fixed instant prints as 2026-09-25T14:05:09.123Z, 2026-09-25T10:05:09.123-04:00[America/New_York] (New York is on daylight time in September) and 2026-09-25T19:35:09.123+05:30: one moment, three wall clocks. Its epoch values are 1790345109123 ms, 1790345109 s, ofEpochMilli turns the millis back into 2026-09-25T14:05:09.123Z, and ofEpochSecond(0) is 1970-01-01T00:00:00Z. Use IANA zone IDs like Europe/London, not three-letter abbreviations. To time how long code takes, use System.nanoTime() instead: it can't jump when the wall clock is corrected.

5Convert to and from java.util.Date

Old APIs still hand you a java.util.Date, which, despite its name, is an instant: a count of milliseconds since the epoch with no zone. Java 8 added a bridge in each direction: date.toInstant() and Date.from(instant). A LocalDateTime has no zone, so converting it to a Date means choosing one with atZone(...) first, and converting back means choosing the zone to read it in. The end of the snippet shows two of the reasons the old classes were replaced.

Main.java

Output

The Date holds 1790345109000 and prints as Fri Sep 25 14:05:09 GMT 2026: toString() renders it in the JVM's default zone, which is why the same Date prints a different hour on your laptop. The round trip gives back 2026-09-25T14:05:09 and round trip equal: true. Reading the same wall-clock time as New York time gives an instant 4 hours apart, so pick the zone on purpose. Then the legacy traps: Calendar.MONTH is 8 for September, and SimpleDateFormat is lenient by default, so it turns month 13, day 45 into 2027-02-14 without complaint. LocalDate.parse rejects it: Text '2026-13-45' could not be parsed: Invalid value for MonthOfYear (valid values 1 - 12): 13. Convert at the boundary and keep java.time types everywhere else.

6Which should you use?

MethodGives youTime zoneBest for
LocalDateTime.now()Date and timeNone (read in the JVM default)Showing the local time, simple timestamps
LocalDate.now()Date onlyNone (read in the JVM default)Today, due dates, birthdays
ZonedDateTime.now(zone)Date, time and zoneAny IANA zone, DST-awareThe time in a specific place
Instant.now()A momentUTCStoring, logging, comparing across machines
System.currentTimeMillis()long millisecondsUTC epochCheap timestamps, APIs that want a long
new Date()Mutable legacy objectNone (toString uses the default)Only old APIs; convert at the edge

Frequently asked questions

Why does LocalDateTime.now() show the wrong hour?

It shows the wall-clock time in the JVM's default time zone, which is the machine's zone unless you set -Duser.timezone. Servers usually run in UTC, and the sandbox on this page runs in GMT, so now() there is UTC time rather than yours. Ask for a zone explicitly with ZonedDateTime.now(ZoneId.of("America/New_York")), or use Instant.now() and convert to the user's zone only when you display it.

What is the difference between yyyy and YYYY in a Java date pattern?

yyyy is the calendar year. YYYY is the week-based year, which differs for a few days around New Year: with Locale.US, 28 December 2026 formats as 2026 with yyyy but 2027 with YYYY, because that day is in week 1 of 2027. The week rules come from the locale, so with Locale.UK the same date stays in week 53 of 2026. Use yyyy (or uuuu) unless you are also printing week numbers with ww.

How do I get the current time in milliseconds in Java?

System.currentTimeMillis() returns a long count of milliseconds since 1970-01-01T00:00:00Z, and Instant.now().toEpochMilli() is the same number from java.time. To go back, Instant.ofEpochMilli(1790345109123L) gives 2026-09-25T14:05:09.123Z. To measure elapsed time, use System.nanoTime() instead, because the wall clock can be adjusted while your code runs.

How do I convert LocalDateTime to java.util.Date and back?

A Date is an instant and a LocalDateTime has no zone, so you pick one each way: Date.from(local.atZone(ZoneId.systemDefault()).toInstant()), and LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()). For JDBC, java.sql.Timestamp.valueOf(local) and timestamp.toLocalDateTime() convert directly: 2026-09-25T14:05:09.123 becomes the Timestamp 2026-09-25 14:05:09.123 and back. JDBC 4.2 drivers also accept LocalDateTime itself through setObject.

How do I get the current date and time in UTC?

Instant.now() is always UTC and prints with a trailing Z, like 2026-09-25T14:05:09.123Z. If you need date and time fields as well, use OffsetDateTime.now(ZoneOffset.UTC) or ZonedDateTime.now(ZoneOffset.UTC). Avoid LocalDateTime.now() for this: it only looks like UTC when the machine happens to be set to UTC.

Is SimpleDateFormat thread-safe?

No. A SimpleDateFormat keeps its working state in fields, so sharing one instance between threads (for example in a static field) can produce wrong dates or exceptions under load. It is also lenient by default and parses 2026-13-45 as 2027-02-14. DateTimeFormatter is immutable and thread-safe, so a single static final instance can be shared freely, and it rejects invalid dates with a DateTimeParseException.

Run it yourself

Open any of these in the full Java editor to tweak, run and share.

Java playground