summaryrefslogtreecommitdiff
path: root/core
Unidiff
Diffstat (limited to 'core') (more/less context) (ignore whitespace changes)
-rw-r--r--core/pim/datebook/datebookweek.cpp162
1 files changed, 92 insertions, 70 deletions
diff --git a/core/pim/datebook/datebookweek.cpp b/core/pim/datebook/datebookweek.cpp
index ce0b10b..8caa827 100644
--- a/core/pim/datebook/datebookweek.cpp
+++ b/core/pim/datebook/datebookweek.cpp
@@ -589,97 +589,119 @@ QDate DateBookWeek::weekDate() const
589 return d.addDays(-dayoffset); 589 return d.addDays(-dayoffset);
590} 590}
591 591
592// this used to only be needed by datebook.cpp, but now we need it inside 592// This used to only be needed by datebook.cpp, but now we need it
593// week view since 593// inside week view since we need to be able to figure out our total
594// we need to be able to figure out our total number of weeks on the fly... 594// number of weeks on the fly. This is probably the best place to put
595// this is probably the best place to put it.. 595// it.
596 596
597// For Weeks that start on Monday... (EASY!) 597// For Weeks that start on Monday... (EASY!)
598// At the moment we will use ISO 8601 method for computing 598// At the moment we will use the ISO 8601 method for computing the week.
599// the week. Granted, other countries use other methods, 599// Granted, other countries use other methods, but we aren't doing any
600// bet we aren't doing any Locale stuff at the moment. So, 600// Locale stuff at the moment. Without locale info it is too hard to
601// this should pass. This Algorithim is public domain and 601// guess what method should be used. So, this should pass. This
602// available at: 602// algorithim is public domain and available at:
603// http://personal.ecu.edu/mccartyr/ISOwdALG.txt 603// http://personal.ecu.edu/mccartyr/ISOwdALG.txt
604// the week number is return, and the year number is returned in year 604// the week number is returned, and the year number is returned in year
605// for Instance 2001/12/31 is actually the first week in 2002. 605// for Instance 2001/12/31 is actually the first week in 2002.
606// There is a more mathematical definition, but I will implement it when 606// There is a more mathematical definition, it should be implemented.
607// we are pass our deadline.
608 607
609// For Weeks that start on Sunday... (ahh... home rolled) 608// For Weeks that start on Sunday... (ahh... home rolled)
610// okay, if Jan 1 is on Friday or Saturday, 609// okay, if Jan 1 is on Friday or Saturday, it will go to the previous
611// it will go to the pervious 610// week.
612// week... 611
613 612/*!
613 * The week number and year number of a date may actually be different
614 * then the date itself as specified by the ISO 8601 standard. For
615 * example if Jan 1 year falls on a Friday, the week number will
616 * be the last week number for the previous year (52 of year - 1). Another
617 * example is that the date 2001-12-31 falls on a Monday, its week number
618 * is 1 and its year is 2002. This function provides stripped down
619 * version of the alogrithm described in
620 * http://personal.ecu.edu/mccartyr/ISOwdALG.txt to provide the correct
621 * week number and year number for a given date.
622 *
623 * \param d The date that you want to know the week number for.
624 * \param week A reference to the variable you want to store the week
625 * number in.
626 * \param year A reference to the variable you want to store the year
627 * number in.
628 * \param startOnMonday Inform the function whether weeks start on
629 * Sunday or Monday. Set to true if your weeks start on Monday.
630 * \return false if the supplied date is invalid, true otherwise.
631 */
614bool calcWeek( const QDate &d, int &week, int &year, 632bool calcWeek( const QDate &d, int &week, int &year,
615 bool startOnMonday ) 633 bool startOnMonday )
616{ 634{
617 int weekNumber; 635 int weekNumber = -1;
618 int yearNumber; 636 int yearNumber = -1;
619 637
620 // remove a pesky warning, (Optimizations on g++)
621 weekNumber = -1;
622 int jan1WeekDay = QDate(d.year(), 1, 1).dayOfWeek(); 638 int jan1WeekDay = QDate(d.year(), 1, 1).dayOfWeek();
623 int dayOfWeek = d.dayOfWeek(); 639 int dayOfWeek = d.dayOfWeek();
624 640
625 if ( !d.isValid() ) 641 if ( !d.isValid() )
626 return false; 642 return false;
627 643
628 if ( startOnMonday ) { 644 if ( startOnMonday ) {
629 // find the Jan1Weekday; 645 // find the Jan1Weekday;
630 if ( d.dayOfYear() <= ( 8 - jan1WeekDay) && jan1WeekDay > 4 ) { 646 if ( d.dayOfYear() <= ( 8 - jan1WeekDay) && jan1WeekDay > 4 ) {
631 yearNumber = d.year() - 1; 647 yearNumber = d.year() - 1;
632 if ( jan1WeekDay == 5 || ( jan1WeekDay == 6 && QDate::leapYear(yearNumber) ) ) 648 if ( jan1WeekDay == 5
633 weekNumber = 53; 649 || ( jan1WeekDay == 6 && QDate::leapYear(yearNumber) ) )
634 else 650 weekNumber = 53;
635 weekNumber = 52; 651 else
636 } else 652 weekNumber = 52;
637 yearNumber = d.year(); 653 } else
638 if ( yearNumber == d.year() ) { 654 yearNumber = d.year();
639 int totalDays = 365; 655
640 if ( QDate::leapYear(yearNumber) ) 656 if ( yearNumber == d.year() ) {
641 totalDays++; 657 int totalDays = 365;
642 if ( ((totalDays - d.dayOfYear()) < (4 - dayOfWeek) ) 658 if ( QDate::leapYear(yearNumber) )
643 || (jan1WeekDay == 7) && (totalDays - d.dayOfYear()) < 3) { 659 totalDays++;
644 yearNumber++; 660 if ( ((totalDays - d.dayOfYear()) < (4 - dayOfWeek) )
645 weekNumber = 1; 661 || (jan1WeekDay == 7) && (totalDays - d.dayOfYear()) < 3)
662 {
663 yearNumber++;
664 weekNumber = 1;
665 }
666 }
667 if ( yearNumber == d.year() ) {
668 int j = d.dayOfYear() + (7 - dayOfWeek) + ( jan1WeekDay - 1 );
669 weekNumber = j / 7;
670 if ( jan1WeekDay > 4 )
671 weekNumber--;
646 } 672 }
647 }
648 if ( yearNumber == d.year() ) {
649 int j = d.dayOfYear() + (7 - dayOfWeek) + ( jan1WeekDay - 1 );
650 weekNumber = j / 7;
651 if ( jan1WeekDay > 4 )
652 weekNumber--;
653 }
654 } else { 673 } else {
655 // it's better to keep these cases separate... 674 // it's better to keep these cases separate...
656 if ( d.dayOfYear() <= (7 - jan1WeekDay) && jan1WeekDay > 4 675 if ( d.dayOfYear() <= (7 - jan1WeekDay) && jan1WeekDay > 4
657 && jan1WeekDay != 7 ) { 676 && jan1WeekDay != 7 )
658 yearNumber = d.year() - 1; 677 {
659 if ( jan1WeekDay == 6 678 yearNumber = d.year() - 1;
660 || (jan1WeekDay == 7 && QDate::leapYear(yearNumber) ) ) { 679 if ( jan1WeekDay == 6
661 weekNumber = 53; 680 || (jan1WeekDay == 7 && QDate::leapYear(yearNumber) ) )
662 }else 681 {
663 weekNumber = 52; 682 weekNumber = 53;
664 } else 683 } else
665 yearNumber = d.year(); 684 weekNumber = 52;
666 if ( yearNumber == d.year() ) { 685 } else
667 int totalDays = 365; 686 yearNumber = d.year();
668 if ( QDate::leapYear( yearNumber ) ) 687
669 totalDays++; 688 if ( yearNumber == d.year() ) {
670 if ( ((totalDays - d.dayOfYear()) < (4 - dayOfWeek % 7)) ) { 689 int totalDays = 365;
671 yearNumber++; 690 if ( QDate::leapYear( yearNumber ) )
672 weekNumber = 1; 691 totalDays++;
692 if ( ((totalDays - d.dayOfYear()) < (4 - dayOfWeek % 7)) ) {
693 yearNumber++;
694 weekNumber = 1;
695 }
673 } 696 }
674 } 697 if ( yearNumber == d.year() ) {
675 if ( yearNumber == d.year() ) { 698 int j = d.dayOfYear() + (7 - dayOfWeek % 7) + ( jan1WeekDay - 1 );
676 int j = d.dayOfYear() + (7 - dayOfWeek % 7) + ( jan1WeekDay - 1 ); 699 weekNumber = j / 7;
677 weekNumber = j / 7; 700
678 if ( jan1WeekDay > 4 ) { 701 if ( jan1WeekDay > 4 )
679 weekNumber--; 702 weekNumber--;
680 } 703 }
681 } 704 }
682 }
683 year = yearNumber; 705 year = yearNumber;
684 week = weekNumber; 706 week = weekNumber;
685 return true; 707 return true;