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?
- Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6 and Java SE 7
- Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- Later versions of Android bundle implementations of the java.time classes.
- For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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; }