LocalTime from Date
Asked Answered
N

5

20

I'm trying to convert a Date instance to a LocalTime instance.

// Create the Date
Date date = format.parse("2011-02-18 05:00:00.0");    

// Convert to Calendar
Calendar cal = Calendar.getInstance();
cal.setTime(date);

// Convert Calendar to LocalTime
Instant instant = Instant.ofEpochMilli(cal.getTimeInMillis());
LocalTime convert = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()).toLocalTime();

I don't get a compiler error but the LocalTime instance values are wrong.

I think it does not work because Date stores time in fasttime instead of cdate.

I'm using JDK version 1.8.

Nachison answered 28/4, 2015 at 18:40 Comment(2)
First is first, what version of Java are we talking about?Biforate
@RafaelR.S.Robles JDK 1.8Nachison
S
12

Your input is effectively a LocalDateTime. It would be much simpler to simply parse that to a LocalDateTime and then get the LocalTime from that. No time zones to worry about, no somewhat-legacy classes (avoid Date and Calendar where possible...)

import java.time.*;
import java.time.format.*;
import java.util.*;

public class Test {

    public static void main(String[] args) {
        DateTimeFormatter formatter =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S", Locale.US);

        String text = "2011-02-18 05:00:00.0";
        LocalDateTime localDateTime = LocalDateTime.parse(text, formatter);
        LocalTime localTime = localDateTime.toLocalTime();
        System.out.println(localTime);
    }
}
Schock answered 28/4, 2015 at 18:49 Comment(1)
Accepted answer is correct but I had to still muck with it to get what I want. To get LocalDateTime formatted to whatever you want: LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S"))Statis
B
24

This is also quite simple:

LocalTime time = LocalDateTime.ofInstant(new Date().toInstant(),
    ZoneId.systemDefault()).toLocalTime();
Bark answered 5/10, 2016 at 9:14 Comment(3)
can be simplified with LocalTime.ofInstant()Vaporetto
very bad anwser, create a localdatetime then convert to localtime? why not just create a localtimeOcker
@RafaelLima - Here is a demo of exactly what you have mentioned.Homiletic
S
12

Your input is effectively a LocalDateTime. It would be much simpler to simply parse that to a LocalDateTime and then get the LocalTime from that. No time zones to worry about, no somewhat-legacy classes (avoid Date and Calendar where possible...)

import java.time.*;
import java.time.format.*;
import java.util.*;

public class Test {

    public static void main(String[] args) {
        DateTimeFormatter formatter =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S", Locale.US);

        String text = "2011-02-18 05:00:00.0";
        LocalDateTime localDateTime = LocalDateTime.parse(text, formatter);
        LocalTime localTime = localDateTime.toLocalTime();
        System.out.println(localTime);
    }
}
Schock answered 28/4, 2015 at 18:49 Comment(1)
Accepted answer is correct but I had to still muck with it to get what I want. To get LocalDateTime formatted to whatever you want: LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S"))Statis
V
3

The accepted Answer by Jon Skeet is correct. This Answer expands on those ideas.

Avoid legacy date-time classes

Some of the other Answers, and the Question, mix the old legacy date-time classes with the new. That is unnecessary and bad practice. The whole point of the java.time classes is to replace the troublesome and confusing old classes.

  • You do not need java.util.Date.
  • You do not need java.util.Calendar.

LocalDateTime

Your input string lacks any information about offset-from-UTC or time zone. So we parse it as a LocalDateTime object.

To parse, we replace the SPACE in the middle with a T to comply with the ISO 8601 standard for date-time formats.

String input = "2011-02-18 05:00:00.0".replace( " " , "T" );
LocalDateTime ldt = LocalDateTime.parse( input );

LocalTime

To focus on the time-of-day without the date, ask for a LocalTime.

LocalTime lt = ldt.toLocalTime();

ZonedDateTime

Note that none of this are actual moments, not a point on the timeline. Without the context of an offset-from-UTC or a time zone, we do not know if you meant 5 AM in Auckland NZ or 5 AM in Kolkata IN or 5 AM in Paris France or 5 AM in Montréal Québec. Each of those would be very different moments in time.

If by context you do know for certain the intended time zone, apply it. Apply a ZoneId to get a ZonedDateTime.

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ldt.atZone( z );

From there, ask for the LocalTime if desired.

LocalTime lt = zdt.toLocalTime(); 

Instant

If you want to see that same moment in UTC, extract an Instant. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

Generally best to focus on UTC in much of your business logic, logging, data storage, and data exchange. Learn to think of UTC as “The One True Time”.

Instant instant = zdt.toInstant();  // Same moment, shifted to UTC.
Valley answered 5/10, 2016 at 22:47 Comment(0)
T
0

Try this

    String datestring = "2011-02-18 05:00:00.0";
    SimpleDateFormat dt = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");//take a look at MM
    Date date = dt.parse(datestring );
    Instant instant = Instant.ofEpochMilli(date.getTime());
    LocalTime res = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()).toLocalTime();
Tattan answered 28/4, 2015 at 18:50 Comment(2)
Silly to mix the troublesome old classes with the java.time classes. The old classes are now supplanted by java.time classes. No need for old ones.Valley
If you have to use the old classes with the new then what do you do? Refactor whatever codebase you have to suit the new classes? That makes no sense. Sometimes there's a need to keep using the old style together with the new, and this applies to any development work, not just Java.Braise
H
0

You can parse your date-time string into a LocalTime directly

Solution using java.time, the modern Date-Time API*:

Having formatted the given date-time string into ISO 8601 format, you can parse it to LocalTime directly using DateTimeFormatter.ISO_LOCAL_DATE_TIME.

Alternatively, you can use the pattern u-M-d H:m:s.S with DateTimeFormatter to parse the given date-time string directly into LocalTime.

Demo:

public class Main {
    public static void main(String[] args) {
        LocalTime time = LocalTime.parse("2011-02-18 05:00:00.0".replace(' ', 'T'), DateTimeFormatter.ISO_LOCAL_DATE_TIME);
        System.out.println(time);

        // Alternatively,
        time = LocalTime.parse("2011-02-18 05:00:00.0", DateTimeFormatter.ofPattern("u-M-d H:m:s.S", Locale.ENGLISH));
        System.out.println(time);
    }
}

Output:

05:00
05:00

ONLINE DEMO

Learn more about the modern Date-Time API from Trail: Date Time.


* The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API.

Homiletic answered 18/7, 2023 at 14:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.