Nezar1990
Nezar1990

Reputation: 43

Time.valueOf method returning wrong value

I used the method Time.valueOf to convert the String "09:00:00" into Time object as follows: Time.valueOf (LocalTime.parse("09:00:00")).

When I call getTime () to display the value I get: 28800000 ms instead of 32400000‬‬ ms (calculated from calculator).

Did I make an error when I used Time.value Of ? Because I don't understand why I get the wrong value.

Thanks.

Upvotes: 3

Views: 1197

Answers (2)

Anonymous
Anonymous

Reputation: 86276

Stick to java.time.LocalTime

I recommend you stick to LocalTime from java.time, the modern Java date and time API, and don’t use java.sql.Time. The latter class is poorly designed, a true hack, indeed, on top of the already poorly designed java.util.Date class. Fortunately it’s also long outdated. There was a time when we needed a Time object for storing a time of day into a database column of datatype time or transferring a time to an SQL query using that datatype. Since JDBC 4.2 this is no longer the case. Now your JDBC driver accepts a LocalTime object and passes its time value on to the database.

So if you’ve got a string, parse it into a LocalTime object the way you already did:

    LocalTime time = LocalTime.parse("09:00:00");

If you don’t need to go through a string, you may obtain the same result using the of factory method, for example:

    LocalTime time = LocalTime.of(9, 0);

I don’t know why you should want to convert it to milliseconds, but you can:

    int milliOfDay = time.get(ChronoField.MILLI_OF_DAY);
    System.out.println(milliOfDay);

Output is:

32400000

This is the value you said you expected.

To insert the LocalTime into your database:

    PreparedStatement ps = yourDatabaseConnection.prepareStatement(
            "insert into your_table(your_time_col) values (?)");
    ps.setObject(1, time);
    int rowsInserted = ps.executeUpdate();

Note the use of setObject(), not setTime().

If you do need a Time object for some legacy API that you don’t want to upgrade just now, the conversion you made is correct.

Your expectations were wrong, your conversion was correct

Did I make an error when I used Time.value Of ? Because I don't understand why I get the wrong value.

No, the other way around. You made no error. And in this case you got the correct value. It’s the poor and confusing design of Time playing a trick on you (I said you shouldn’t want to use that class). I am not sure it’s documented, but Time.valueOf (LocalTime.parse("09:00:00")) gives you a Time object that internally holds a point in time of Jan 1, 1970 09:00 in the time zone of your JVM. From the millisecond value you got, 28 800 000, it seems that this time is equal to 08:00 UTC. Was your time zone at UTC offset +01:00 in the winter of 1970? The getTime() method returns the number of milliseconds since Jan 1, 1970 00:00 UTC.

Upvotes: 2

Oleg
Oleg

Reputation: 6314

That's caused by time zone issues. If you do

TimeZone.setDefault(TimeZone.getTimeZone("UTC"));

Before your code you will get 32400000‬‬ as you expect.

Time.valueOf (LocalTime.parse("09:00:00")) assumes the nine is at your local time zone so it converts it to UTC.

For example if the time zone is "Asia/Jerusalem" (you can simulate it with TimeZone.setDefault(TimeZone.getTimeZone("Asia/Jerusalem")); which was UTC+2 at 1 January 1970 it will convert 9 o'clock to 7 o'clock. You can see it with System.out.println(time.toGMTString());

As always in questions about the old java time api I have to give you an obligatory recommendation to always use only the modern post java8 api.

Upvotes: 3

Related Questions