Get timestamp for start of day

I am storing times/dates in a database using a unix timestamp. I want to then get all the instances on certain day so I therefore need to calculate the timestamp for the start of the day in order to query the database.

I have done a similar thing in php by passing mktime the values for the day/month/year from a date object and setting hour and minute to zero. There doesn't seem to be similar functions for this in java/android (the functions for getting the specific parts of date are deprecated)

Can anyone give some guidance on this? Thanks

Edit:

Ok so I realised this might work:

public static int startOfDay(Timestamp time) {
        Calendar cal = dateToCalendar(new Date(time.getTime()));
        cal.add(Calendar.HOUR_OF_DAY, -Calendar.HOUR_OF_DAY);
        cal.add(Calendar.MINUTE, -Calendar.MINUTE);
        cal.add(Calendar.SECOND, -Calendar.SECOND);
        Log.i("Time", cal.getTime().toString());        
        return (int) cal.getTimeInMillis()/1000;
}

However when I ran this just now I got:

Sat Dec 15 01:24:00 GMT 2012

The seconds are right but the hour and minute are wrong??

Answers


tl;dr

ZoneId z = ZoneId.of( "America/Montreal" );
long secondsSinceEpoch = ZonedDateTime.now( z ).toLocalDate().asStartOfDay( z ).toEpochSecond() ;

Details

The accepted Answer by Tomik is correct but outdated. The troublesome old legacy date-time classes have been supplanted by the java.time classes.

As that Answer advised, you must consider time zone when getting the start of a day. A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.now( z );

Getting the first moment of the day requires going through LocalDate. The LocalDate class represents a date-only value without time-of-day and without time zone.

LocalDate today = zdt.toLocalDate();
ZonedDateTime zdtTodayStart = today.atStartOfDay( z );

Note that we let java.time determine the start of day rather than assuming and hard-coding 00:00:00. Because of Daylight Saving Time (DST) and other anomalies, the day may start at another time such as 01:00:00.

Apparently, by unix timestamp you mean a count of whole seconds since the first moment of 1970 in UTC. The ZonedDateTime class has a method to give you that number. Note this may mean data loss as the ZonedDateTime may have a fraction of a second with resolution of nanoseconds.

long secondsSinceEpoch = zdtTodayStart.toEpochSecond();

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?


When dealing with time, you should always consider time zones. You database timestamps should be always stored in one time zone (e.g. UTC). Your computation should then consider that users can be in different time zones and that they can change time zones.

If you want to compute start of the day in the time zone the user has currently set in his phone. Create the Calendar instance with:

Calendar cal = Calendar.getInstance(); 

To get the instance for a specific time zone use:

// use UTC time zone
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));

Then set the beginning of the day:

cal.setTime(time); // compute start of the day for the timestamp
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);

public static int startOfDay(Timestamp time) {
    Calendar cal = Calendar.getInstance();
    cal.setTimeInMillis(time.getTime());
    cal.set(Calendar.HOUR_OF_DAY, 0); //set hours to zero
    cal.set(Calendar.MINUTE, 0); // set minutes to zero
    cal.set(Calendar.SECOND, 0); //set seconds to zero
    Log.i("Time", cal.getTime().toString());        
    return (int) cal.getTimeInMillis()/1000;
}

Need Your Help

How to fix issue when committing a change to CVS

cvs commit conflict

I'm trying to commit my changes to CVS repository, but I get the following error:

How to detect duplicate rows in a SQL Server table?

sql-server rdbms

What is the most efficient way to detect duplicates in a 10 column / 50K row table? I'm using MSSQL 8.0