Question

Count days between two date objects with saturday & sunday excluded

Asked by: gnoon

I'm trying to find the best way, in term of performance, to get a number of days between two dates with saturday & sunday excluded.
Currently, I have one to loop through all days between them to check & count.

Any better idea?

Thanks

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
2008-04-22 at 01:56:30ID23342183
Topic

Java Programming Language

Participating Experts
4
Points
500
Comments
46

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. Find Saturday and Sunday between two dates
    Hello to you all! My question is as follows: I've got two dates DateFrom and DateTo, now i want to find out if there is a saturday between those dates or a sunday, or a saturday and a sunday. Then when there is a compare i want to trigger a Boolean and an integer that holds t...
  2. How to exclude saturday and sunday using sql query
    How to run a five business days report using sql server reporting services. I'm using reporting services tool in which I'm writing a query. I want to know how to write the sql query in which I can get only business days excluding saturday,sunday and holidays. Thanks bm
  3. Calculate Working Days exclude Saturday and Sunday
    Hi, I need to know how many working days have gone through specific dates but do not include Saturday or Sunday, for example for July 2005: A1 Beginning Date A2 Todays Date Answer for cell A3 would be 17 As A1 would be 01/07/2005, A2 would be 25/07/2005 A3 would be 17 as...
  4. count the # of Saturdays and Sundays in the current month
    So far I have this but missing one for this month, it's not accounting for the stray Sunday that's in the first day of this month. Should produce 9, but it produces 8: DECLARE @today datetime, @TotalWeekendDays int -- TOTAL # WEEKEND DAYS THIS MONTH SELECT @To...
  5. Calculating the past 30 days excluding Saturday and Sund…
    HI I have this problem where I have to want to calcuate the past 30 days excluding the Saturdays and Sundays from todays date. Example if I give the currentDate as 02/28/2006 then it should start looking from 01/30/2006 and then exclude Saturday and Sundays and give me back ...

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: CEHJPosted on 2008-04-22 at 01:58:55ID: 21409124

You're probably using the best way. You need to use Calendar to avoid time variation pitfalls

 

by: krakatoaPosted on 2008-04-22 at 02:02:33ID: 21409143

Actually, that doesn't look all that plausible, and it's not Java.

 

by: krakatoaPosted on 2008-04-22 at 02:04:42ID: 21409156

 

by: krakatoaPosted on 2008-04-22 at 02:05:59ID: 21409163

(the Calendar element of which has already been mentioned).

 

by: objectsPosted on 2008-04-22 at 02:21:26ID: 21409218

you can speed your loop up by having your loop jump 7 days at a time (adding 5 to the counter each time)  until there are less than 7 days remaining. then going one day at a time.

Actually you can avoid having a loop altogether by just making 3 calcs
- number of full week + number of days before first full week + number of days after last full week.


 

by: objectsPosted on 2008-04-22 at 02:23:53ID: 21409234

typo:

= 5 * number of full week + number of days before first full week + number of days after last full week.

 

by: gnoonPosted on 2008-04-22 at 03:00:02ID: 21409375

Thanks you all experts for quick response. I much appreciate all of you.

I'm now interested in calculation way than looping since it seems to be faster, but I do not understand in some parts of code in the links and need time to test them for valid/performance. The concept should be as objects described, I think.

I will come back soon with solutions and point split, or some problems. hehe

Regards

 

by: krakatoaPosted on 2008-04-22 at 03:28:16ID: 21409503

Another thought :

Just first subtract the dates from one another to get the total number of days. Divide that by 7 and double the resulting int, to give you the number of weekend days. Then mod your total number of days by 7 (which can only result in 1-6), and make a short loop to test each of these 1-6 days for weekendedness, adding that tally to the 7-int'd calc, remembering that you won't know - or care - whether the mod days are before, or after, your period.

 

by: krakatoaPosted on 2008-04-22 at 03:29:07ID: 21409510

>>(which can only result in 1-6),  <<

if it's not 0 of course.

 

by: krakatoaPosted on 2008-04-22 at 04:37:12ID: 21409860

Ah .. my last wasn't quite right, but I believe this is  :

Subtract the dates to get total days. Mod that by 7, and test each of the last 'mod-result' (1-6) days *back* from the end date for Saturday or Sundayness. Add any that are, to the (int) of the ((end - beg date /7) *2).

 

by: krakatoaPosted on 2008-04-22 at 07:42:15ID: 21411561

Here's the code (using ints 1-7 for days of the week instead of a calendar), based on the above model I described :
.
.

private float start, end, result;
private int daynum=0;
private int[] days;
.
.
.

