1

I am storing some days and hours as timestamp in my MySQL table. What I want to do now is retrieve every day that a specific user worked from last Sunday until the Sunday before (One week of work). And the other option is retrieve every day from today until last Sunday (current week). Some employees does not work everyday.

I don't know how I can code this in Java or whether there is a specific MySQL function.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Camus
  • 827
  • 2
  • 20
  • 36

2 Answers2

3

in Java, you can put the Calendar class to good use to find the previous Sunday :

Calendar c = Calendar;
c.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
Date lastSunday = c.getTime();

you can then decrement by 1 WEEK_OF_MONTH to find the Sunday before that :

c.add(Calendar.WEEK_OF_MONTH, -1);
Date sundayBeforeThat = c.getTime();

Simon Baslé
  • 27,105
  • 5
  • 69
  • 70
  • Thanks. So the first 3 lines of the code will retrieve the data of the last Sunday. For example today is 27-04-2012 (Friday). The date in this variable will be 22-04-2012? Thanks again – Camus Apr 26 '12 at 14:19
  • Actually I've tried this code and it works a bit different. The first line should be Calendar c = Calendar.getInstance; The second line returns the next day not the before. But I appreciate the help. Now I can work around it and find a suitable solution to my problem. – Camus Apr 29 '12 at 02:27
  • oh yes I forgot the ".getInstance()", my bad :/ as for the returning of the next day, there could be an internal implementation subtility that goes to the next sunday or the previous one depending on current day of the week... so take this part of the code with a grain of salt – Simon Baslé May 03 '12 at 08:50
  • This Answer ignores the crucial issue of time zones. `Calendar` is implicitly using the JVM’s current default time zone. That means your results will vary; not good. – Basil Bourque Jul 10 '17 at 01:38
0

tl;dr

LocalDate.now( ZoneId.of( "Pacific/Auckland" ) )
         .with( TemporalAdjusters.previous( DayOfWeek.SUNDAY ) ) 

java.time

The modern approach uses the java.time classes.

Remember that the TIMESTAMP data type in MySQL is in UTC time zone.

In contrast, you want particular dates for particular day-of-week value where a particular time zone is critical. 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.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );

Let's get the last Sunday, excluding today if it were a Sunday. Use a TemporalAdjuster implementation found in the TemporalAdjusters (note plural) class. Specify a DayOfWeek enum object.

LocalDate previousSunday = today.with( TemporalAdjusters.previous( DayOfWeek.SUNDAY ) ) ;

Get the Sunday further back.

LocalDate startingSunday = previousSunday.minusWeeks( 1 ) ;

We need exact moment, not entire date. Get the first moment of the day. Do not assume that means the time-of-day of 00:00:00. Anomalies such as Daylight Saving Time (DST) means that the day might begin at a time like 01:00:00. Let java.time figure that out.

ZonedDateTime zdtStart = startingSunday.atStartOfDay( z ) ;

Next we need the ending time. Actually, not the ending time. Determining the split second ending of the week is tricky. The common practice in date-time work is to use the Half-Open approach to defining a span of time. In Half-Open, the beginning is inclusive while the ending is exclusive. That means we want to start at the first moment of one Sunday and run up to, but not include, the first moment of the following Sunday.

Note that you cannot use BETWEEN in SQL for Half-Open, as that command is Closed, meaning both beginning and ending are inclusive.

ZonedDateTime zdtStop = previousSunday.atStartOfDay( z ) ;

The query in MySQL will be done in UTC. So let's extract Instant objects from the ZonedDateTime objects as they are always in UTC by definition.

Instant start = zdtStart.toInstant() ;
Instant stop = zdtStop.toInstant() ;

If your JDBC driver supports JDBC 4.2 and later, you can directly use these Instant objects in your query via PreparedStatement::setObject and ResultSet::getObject.

This SQL code is untested, but should point you in the right direction.

String sql = "SELECT * from tbl_ WHERE col_ >= ? AND col_ < ? ; " ;
PreparedStatement pstmt = conn.prepareStatement( sql ) ;
pstmt.setObject( 1 , start ) ;
pstmt.setObject( 2 , stop ) ; 
ResultSet rs = pstmt.executeQuery() ;
…
    Instant instant = rs.getObject( … , Instant.class ) ;

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.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154