0

Please tell me how to set the date (current date minus one day) and time equal to 19:00:00 using such a construction?

new java.sql.Timestamp(java.util.Calendar.getInstance.getTime().getTime())

LocalDateTime don't use.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
Alex
  • 25
  • 1
  • 8
  • 3
    _LocalDateTime don't use_ Do you mean that you can't use the [date-time API](https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html)? – Abra Dec 25 '20 at 10:59
  • 1
    I recommend you don’t use `java.sql.Timestamp` and `Calendar`. Those classes are poorly designed and long outdated. If your SQL datatype is `timestamp with time zone` (recommended for the majority of purposes), use `OffsetDateTime` from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). If it is `timestamp` (without time zone) or `datetime`, do use `LocalDateTime` from the same API. Why not? – Ole V.V. Dec 25 '20 at 14:08
  • 1
    Or to put it the other way around: Like you said, don’t use `LocalDateTime` for a timestamp. Use `OffsetDateTime` or `Instant`. – Ole V.V. Dec 26 '20 at 07:15

2 Answers2

2

I recommend you do it using the java.time (the modern date-time API).

Solution, purely using the modern API:

import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        OffsetDateTime odt = ZonedDateTime.now(ZoneId.systemDefault())
                                .minusDays(1)
                                .with(LocalTime.of(19, 0))
                                .toOffsetDateTime();

        System.out.println(odt);
    }
}

Output:

2020-12-24T19:00Z

You can use the OffsetDateTime in your JDBC code as follows:

PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, odt);
st.executeUpdate();
st.close();

However, if you still want to use java.sql.Timestamp, you can use ZonedDateTime with the applicable timezone to get the required date-time and then convert it into Instant from which you can get Epoch milliseconds. You can Finally use the Epoch milliseconds to construct an instance of java.sql.Timestamp.

import java.sql.Timestamp;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        ZonedDateTime zdt = ZonedDateTime.now(ZoneId.systemDefault())
                            .minusDays(1)
                            .with(LocalTime.of(19, 0));
        
        Timestamp timestamp = new Timestamp(zdt.toInstant().toEpochMilli());
        System.out.println(timestamp);
    }
}

Output:

2020-12-24 19:00:00.0

Notes:

  1. I have used ZoneId.systemDefault() which uses the JVM's timezone. Change it to applicable timezone e.g. ZoneId.of("Europe/London").
  2. Instant belongs to the modern date-time API. Learn about the modern date-time API from Trail: Date Time.
  3. For whatsoever reason if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Solution, purely using the legacy API:

import java.sql.Timestamp;
import java.util.Calendar;

public class Main {
    public static void main(String[] args) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_YEAR, -1);
        calendar.set(Calendar.HOUR_OF_DAY, 19);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        Timestamp timestamp = new Timestamp(calendar.getTimeInMillis());
        System.out.println(timestamp);
    }
}

Output:

2020-12-24 19:00:00.0
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • — And while this answer is helpful in the best of ways by showing a better alternative to the `Timestamp` class, it *also* does answer the question as asked: how to set a `java.sql.Timestamp` to yesterday at 19. – Ole V.V. Dec 26 '20 at 07:00
  • Thanks, @OleV.V. for approving the answer. It's the positive feedback on the correct usage of the modern date-time API and helpful comments, from the date-time champions like [Basil Bourque](https://stackoverflow.com/users/642706/basil-bourque) and you, that has encouraged many, like me, to learn and explore deeper the modern date-time API. – Arvind Kumar Avinash Dec 26 '20 at 10:39
  • Actually, I do see a problem with this Answer. The first solution should replace `OffsetDateTime.now` with `ZonedDateTime.now`. Then later in the code convert to an `OffsetDateTime` for use with JDBC 4.2. The current code fails on any days where the politicians in that region are changing the offset of their time zone, such as cut-over for Daylight Saving Time (DST) or a [diplomatic move between North Korea – South Korea](https://www.bbc.com/news/world-asia-44010705). – Basil Bourque Dec 26 '20 at 18:14
  • 1
    @BasilBourque - Thank you. I have replaced `OffsetDateTime.now` with `ZonedDateTime.now`. – Arvind Kumar Avinash Dec 26 '20 at 18:24
0

This is my code

Set date to yesterday with Calendar.add(Calendar.DAY_OF_YEAR, -1)

Compare hour with Calendar.get(Calendar.HOUR_OF_DAY)

getHour of java.sql.Timestamp is Deprecated.

replaced by Calendar.get(Calendar.HOUR_OF_DAY).

import java.sql.Timestamp;
import java.util.Calendar;

Calendar calendar = Calendar.getInstance(); // 2020-12-25 19:42:57.739
calendar.add(Calendar.DAY_OF_YEAR, -1);
Timestamp timestamp = new Timestamp(calendar.getTimeInMillis());

System.out.println(timestamp); // 2020-12-24 19:42:57.739
System.out.println(19 == calendar.get(Calendar.HOUR_OF_DAY)); // true

Bye!

botem
  • 348
  • 1
  • 11
  • 2
    These are terrible legacy classes. See modern *java.time* solution in [answer by Live and Let Live](https://stackoverflow.com/a/65447424/642706). – Basil Bourque Dec 26 '20 at 18:07