start = 10;
end = 31;

 days = new int[(int)(end-start)];
 for (int a=0;a<end-start;a++){
      days[a]=++daynum;
      if(daynum==7){daynum=0;}
  }

 result = (end-start)/7;

 result = (int)result*2;

  if ((int)(end-start)%7>0){
           System.out.println("Extra days beyond a full week = "+((int)end-start)%7);
  }

  for(int y=0;y<(int)((end-start)%7);y++){
      if(days[(int)((end-start)-(y+1))]==6||days[(int)((end-start)-(y+1))]==7){
            result+=1;
      }
   }

  System.out.println("The total number of working days between dates is "+((int)(end-start)-(int)result));

.
.
.

 

by: krakatoaPosted on 2008-04-22 at 08:20:49ID: 21411986

>>I'm trying to find the best way, in term of performance ...

above code, but now working on 1,400 years worth of days, (starting a day 10), now with a timer which starts *after* the days' array is up and available.


start = 10;
end = 511000;//about 1,400 years worth of days ;)

 days = new int[(int)(end-start)];
 for (int a=0;a<end-start;a++){
      days[a]=++daynum;
      if(daynum==7){daynum=0;}
  }
long starttime = System.nanoTime();

 result = (end-start)/7;

 result = (int)result*2;

  for(int y=0;y<(int)((end-start)%7);y++){
      if(days[(int)((end-start)-(y+1))]==6||days[(int)((end-start)-(y+1))]==7){
            result+=1;
      }
   }
long endtime = System.nanoTime();

  System.out.println("The total number of working days between dates is "+((int)(end-start)-(int)result));
   if(((endtime-starttime)/1000000)>0) {System.out.println(((endtime-starttime)/1000000)+" milliseconds");}
   else {System.out.println("This calculation took "+(endtime-starttime)+" nanoseconds");}

 

by: gnoonPosted on 2008-04-23 at 00:44:36ID: 21418431

Thanks for your try, krakatoa.

I wrote a class to test in 4 ways using GregorianCalendar with GMT timezone to avoid DST offset problem.
It's attached below.

way1 - my own looping through all days
way2 - using calculation in link of Bart_Cr
way3 - using krakatoa's calculation
way4 - boost up looping as objects's suggest

At the final of R&D, I ended up with the way4 since it seems to be most valid and fairly speed.
One more issue, what I need is counting days not finding the different number. If both the same day, it should result in 1 not 0.

Here is the result of R&D

Start             End             Method  Days        Time(msec)  Result      Note
==================================================
2008/01/04  2008/01/04  way1    1                                                  It's Friday
                                         way2    1                      
                                         way3    0                                  !?
                                         way4    1                      
2008/01/05  2008/01/05  way1    0                                                  It's Saturday
                                         way2    1                                  !?
                                         way3    0                      
                                         way4    0                      
2008/01/06  2008/01/06  way1    0                                                  It's Sunday
                                         way2    0                      
                                         way3    0                      
                                         way4    0                      
2008/01/01  2008/01/31  way1    23                                                Jan 2008
                                         way2    23                      
                                         way3    22                                  !?
                                         way4    23                      
2008/02/01  2008/02/29  way1    21                                                Feb 2008
                                         way2    21                      
                                         way3    20                                  !?
                                         way4    21                      
2000/01/01  4000/01/01  way1    521775      2153                          2,000 years
                                         way2    521776      0                  !?
                                         way3    521775      10
                                         way4    521775      551
2000/01/01  4001/01/01  way1    522297      2153                          2,001 years
                                         way2    522297      0
                                         way3    522298      10                !?
                                         way4    522297      551
2000/01/01  4005/01/01  way1    523080      2163                          2,005 years
                                         way2    523081      0                  !?
                                         way3    523080      10
                                         way4    523080      551

!? = seems to be wrong #days

It would be great if the calculation ways give the right result, but I cann't figure for the right algorithm.

import java.util.*;
 
public class CalendarTest
{
    GregorianCalendar g1, g2;
    GregorianCalendar gc1, gc2;
    boolean debug;
 
    CalendarTest(boolean debug)
    {
        this.debug = debug;
        g1 = new GregorianCalendar(TimeZone.getTimeZone("GMT"), Locale.US);
        g2 = new GregorianCalendar(TimeZone.getTimeZone("GMT"), Locale.US);
    }
 
    void reset()
    {
        if (g2.after(g1))
        {
            gc2 = (GregorianCalendar) g2.clone();
            gc1 = (GregorianCalendar) g1.clone();
        }
        else
        {
            gc2 = (GregorianCalendar) g1.clone();
            gc1 = (GregorianCalendar) g2.clone();
        }
        gc1.clear(Calendar.MILLISECOND);
        gc1.clear(Calendar.SECOND);
        gc1.clear(Calendar.MINUTE);
        gc1.clear(Calendar.HOUR_OF_DAY);
        gc2.clear(Calendar.MILLISECOND);
        gc2.clear(Calendar.SECOND);
        gc2.clear(Calendar.MINUTE);
        gc2.clear(Calendar.HOUR_OF_DAY);
    }
 
    void set1(int y, int m, int d)
    {
        g1.set(y, m, d);
    }
 
