2

I let's say I have the following time period:

long start = java.sql.Timestamp.valueOf("2021-01-01 00:00:00").getTime();
long end = java.sql.Timestamp.valueOf("2021-02-01 00:00:00").getTime();

I want to loop through this time period and do something for each hh:00, which means:

"2021-01-01 00:00:00"
"2021-01-01 01:00:00"
"2021-01-01 02:00:00"
"2021-01-01 03:00:00"
"2021-01-01 04:00:00"
etc.
TheStranger
  • 1,387
  • 1
  • 13
  • 35
  • I recommend you don’t use `java.sql.Timestamp`. That class is poorly designed and long outdated. Instead use `ZonedDateTime` or another class from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Aug 10 '21 at 16:43

3 Answers3

3

java.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*.

A sample solution using java.time, the modern Date-Time API:

Parse the start and end Date-Time strings into LocalDateTime and iterate from the start to end checking the loop termination condition using LocalDateTime#isAfter as shown below:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String strStartDateTime = "2021-01-01 00:00:00";
        String strEndDateTime = "2021-01-01 10:00:00";

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);

        LocalDateTime ldtStart = LocalDateTime.parse(strStartDateTime, dtf);
        LocalDateTime ldtEnd = LocalDateTime.parse(strEndDateTime, dtf);

        for (LocalDateTime ldt = ldtStart; !ldt.isAfter(ldtEnd); ldt = ldt.plusHours(1)) {
            // System.out.println(ldt);

            // Formatted
            System.out.println(ldt.format(dtf));

            // ...Your logic
        }
    }
}

Output:

2021-01-01 00:00:00
2021-01-01 01:00:00
2021-01-01 02:00:00
2021-01-01 03:00:00
2021-01-01 04:00:00
2021-01-01 05:00:00
2021-01-01 06:00:00
2021-01-01 07:00:00
2021-01-01 08:00:00
2021-01-01 09:00:00
2021-01-01 10:00:00

ONLINE DEMO

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


* For any 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.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
0

Use a ScheduledExecutorService:

private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); scheduler.scheduleAtFixedRate(yourRunnable, 0, 1, TimeUnit.HOURS);

Vladislav
  • 21
  • 3
0

In modern SDKs (java 8 and above) java.sql.Timestamp should be used only in the database layer. All other layers, should use modern java.time.Instant.

Here's one way to do it:

public static void main(String[] args) {
    Duration d = Duration.of(1, ChronoUnit.HOURS);

    Instant now = Instant.now();
    Instant lastFourHours = now.minus(4, ChronoUnit.HOURS);

    while (lastFourHours.isBefore(now)) {
        // do something each hour

        lastFourHours = lastFourHours.plus(d);
    }
}

PS: Instant is what it says it is...an instant. That means it has no timezone information. This also means it deals in UTC.

Boss Man
  • 587
  • 2
  • 12