Dan
Dan

Reputation: 2098

Java - Producing a timestamp for every minute of every hour for 24 hours

I am writing a program to produce a timestamp for every minute of every hour for a whole day. I am using the Calendar class to get the timestamp, I have to use it so no point in suggesting other methods.

My idea to produce the file was to have a for loop for 24 hours and a nested for loop of 60 minutes in which the timestamp would be printed to the .dat file. I thought this would work and would print the data for the whole day and then stop.

However I was wrong, totally wrong!

The result is data being printed for every minute upto a date 2 years from now.

Here is my code so far;

public static void main (String [] args) throws FileNotFoundException
{ 
    try
    {
        DateFormat df = new SimpleDateFormat("dd-MM-yyyy");
        Date date = new Date();
        File fileName = new File(df.format(date) + ".dat");
        RandomAccessFile raf = new RandomAccessFile(fileName, "rw");

        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
        cal.add(Calendar.MILLISECOND, -cal.get(Calendar.MILLISECOND));
        cal.add(Calendar.SECOND, -cal.get(Calendar.SECOND));
        cal.add(Calendar.MINUTE, -cal.get(Calendar.MINUTE));
        cal.add(Calendar.HOUR_OF_DAY, -cal.get(Calendar.HOUR_OF_DAY));

        for(int hourInMinutes = 0; hourInMinutes < 1440; hourInMinutes++) //1440 is the total minutes in a day
        {   
            for(int minute = 0; minute <= hourInMinutes; minute++)
            {   
                    raf.writeLong(cal.getTimeInMillis());       //Timestamp
                    cal.add(Calendar.MINUTE, 1);
            }
        }
        raf.close();
    }
    catch(IOException iOE)
    {
        System.err.println(iOE);
    }
}

The data starts at midnight (last night) and I want it to stop producing data at 11.59pm on the same day.

Anyone have any knowledge on how this is done?

Upvotes: 1

Views: 3742

Answers (5)

Basil Bourque
Basil Bourque

Reputation: 338876

java.time

You are using old outmoded classes, now supplanted by java.time classes.

Time zone is crucial to determining a date and therefore the hours of that day. For any given moment the date varies around the globe by zone. Specify a ZoneId object.

ZoneId zoneId = ZoneId.of ( "America/Montreal" );

ZonedDateTime

Use that time zone to get the current moment in a ZonedDateTime object.

ZonedDateTime now = ZonedDateTime.now ( zoneId );

Get the date-only value (LocalDate) for use in naming the file.

String filename = now.toLocalDate().toString();

To get the first moment of the day, let java.time determine the value. The day does not always start at 00:00:00 in some time zones because of Daylight Saving Time (DST) or other anomalies. To get first moment, we go through the LocalDate class briefly.

ZonedDateTime start = now.toLocalDate ().atStartOfDay ( zoneId );

For there we loop every hour until reaching the next day. Secondarily loop each minute of the hour until reaching the next hour. We soft-code the loops to test going past the limits rather than hard-code a number of hours or a number of minutes. Anomalies such as Daylight Saving Time (DST) can shift the clock by hours or by minutes. For example, a 30-minute change in Venezuela in 2007.

ZonedDateTime nextDay = start.plusDays ( 1 );
ZonedDateTime zdt = start;
while ( zdt.isBefore ( nextDay ) ) {
    ZonedDateTime zdtMinute = zdt;
    ZonedDateTime zdtNextHour = zdtMinute.plusHours ( 1 );
    while ( zdtMinute.isBefore ( zdtNextHour ) ) {
        System.out.println ( zdtMinute.toString () );
        // Prepare for next loop.
        zdtMinute = zdtMinute.plusMinutes ( 1 );
    }
    // Prepare for next loop.
    zdt = zdt.plusHours ( 1 );
}

When run.

2016-08-12T00:00-04:00[America/Montreal]

2016-08-12T00:01-04:00[America/Montreal]

2016-08-12T00:02-04:00[America/Montreal]

2016-08-12T00:03-04:00[America/Montreal]

2016-08-12T23:58-04:00[America/Montreal]

2016-08-12T23:59-04:00[America/Montreal]

Instant

If you want generic 24-hour days and 60-minute hours, instead of ZonedDateTime, use the Instant class as it is always in UTC by definition.

Upvotes: 0

kark
kark

Reputation: 4853

I prefer quartz-scheduler will be the best one to schedule a task for hour convenience

Upvotes: 0

aga
aga

Reputation: 29426

Your for loop looks wrong, here is the updated version:

 for(int hourInDay = 0; hourInDay < 24; hourInDay++) 
    {   
        for(int minute = 0; minute <= 59; minute++)
        {   
            raf.writeLong(cal.getTimeInMillis());
            cal.add(Calendar.MINUTE, 1);                    
        }
    }

Or you can get rid of an inner for loop (which has totally wrong second condition) and use the following version:

    for(int minutesInDay = 0; minutesInDay < 1440; minutesInDay++) //1440 is the total minutes in a day
    {   
        raf.writeLong(cal.getTimeInMillis());     
        cal.add(Calendar.MINUTE, 1);
    }

And try to give distinct names to your variables. hourInMinutes sounds for me like "the number of hours in one minute". Obviously, it's not what this variable stands for.

Upvotes: 5

user987339
user987339

Reputation: 10707

You should throw out your inner loop:

for(int hourInMinutes = 0; hourInMinutes < 1440; hourInMinutes++) //1440 is the total minutes in a day
{   
            raf.writeLong(cal.getTimeInMillis());       //Timestamp
            cal.add(Calendar.MINUTE, 1);
}

Upvotes: 2

Julien
Julien

Reputation: 2584

As you already loop every minute in a day, you shouldn't have a inner loop, that's all.

Upvotes: 0

Related Questions