    void set2(int y, int m, int d)
    {
        g2.set(y, m, d);
    }
 
    int way1() // mine
    {
        reset();
        long startTime = System.currentTimeMillis();
 
        int day = gc1.get(Calendar.DAY_OF_WEEK);
        long days = 0;
 
        while (!gc1.after(gc2)) {
            day = gc1.get(Calendar.DAY_OF_WEEK);
            if(day != Calendar.SATURDAY && day != Calendar.SUNDAY) {
                days++;
            }
            gc1.add(Calendar.DATE, 1);
        }
        days = (days==0 && day != Calendar.SATURDAY && day != Calendar.SUNDAY) ? 1 : days;
        if(debug) System.out.println(days+" days ("+(System.currentTimeMillis()-startTime)+")");
 
        return (int)days;
    }
 
    int way2() // Bart_Cr
    {
        reset();
        long startTime = System.currentTimeMillis();
 
        boolean addOne = true;
        final long ONE_HOUR = 60 * 60 * 1000L;
 
        int firstDOW = gc1.get(Calendar.DAY_OF_WEEK);
        int lastDOW = gc2.get(Calendar.DAY_OF_WEEK);
 
        gc2.add(Calendar.DAY_OF_WEEK, firstDOW - lastDOW);
 
        long days = (gc2.getTimeInMillis() - gc1.getTimeInMillis() + ONE_HOUR) / (ONE_HOUR * 24);
        days = 5 * (days / 7);
        days -= firstDOW - lastDOW;
 
        if (firstDOW == Calendar.SUNDAY) {
            addOne = false;
        }
        if (addOne) {
            days++;
        }
        if(debug) System.out.println(days+" days ("+(System.currentTimeMillis()-startTime)+")");
 
        return (int)days;
    }
 
    int way3() // krakatoa
    {
        reset();
        long startTime = System.currentTimeMillis();
 
        final long ONE_HOUR = 60 * 60 * 1000L;
        long totalDays = (gc2.getTimeInMillis() - gc1.getTimeInMillis() + ONE_HOUR) / (ONE_HOUR * 24);
        int dayNum = 0;
 
        int[] days = new int[(int)totalDays];
        for (int a=0; a<totalDays; ++a) {
            days[a] = ++dayNum;
            if(dayNum == 7) { dayNum = 0; }
        }
        long result = totalDays / 7;
        result = result * 2;
        for(int y=0; y<(int)(totalDays % 7); ++y) {
            if(days[(int)(totalDays-(y+1))]==6||days[(int)(totalDays-(y+1))]==7){
                result+=1;
            }
        }
        result = totalDays - result;
        if(debug) System.out.println(result+" days ("+(System.currentTimeMillis()-startTime)+")");
 
        return (int)result;
    }
 
    int way4() // objects
    {
        reset();
        long startTime = System.currentTimeMillis();
 
        int day;
        long days = 0;
 
        while (!gc1.after(gc2)) {
            day = gc1.get(Calendar.DAY_OF_WEEK);
            if(day == Calendar.SATURDAY) break;
            else if(day != Calendar.SUNDAY) days++;
            gc1.add(Calendar.DATE, 1);
        }
        while (!gc1.after(gc2)) {
            days += 5;
            gc1.add(Calendar.DATE, 7);
            if(gc1.after(gc2)) {
                gc1.add(Calendar.DATE, -1); // back to Fri
                while(!gc1.before(gc2)) {
                    day = gc1.get(Calendar.DAY_OF_WEEK);
                    if(day != Calendar.SUNDAY && day != Calendar.SATURDAY) {
                        if(gc1.equals(gc2)) break;
                        days--;
                    }
                    gc1.add(Calendar.DATE, -1);
                }
                break;
            }
        }
        if(debug) System.out.println(days+" days ("+(System.currentTimeMillis()-startTime)+")");
 
        return (int)days;
    }
 
    public static void main(String[] args)
    {
        CalendarTest ct = new CalendarTest(true);
        ct.set1(2000,0,1);
        ct.set2(4005,0,1);
        
        System.out.println("A: "+ct.g1.getTime());
        System.out.println("B: "+ct.g2.getTime());
 
        System.out.print("way1 = "); ct.way1();
        System.out.print("way2 = "); ct.way2();
        System.out.print("way3 = "); ct.way3();
        System.out.print("way4 = "); ct.way4();
    }
}

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:

Select allOpen in new window

 

by: Bart_CrPosted on 2008-04-23 at 01:07:39ID: 21418487

