1

There are two options that I can think of:

Option 1:

public class TimestampFormatter {

    private static SimpleDateFormat dateFormatter = 
            new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");

    private static Date date = new Date();

    public static String get() {
        date.setTime(System.currentTimeMillis());
        return dateFormatter.format(date);
    }
}

Option 2:

public class TimestampFormatter {

    private static SimpleDateFormat dateFormatter = 
            new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");

    public static String get() {
        return dateFormatter.format(new Date());
    }
}

And then using this loop to print the formatted date+time every second:

new Thread(() -> {
            while (true) {
                System.out.println(TimestampFormatter.get());
                Sleep.millis(1000);
            }
        }).start();

I think the first option is the best of the two here, but can anyone think of a better way?

Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
Asaf Levy
  • 191
  • 1
  • 7
  • 3
    I recommend you don’t use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead use for example `LocalDateTime` and `DateTimeFormatter`, both from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Dec 08 '19 at 08:47
  • 2
    You don’t need to worry. Formatting the current time doesn’t take prohibitively long. Use the code that you find the most readable. (And if you should insist, no one here knows the answer in your setup. You would have to make your own measurements.) – Ole V.V. Dec 08 '19 at 08:50

1 Answers1

4

The second option may be more efficient than the first (or perhaps the first is infinitesimally better - I doubt you can measure any difference). Regardless I would prefer the newer java.time.format.DateTimeFormatter and java.time.LocalDateTime over the long deprecated SimpleDateFormat and Date classes. Also, it would be more efficient to schedule a repeating Timer instead of using a while loop and repeating sleep calls. Something like,

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
TimerTask task = new TimerTask() {
    public void run() {
        System.out.println(dtf.format(LocalDateTime.now()));
    }
};
Timer timer = new Timer("Timer");
timer.scheduleAtFixedRate(task, TimeUnit.SECONDS.toMillis(0), 
        TimeUnit.SECONDS.toMillis(1));
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • why second option is probably more efficient then the first? it creates a new `Date()` in each iteration – Sharon Ben Asher Dec 08 '19 at 07:59
  • @SharonBenAsher Creating a single short lived `Date` that's eligible for immediate garbage collection is probably better than creating a long lived `Date` that isn't. But neither approach (with `sleep`) is particularly efficient. – Elliott Frisch Dec 08 '19 at 08:00
  • 1
    I fail to see why the lifespan of the object makes a difference. Creating an object requires allocation in heap, setting its state, etc. to me eyes, this seems more expensive (at least in performance terms) to method calling – Sharon Ben Asher Dec 08 '19 at 08:03
  • 1
    @SharonBenAsher [Young vs Tenured](https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/generations.html) in generational garbage collection. But the difference may not even be measurable, because a `Date` (or `LocalDateTime`) is a tiny object. – Elliott Frisch Dec 08 '19 at 08:06
  • I am aware of generational collection. The linked article explains the concept but otherwise does not mention any benefit for making repeated short lived objects over having one long lived one. – Sharon Ben Asher Dec 08 '19 at 08:12
  • 1
    @SharonBenAsher Regardless; would you agree the solution I am actually advocating is better than either proposed in the question? I think the relevant part of the question is *can anyone think of a better way*. – Elliott Frisch Dec 08 '19 at 08:22
  • @SharonBenAsher Edited to (hopefully) remove controversy. – Elliott Frisch Dec 08 '19 at 08:29
  • thanks. I do believe the latest version of the text is more clear, so future readers will not have doubts and questions as I have. cheers. – Sharon Ben Asher Dec 08 '19 at 08:32
  • @SharonBenAsher: there are several misconceptions here. First, the question only focuses on a single visible object, not being aware of all the other temporary objects created in the background, which makes looking at the single object pointless. Further, not only creating an object requires setting its state, the shared object must be updated too. And since it’s fetched from a `static` variable, it hinders several JVM side optimizations; I just verified that those truly make the temporary `Date` more efficient. [Regarding temporary objects costs…](https://stackoverflow.com/a/54619104/2711488) – Holger Dec 10 '19 at 12:10