Give this a try. And thanks for finding a bug in my application ;)

    int way2() // Bart_Cr
    {
        reset();
        long startTime = System.currentTimeMillis();
 
        boolean addOne = true;
        final long ONE_HOUR = 60 * 60 * 1000L;
 
        int firstDOW = gc1.get(Calendar.DAY_OF_WEEK);
        int lastDOW = gc2.get(Calendar.DAY_OF_WEEK);
 
        gc2.add(Calendar.DAY_OF_WEEK, firstDOW - lastDOW);
 
        long days = (gc2.getTimeInMillis() - gc1.getTimeInMillis()/* + ONE_HOUR*/) / (ONE_HOUR * 24);
        days = 5 * (days / 7);
        days -= firstDOW - lastDOW;
 
        if (firstDOW == Calendar.SUNDAY || lastDOW == Calendar.SATURDAY) {
            addOne = false;
        }
        if (addOne) {
            days++;
        }
        if (debug) {
            System.out.println(days + " days (" + (System.currentTimeMillis() - startTime) + ")");
        }
 
        return (int) days;
    }
                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:

Select allOpen in new window

 

by: gnoonPosted on 2008-04-23 at 01:44:43ID: 21418615

I used the following loop to compare the result with way2. It's exactly the same. So, I assummed you solution is the best since it takes the result in ~0 msec for 2,000 years. That's great!

        ct.set1(2000,0,1);
        for(int i=2000; i<=4000; i++) {
            ct.set2(i,0,1);
            int a = ct.way4();
            int b = ct.way2();
            if(a != b) System.out.println(i+" !?");
            else if(i%100==0) System.out.println(i);
            try{Thread.sleep(0);}catch(Exception e){}
        }

Thanks

 

by: krakatoaPosted on 2008-04-23 at 01:51:23ID: 21418640

You can't compare the method wiht the one I posted unless you do so using nanotime for both - or all.

My routine is going to be many orders of magnitude faster than way4 in any case. I'm still looking at your tests, but it wuld be fairer and more informative if they were set up more equally.

 

by: krakatoaPosted on 2008-04-23 at 01:53:23ID: 21418646

gnoon - that's ridiculous to close the question at this stage!

 

by: gnoonPosted on 2008-04-23 at 01:57:43ID: 21418665

I'm sorry to other experts for no point split. As my original problem is finding the only one the best solution. This will help EE to keep more clear solution in kb.

Again, thanks a lot anyway.

 

by: gnoonPosted on 2008-04-23 at 02:02:49ID: 21418688

>You can't compare the method wiht the one I posted unless you do so using nanotime for both - or all.
I currently using jdk 1.4. There is no nanotime function.

 

by: CEHJPosted on 2008-04-23 at 02:07:07ID: 21418703

For testing, you can scale the tests by using multiple invocations and taking the average

 

by: Bart_CrPosted on 2008-04-23 at 02:09:29ID: 21418712

Comparison using nanoTime stills show my version is faster. It constantly stays in the ns range while krakatoa's version will go to ms when it reaches the 300 year mark (on my system).

 

by: krakatoaPosted on 2008-04-23 at 02:10:48ID: 21418723

>>Comparison using nanoTime stills show my version is faster. It constantly stays in the ns range while krakatoa's version will go to ms when it reaches the 300 year mark (on my system). <<

Nonsense.

 

by: krakatoaPosted on 2008-04-23 at 02:13:30ID: 21418731

>>  currently using jdk 1.4. There is no nanotime function. <<  ...

All the more reason to test it more forensically. As for your comment about EE database ( I expect that's what you meant by kb ?), this won't do very much to improve it.

 

by: krakatoaPosted on 2008-04-23 at 02:23:36ID: 21418789

You didn't stick to anything like the framework when it came to timings:

long startTime = System.currentTimeMillis();
 
        final long ONE_HOUR = 60 * 60 * 1000L;
        long totalDays = (gc2.getTimeInMillis() - gc1.getTimeInMillis() + ONE_HOUR) / (ONE_HOUR * 24);
        int dayNum = 0;
 
        int[] days = new int[(int)totalDays];
        for (int a=0; a<totalDays; ++a) {
            days[a] = ++dayNum;
            if(dayNum == 7) { dayNum = 0; }
        }
The whole point of the for loop here was simply to set up an array of ints that could be used instead of dates - *to test the algorithm* **NOT** the acquisition of the dates themselves!! You put the timer **upstream** of this initialisation - what kind of sense does that make??!

 

by: krakatoaPosted on 2008-04-23 at 03:17:43ID: 21419017

OK, I should have trusted you to do the trivial part yourself, and obtain the dates (the number of days); but as you didn't, here is the full code - plus the results from a test on 4,000 years - you should have run to make a test against other methods:

import java.util.*;
import java.text.*;



public class SatSunlessDays  {

private float start, end, result;
private int daynum=0;
private int[] days;
private long totdays;

      public static void main(String[] args){

      new SatSunlessDays();

      }


public SatSunlessDays (){

Date d1 = new GregorianCalendar(1973,11,31,23,59).getTime();
Date d2 = new GregorianCalendar(5973,11,31,23,59).getTime();

long diff = d2.getTime() - d1.getTime();

totdays = (diff / (1000*60*60*24));

days = new int[(int)(totdays)];

long starttime = System.nanoTime(); // THIS IS WHERE THE TIMERS SHOULD START

result = (totdays)/7;

 result = ((int)result)*2;

  for(int y=0;y<(int)((totdays)%7);y++){
      if(days[(int)((totdays)-(y+1))]==6||days[(int)((totdays)-(y+1))]==7){
            result+=1;
      }
   }

   long endtime = System.nanoTime();//TIMERS SHOULD FINISH HERE BECAUSE SYSTEM.OUT.PRINTLNs ARE SKEWS.

   System.out.println("Number of days in period is " + totdays + ".");
   System.out.println("The total number of working days between dates is "+((int)(totdays)-(int)result));
   if(((endtime-starttime)/1000000)>0) {System.out.println(((endtime-starttime)/1000000)+" milliseconds");}
   else {System.out.println("This calculation took "+(endtime-starttime)+" nanoseconds");}


}

}















C:\jdk1.5\>java SatSunlessDays
Number of days in period is 1460970.
The total number of working days between dates is 1043550
This calculation took 7823 nanoseconds

 

by: krakatoaPosted on 2008-04-23 at 03:20:23ID: 21419025

That gives you a chance to convince me otherwise, before I ask for the Q ot be re-opened.

 

by: krakatoaPosted on 2008-04-23 at 04:26:44ID: 21419367

i.e.:




import java.util.*;
import java.text.*;

// Span - 4,000 years.

public class SatSunlessDays  {

  private float  result;
  private long totdays;

      public static void main(String[] args){

      new SatSunlessDays();

      }

  public SatSunlessDays (){

       GregorianCalendar gd1 = new GregorianCalendar(1973,11,31);
       GregorianCalendar gd2 = new GregorianCalendar(5973,12,31);

       Date d1 = new GregorianCalendar(1973,11,31).getTime();
       Date d2 = new GregorianCalendar(5973,12,31).getTime();

       long diff = d2.getTime() - d1.getTime();

       totdays = (diff / (1000*60*60*24));

       long starttime = System.nanoTime(); // TIMER STARTS HERE

       result = (int)((totdays/7)*2);
 
    for(int y=0;y<(int)((totdays)%7);y++){
      
      if((gd2.get(Calendar.DAY_OF_WEEK-(y+1)))==Calendar.SATURDAY||(gd2.get(Calendar.DAY_OF_WEEK-(y+1)))==Calendar.SUNDAY){
            System.out.println(gd2.get(Calendar.DAY_OF_WEEK-(y+1)));
            result+=1;
      }
    }


   long endtime = System.nanoTime(); // TIMER ENDS HERE

   System.out.println("Number of days in period is " + totdays + ".");
   System.out.println("The total number of working days between dates is "+((int)(totdays)-(int)result));
   if(((endtime-starttime)/1000000)>0) {System.out.println(((endtime-starttime)/1000000)+" milliseconds");}
   else {System.out.println("This calculation took "+(endtime-starttime)+" nanoseconds");}


 }

}

 

by: gnoonPosted on 2008-04-23 at 07:37:38ID: 21421137

CEHJ:
>For testing, you can scale the tests by using multiple invocations and taking the average
Yes, that's the estimate of everage. I'm using Editplus to modify the code and there are hot keys to compile & run easily. At least ten times for each solution running (uncomment one by one), but no matter how many times since I got a working/validated code with a nice time running than my origin code. I just don't want to get a headache on other solutions anymore.

krakatoa:
>You put the timer **upstream** of this initialisation - what kind of sense does that make??!
As your code does not act on dates but integer, I was trying to apply the algorithm to dates but not quite understand it. On the basic lookup, I saw two 'for' loops and both use days as a shared var. If there is no first loop, what the second loop shall be. So, I thought that the whole code is a unit and should be under the start time capture.  Besides, I can't get the applied code (from your algorithm) to make the right result.

I do not test your last code yet, but is this code really working?

gd2.get(Calendar.DAY_OF_WEEK-(y+1))

 

by: krakatoaPosted on 2008-04-23 at 09:13:37ID: 21422311

>>I just don't want to get a headache on other solutions anymore.

I thought you were both an expert (on the leaderboard), and cognizant of the fact that solving other people's problems gives you a headache, rather than the other way around.

The point of my posts was, as I have repeated several times, that the speed resides in the fact that the biggest loop you will ever have to evaluate, no matter how big the time period, is 6 - this being the maximum number of days needed to look back on form the end date to see if any were Saturdays or Sundays!

 

by: krakatoaPosted on 2008-04-23 at 19:15:34ID: 21427284

gnoon, re:    but is this code really working?

Yes.

Both pieces of code below are now fully working. I'm posting twice: first is the code without any debugs and with an if conditional, to run as fast as possible; second post uses a switch case and debugs, so you can see in the dark.

Again, I don't believe the code you awarded on compares with this. Where are the dates and the looping for it? There are none. You can run the tests.

I put the timer *after* the 'acquisition' of the dates because that part is the responsibility of Java, not the algorithm. Obviously, you're welcome to do the same for any other code - as I wouldn't want to be accused of gerrymandering.

import java.util.*;
import java.text.*;
 
public class SatSun  {
 
  private long totalweekenddays;
  private long totdays =1;
  private int thisDay;
 
	public static void main(String[] args){
 
	new SatSun();
 
	}
 
  public SatSun (){
 
       GregorianCalendar gd1 = new GregorianCalendar(2008,1,1);
       GregorianCalendar gd2 = new GregorianCalendar(2008,2,31);
 
      gd1.clear(Calendar.MILLISECOND);
      gd1.clear(Calendar.SECOND);
      gd1.clear(Calendar.MINUTE);
      gd1.clear(Calendar.HOUR_OF_DAY);
      
      gd2.clear(Calendar.MILLISECOND);
      gd2.clear(Calendar.SECOND);
      gd2.clear(Calendar.MINUTE);
      gd2.clear(Calendar.HOUR_OF_DAY);
      
       while ( gd1.before(gd2) ) {
	totdays++;
                gd1.add(Calendar.DATE, 1);
                
       }
 
   //*******************************************************  
       long starttime = System.nanoTime(); // TIMER STARTS HERE
     
       totalweekenddays = ((totdays/7)*2);
       thisDay = gd2.get(Calendar.DAY_OF_WEEK);
 
    for(int y=0;y<((totdays)%7);y++){
 
		if(thisDay ==1||thisDay==7){totalweekenddays+=1;}
		if(thisDay==1){thisDay=7;}
		else{thisDay = thisDay -1;}
    }
 
   //*******************************************************
   long endtime = System.nanoTime(); // TIMER ENDS HERE
 
   System.out.println("\nNumber of days in period is " + totdays + ".\n");
   System.out.println("The total number of working days between dates is "+((int)(totdays)-(int)totalweekenddays));
   System.out.println("Number of Saturdays and Sundays in this period is "+(int)totalweekenddays);	
   if(((endtime-starttime)/1000000)>0) {System.out.println("This calculation took "+((endtime-starttime)/1000000)+" milliseconds");}
   else {System.out.println("This calculation took "+(endtime-starttime)+" nanoseconds");}
 
 }
 
}

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:

Select allOpen in new window

 

by: krakatoaPosted on 2008-04-23 at 19:16:10ID: 21427286

and ...

import java.util.*;
import java.text.*;
 
public class SatSun  {
 
  private long totalweekenddays;
  private long totdays =1;
  private int thisDay;
 
	public static void main(String[] args){
 
	new SatSun();
 
	}
 
  public SatSun (){
 
       GregorianCalendar gd1 = new GregorianCalendar(2008,1,1);
       GregorianCalendar gd2 = new GregorianCalendar(6008,2,31);
 
      gd1.clear(Calendar.MILLISECOND);
      gd1.clear(Calendar.SECOND);
      gd1.clear(Calendar.MINUTE);
      gd1.clear(Calendar.HOUR_OF_DAY);
      
      gd2.clear(Calendar.MILLISECOND);
      gd2.clear(Calendar.SECOND);
      gd2.clear(Calendar.MINUTE);
      gd2.clear(Calendar.HOUR_OF_DAY);
      
       while ( gd1.before(gd2) ) {
	totdays++;
                gd1.add(Calendar.DATE, 1);
                
       }
     
 
       System.out.println("Number of WHOLE weeks in the given period is "+totdays/7);
       
       totalweekenddays = ((totdays/7)*2);
       System.out.println("Total weekend days before adding possible mod-ed extras, is "+totalweekenddays);
 
       System.out.println("There are now "+totdays%7+" days to check for weekendedness ...");
       long starttime = System.nanoTime(); // TIMER STARTS HERE
       thisDay = gd2.get(Calendar.DAY_OF_WEEK);
       System.out.println("DOW is "+gd2.get(Calendar.DAY_OF_WEEK)+'\n');
 
    for(int y=0;y<((totdays)%7);y++){
	           		
		System.out.println("Interrogating day "+thisDay+" for weekendedness");
	
		switch (thisDay){
		case 1:{totalweekenddays+=1;System.out.println("Sunday");}break;
		case 7:{totalweekenddays+=1;System.out.println("Saturday");}break;
		case 2:{System.out.println("Monday");}break;
		case 3:{System.out.println("Tuesday");}break;
		case 4:{System.out.println("Wednesday");}break;
		case 5:{System.out.println("Thursday");}break;
		case 6:{System.out.println("Friday");}break;
 
		}
		if(thisDay==1){thisDay=7;}
		else{thisDay = thisDay -1;}
		
		
    }
 
 
   long endtime = System.nanoTime(); // TIMER ENDS HERE
 
   System.out.println("\nNumber of days in period is " + totdays + ".\n");
   System.out.println("The total number of working days between dates is "+((int)(totdays)-(int)totalweekenddays));
   System.out.println("Number of Saturdays and Sundays in this period is "+(int)totalweekenddays);	
   if(((endtime-starttime)/1000000)>0) {System.out.println("This calculation took "+((endtime-starttime)/1000000)+" milliseconds");}
   else {System.out.println("This calculation took "+(endtime-starttime)+" nanoseconds");}
 
 }
 
}

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:

Select allOpen in new window

 

by: gnoonPosted on 2008-04-23 at 19:38:06ID: 21427390

Yes, you're right (6-being the maximum number of days remained by mod 7), but (1)there are three groups to concern within #total days (the first week, middle week(s), and the last week) and (2)the 1st date of each month is *not* always on Monday.

Here is what I see from your algorithm:

totalDays = end - start
weeks = totalDays / 7
satsunDays = weeks * 2 //<-- (1) here is what I need a period of time to prove is it true and what if totaldays is 2 and both are sat. and sun.
remainDays = totalDays % 7
satsunDays += FN(remainDays) //<-- (2) It's hard to imagine for the function to find # of sat. & sun.
result = totalDays - satsunDays //<-- (3) the result is a blurred figure

Look at Bart_Cr's code, he is finding only positive # of days and get result

days -= firstDOW - lastDOW;
If firstday and lastday are not SUN or SAT Then
    days++;
End If

This is amazing code I ever seen. It's simple but completly beautiful just like Newton's formula (F=ma). That's.

Thanks

 

by: CEHJPosted on 2008-04-24 at 01:48:16ID: 21428728

btw gnoon, are you requiring this code to work with *any* date or are you in practice using it for relatively recent ones? what is the range?

 

by: krakatoaPosted on 2008-04-24 at 02:09:49ID: 21428828

gnoon:

>> ... but (1)there are three groups to concern within #total days (the first week, middle week(s), and the last week) and (2)the 1st date of each month is *not* always on Monday. ...<<

1. You mentioned **absolutely none** of this in your question. You asked for the number of days without Sats and Suns - no mention of splitting anything - come on!

2. If by " .. *not* always a Monday ..." you are referring to anything to do with my code, then I'm afraid you just don't understand the first thing about what I'm trying to say with this algorithm. Let me repeat it once more :

******ANY******* contiguous set of days always includes a Saturday and a Sunday if the size of that set is equal to any multiple of 7   - ****IRRESPECTIVE**** of which day of the week (M,T,W,T,F,S,S) that period starts on. You threfore know, with cast-iron certainty, that the only calculation that needs to be made to find the number of Saturdays and Sundays in any date range is to see how many times it divides by 7, and then **ONLY** examine each day of any modulus remainder for whether any of those days are weekend days -- BACKWARDS, FROM THE LAST DATE. Underlined.

3. As to bart_cr's code : firstly, it isn't his code *anyway*, so I don't see why you are so enamoured with what he's contributed with that - in fact it's plagiarism. Secondly, when it comes to testing it, you have code there which works on ******no dates at all, bar one****** without any looping, and timed in some incompatible way that it renders the test useless.

4. My pathology is :

> a) find total number of days;
> b) divide integrally by 7 to get weeks, and double that for the Sat/Sun count;
> c) mod the total days by 7, to see if any what part of a week (days) remains;
> d) from the end date, examine each c) date back from there for Sat/Sun
> e) if you find a Sat / Sun in d), add it to the doubled-up value already in b).

 

by: Bart_CrPosted on 2008-04-24 at 02:19:45ID: 21428880

>>> As to bart_cr's code : firstly, it isn't his code *anyway*

It is my code, code that I've written a few years ago for a plugin I've written for IntelliJ idea. As you can see in the comments of the commited code and the name of the committer, they're not incidentally all "BartCr". I just didn't want to simply copy paste the code which would not get this comment.

And it is code that works for the problem stated, at a good speed. I'm not going to discuss which code is fastest because with benchmarks you can prove everything or nothing. I to can state that starting the time should be done 3 lines later in my code, but I don't see why I should.

The fact is that the code I provided works fast enough and after fixing the bug that was originally in there did give the correct results for all date ranges at always the same speed.

 

by: krakatoaPosted on 2008-04-24 at 02:31:00ID: 21428930

@Bart_cr


>> for a plugin I've written for IntelliJ idea

Really? And you just happened to notice a bug when you trotted it out for some l'il ole EE question, right?

As for the rest of your comment, this is exactly the spirit of dismissiveness that got this question into the mess it was as it was closing - you don't have the committment to put your claims to the test properly, as I have done in my code.

Stick the timers anywhere you like - as long as mine are in the same place! Let's say - as I've said umpteen times - ***after the acquisition of the dates*** since that acquisition is neither here nor there when it comes to the engine code and its speed. And anyway, LOL, the point you missed completely is that the quintessence of what my solution offers is so no-brainingly obvious that it only needs a tiny loop to accommodate it - IOW time's arrow runs one way - there'll always be a Sat and Sun in ***any*** 7 -day block.
 :¬P

 

by: Bart_CrPosted on 2008-04-24 at 02:43:54ID: 21429010

>>> Really? And you just happened to notice a bug when you trotted it out for some l'il ole EE question, right?

Nope, I didn't notice the bug, gnoon pointed out the bug with his first test class. The way I use the class in my code never ever lets a period end on a saturday. That's why in the plugin the bug has never been a problem.

And further, I wouldn't have had any problem with a point split, or even you getting all the points. I'm here to answer questions, solve problems, not for getting points or whatever. I'm not that competitive, I just love Java. Been loving it for 11 years now.

As for your code. I like the approach to solving the problem. I didn't think of that way when I originally developed the code. The other two solutions I also had implemented at one time, but they simply lacked the needed performance. The only problem I still had with your code when the question was closed, was (probably as the poster) that it was not clear to me how it should be implemented. BTW, I'm still not sure how to write a method providing two dates and returning one single int with the result using your method, starting out from where you state the timer should start.

 

by: krakatoaPosted on 2008-04-24 at 03:14:56ID: 21429198

>> BTW, I'm still not sure how to write a method providing two dates and returning one single int with the result using your method, starting out from where you state the timer should start. <<

Well, that's another question entirely, and has no bearing on the natural history of how time works - which for once in its miserable life smiles on the programmer.

I appreciate very much you seeing what I was getting at now. Unlike you, I had no reason to tackle this question beforehand, and therefore had to bring the pathology together in some kludgy and buggy earlier code postings - which nevertheless still embodied (but masked) the mod-7 principle.

Like you, I dont mind particularly about the points, but somehow the currency of them plays a role, otherwise a few good and possibly helpful efforts can go unnoticed. I don't make *that* many posts, but when I do, I llike to think they'll end up being correct as well as helping someone who appreciates them. That's the only place where the points come in for me.

I agree about timers, and it's a very probably large and unresolvable area of contention - I'm no expert. But one thing I would say is that if one has to work with the rather arcane (and I'm sure well-founded) Java machinery to work with Dates (hence my downbeat comment above), that that should be left out of the timing considerations since no algorithm on Earth is going to circumvent what amounts to hard-wired convention.

Out of interest, I hacked your class and ran it. It's a good piece of kit. If you have any interest, the results from how it ran against mine are :

C:\jdk1.5\gbjava>java DateUtil
The time taken in nans was 2997588
42

C:\jdk1.5\gbjava>java SatSun

Number of days in period is 60.

The total number of working days between dates is 42
Number of Saturdays and Sundays in this period is 18
This calculation took 65093 nanoseconds

.
.
and that was including more System.outs than your code. However, it would be immensely interesting to know, community-wise, what monsters we'd both fabricated.
:) k.

 

by: krakatoaPosted on 2008-04-24 at 03:27:13ID: 21429268

>> ... wouldn't have had any problem with a point split, or ... <

You can always leave a handful of token points if you like - without my insistence wiht the questioner, your bug would've still lain dormant. ;)

 

by: krakatoaPosted on 2008-04-24 at 03:39:18ID: 21429322

[

To any future visitor to this question: You should ignore my code and remarks in these comments:

ID:21411561 Author:krakatoa
ID:21411986 Author:krakatoa
04.23.2008 at 11:17AM BST, ID: 21419017
04.23.2008 at 12:26PM BST, ID: 21419367

noting that this one overrides all previous :

04.24.2008 at 03:15AM BST, ID: 21427284






]

 

by: krakatoaPosted on 2008-04-24 at 04:08:30ID: 21429484

My last posting is this small comment correction to Bart_Cr:

>>and that was including more System.outs than your code .. <<

That' not quite right. My Sysouts come after the loop. Apologies.

O&O. k.

 

by: CEHJPosted on 2008-04-24 at 05:49:28ID: 21430202

>>It is my code, code that I've written a few years ago for a plugin I've written for IntelliJ idea.

What do you make of that IDE compared to Netbeans and Eclipse btw Bart?

 

by: Bart_CrPosted on 2008-04-24 at 06:42:16ID: 21430712

I've never used NetBeans in a real project, so I'm not going to comment on that.

For me, I slightly prefer IntelliJ over Eclipse. I think Eclipse is probably richer in the area of features, but the learning curve is a bit steeper. IntelliJ contains enough features for me to work and what I really like is that IntelliJ allows each user to use the features he know and likes and all you don't have to bother about the rest.

 

by: CEHJPosted on 2008-04-24 at 06:58:06ID: 21430864

Sounds worth investigation, thanks. I take it it's written in Java?

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...